How to resizing an image with caption while maintaining its aspect ratio - html

I want to display an image that has a caption beneath it. If the user resizes the browser, the image will resize while maintaining its aspect ratio. The width of the image must not exceed its normal width. You can scale down but not scale up beyond its actual size. The image width must also not exceed 500px and the height must not exceed 800px. As you resize the image, the caption's width must align with the image's left and right sides. Here is what I got:
Working jsFiddle
Code:
.furlHtmlCont {
max-width: 600px;
max-height: 800px;
display: inline-block;
flex-direction: column;
align-items: flex-start;
box-shadow: 0 0 8px #c0c0c0;
border-left: 1px solid #c0c0c0;
border-right: 1px solid #c0c0c0;
border-bottom: 1px solid #c0c0c0;
border-bottom-left-radius: 3px;
border-bottom-right-radius: 3px;
}
.furlHtmlFooter {
display: table-caption;
caption-side: bottom;
padding: 5px 10px 5px 10px;
}
.furlHtmlImg {
max-width: 100%;
max-height: 300px;
cursor: pointer;
}
<div class="furlHtmlCont">
<div style="display: flex; flex-direction: column">
<img class="furlHtmlImg" src="http://dhr7l999iqsnw.cloudfront.net/wp-content/uploads/Two_Male_Giraffes_Fighting_600.jpg">
<div class="furlHtmlFooter">
<div class="furlHtmlTitle">Caption goes here</div>
<div class="furlHtmlDesc">Long description goes here. It should wrap at the image's right edge even as the user resizes the image.
</div>
</div>
</div>
</div>
The problem I am having is that the image is exceeding its normal width and getting stretched.
UPDATE:
Although I accepted the answer below, it in fact does NOT work. The height must be limited to 800px.

I think this should work.
CSS:
.furlHtmlCont {
width: 100%;
height: 100%;
max-width: 500px;
max-height: 800px;
display: inline-block;
flex-direction: column;
align-items: flex-start;
box-shadow: 0 0 8px #c0c0c0;
border-left: 1px solid #c0c0c0;
border-right: 1px solid #c0c0c0;
border-bottom: 1px solid #c0c0c0;
border-bottom-left-radius: 3px;
border-bottom-right-radius: 3px;
}
.furlHtmlFooter {
display: table-caption;
caption-side: bottom;
padding: 5px 10px 5px 10px;
}
.furlHtmlImg {
width:100%;
height:auto;
cursor: pointer;
}
JSFiddle: here

None of the solutions listed were able to constrain the height to some maximum value. Here's the solution (I also decided to limit the height to a maximum of 400px instead of 800px):
Html:
<div class="furlHtmlCont">
<div style="display: table;">
<img class="furlHtmlImg">
<div class="furlHtmlFooter">
<div class="furlHtmlTitle">Caption goes here</div>
<div class="furlHtmlDesc">This is where the long description goes and its with should not exceed the width of the image. No clipping either.</div>
</div>
</div>
</div>
css:
.furlHtmlCont {
max-width: 600px;
display: inline-block;
box-shadow: 0 0 8px #c0c0c0;
border-left: 1px solid #c0c0c0;
border-right: 1px solid #c0c0c0;
border-bottom: 1px solid #c0c0c0;
border-bottom-left-radius: 3px;
border-bottom-right-radius: 3px;
}
.furlHtmlFooter {
display: table-caption;
caption-side: bottom;
padding: 5px 10px 5px 10px;
}
.furlHtmlImg {
max-width: 100%;
max-height: 400px;
cursor: pointer;
}
https://jsfiddle.net/Deepview/vy6h0rdj/5/

Here we go!
html,
body {
height: 100%;
}
.container {
width: 100%;
max-width: 500px;
max-height: 800px;
height: 100%;
}
.image-container {
width: 100%;
height: 100%;
}
img {
max-width: 100%;
max-height: 100%;
width: auto;
height: auto;
}
<div class="container">
<div class="image-container">
<img src="http://dhr7l999iqsnw.cloudfront.net/wp-content/uploads/Two_Male_Giraffes_Fighting_600.jpg">
<div>
<div>Caption goes here</div>
<div>Long description goes here. It should wrap at the image's right edge even as the user resizes the image.
</div>
</div>
</div>
</div>

.furlHtmlCont {
max-width: 600px;
max-height: 100%;
display: inline-block;
flex-direction: column;
align-items: flex-start;
box-shadow: 0 0 8px #c0c0c0;
border-left: 1px solid #c0c0c0;
border-right: 1px solid #c0c0c0;
border-bottom: 1px solid #c0c0c0;
border-bottom-left-radius: 3px;
border-bottom-right-radius: 3px;
text-align:justify;
}
.furlHtmlFooter {
display: table-caption;
caption-side: bottom;
padding: 5px 10px 5px 10px;
}
.furlHtmlImg {
max-width: 100%;
max-height: 100%;
cursor: pointer;
object-fit: scale-down;
}
change the css as above.
And let me know if it is what you wanted..

You should have an image of the exact width and height placed there. Every time for the image you can't specify the width and height because that would stretch and distort the image, so put the image in right size to function correctly.

Related

CSS background image in flex container

I need to put a background image to a text. I suspect it could be because we nested too many classes in "div" but still can't figure it out.
CSS:
.box {
display: flex;
top: 80px;
position: relative;
padding-top: 30px;
border-top: thin solid black;
border-bottom: thin solid black;
border-right: thin solid black;
border-left: thin solid black;
}
.box1 {
padding-left: 300px;
padding-right: 30px;
width: 630px;
flex-direction: column;
align-self: flex-start;
}
.smalltitle2 {
border-bottom: medium solid black;
background-image: url("https://s3.amazonaws.com/codecademy-content/courses/freelance-1/unit-4/img-news-bite.png");
background-repeat: no-repeat;
}
HTML:
<div class="box">
<div class="box1">
<div class="smalltitle2">Mother of Three Buys Tuna Steak at Phish Concert. Leaves, "Feeling Funny."</div>
</div>
</div>
Add a width and height to your smalltitle2 container and you can tweak around how you want to make it look whether it should be part of the image, or do you want the entire image inside the container (make use of background-size).
.box {
display: flex;
top: 80px;
position: relative;
padding-top: 30px;
border-top: thin solid black;
border-bottom: thin solid black;
border-right: thin solid black;
border-left: thin solid black;
}
.box1 {
padding-left: 300px;
padding-right: 30px;
width: 630px;
flex-direction: column;
align-self: flex-start;
}
.smalltitle2 {
border-bottom: medium solid black;
background:url(https://s3.amazonaws.com/codecademy-content/courses/freelance-1/unit-4/img-news-bite.png);
background-repeat: no-repeat;
background-size: contain;
width:100%;
height:100px;
}
<div class="box">
<div class="box1">
<div class="smalltitle2">Mother of Three Buys Tuna Steak at Phish Concert. Leaves, "Feeling Funny."</div>
</div>
</div>
You can either try background-size: contain; or background-size: cover; etc.
There is no problem with the CSS, it's just missing a rule to define the size of your background image.
See demo here : https://jsfiddle.net/v8eLsef4/1/

Why do my columns wrap with window resize?

I am trying to add four columns, evenly-spaced, on a webpage that keep their structure when the browser window is resized. I built it this way based on a tutorial which I can't find now. They appear fine until you resize the browser window. Can anyone tell me why my 3rd and 4th columns keep wrapping under the first two when the browser window is resized?
#ColumnMain {
width: 100%;
height: auto;
float: left;
margin-left: auto;
margin-right: auto;
min-width: 44%
}
.col1 {
float: left;
padding: 10px 20px 15px 20px;
margin: 0;
width: 350px;
height: 100px;
border-left: solid 1px #35488C;
}
.col2 {
float: left;
padding: 10px 20px 15px 20px;
margin-left: 10px;
width: 22%;
height: 100px;
border-left: solid 1px #35488C;
}
.col3 {
float: right;
padding: 10px 20px 15px 20px;
margin: 0;
width: 22%;
height: 100px;
border-left: solid 1px #35488C;
overflow: hidden;
}
.col4 {
float: right;
padding: 10px 20px 15px 20px;
margin-right: 10px;
width: 22%;
height: 100px;
border-left: solid 1px #35488C;
Overflow: hidden;
}
<div class="columns" id="ColumnMain">
<div class="col1">content-1</div>
<div class="col2">content-2</div>
<div class="col3">content-3</div>
<div class="col4">content-4</div>
</div>
You're setting a fixed width to the first columns, which is not adaptive, and is pushing back the last divs. If you need a fixed width, but still want to keep every div inline, you can use display: table; layout. That way your first div will always have the same size, and the others will be dynamic.
#ColumnMain {
display: block;
width: 100%;
height: auto;
margin-left: auto;
margin-right: auto;
min-width: 44%
}
.col {
display: table-cell;
padding: 10px 20px 15px 20px;
height: 100px;
border-left: solid 1px #35488C;
}
.col1 {
margin: 0;
width: 350px;
}
.col2 {
margin-left: 10px;
width: 22%;
}
.col3 {
margin: 0;
width: 22%;
overflow: hidden;
}
.col4 {
margin-right: 10px;
width: 22%;
overflow: hidden;
}
<div class="columns" id="ColumnMain">
<div class="col col1">content</div>
<div class="col col2">content</div>
<div class="col col3">content</div>
<div class="col col4">content</div>
</div>
You have specified different width for first column and other columns, to make it resizeable they should be given percentage width or you have to use bootstrap CSS.
And also with margin it will not work with same percentage width. in this case you have to calculate each column width after applying margin/padding with relative to window/document width and then apply in width style. You have to also calculate the same on window resize event.
Remove margin from your column style and add below one property:
box-sizing:border-box;
For testing purpose I have change your first column width to 200px, better to assign 25% width to each column to test.
#ColumnMain {
width: 100%;
height: auto;
float: left;
margin-left: auto;
margin-right: auto;
min-width: 44%
}
.col1 {
float: left;
padding: 10px 20px 15px 20px;
width: 200px;
height: 100px;
border-left: solid 1px #35488C;
box-sizing:border-box;
}
.col2 {
float: left;
padding: 10px 20px 15px 20px;
width: 22%;
height: 100px;
border-left: solid 1px #35488C;
box-sizing:border-box;
}
.col3 {
float: left;
padding: 10px 20px 15px 20px;
width: 22%;
height: 100px;
border-left: solid 1px #35488C;
overflow: hidden;
box-sizing:border-box;
}
.col4 {
float: left;
padding: 10px 20px 15px 20px;
width: 22%;
height: 100px;
border-left: solid 1px #35488C;
Overflow: hidden;
box-sizing:border-box;
}
<div class="columns" id="ColumnMain">
<div class="col1">content</div>
<div class="col2">content</div>
<div class="col3">content</div>
<div class="col4">content</div>
</div>
Your col1 is a width of 350px. Once it gets to a certain size, 22% +22% +22% + 350px is larger than the width of the ColumnMain. So it pushes some of the columns down so they can all fit.
The reason your div's are being wrapped under one another is because when the browser resizes, it hits those widths that you have on those individual .col class and it cannot fit anymore so the div's go under one another.
It is easier and cleaner to just simply rewrite the CSS so that you only need one selector for columns. This makes the code much easier to maintain, and to change. For example, you would only have to change the border or the padding in one location and it would work automatically for all elements that apply the class. Here is the simplified code for what you wish to accomplish:
.col {
float: left;
padding: 10px 20px 15px 20px;
margin: 0;
width: 25%;
height: 100px;
border-left: solid 1px #35488C;
box-sizing: border-box;
}
<div>
<div class="col">content</div>
<div class="col">content</div>
<div class="col">content</div>
<div class="col">content</div>
</div>
Here is an example of the output in gifv format: http://i.imgur.com/VgBByqf.gifv
If you decide that you don't want the border line before the first column (the left-most column), in your CSS code, you would add this pseudo-class underneath your .col selector:
.col:first-child {
border-left: none;
}
<html>
<head>
<style>
.cols_ex {
-webkit-columns: 4 10px;
-moz-columns: 4 10px;
columns: 4 10px;
-webkit-column-gap: 2em;
-moz-column-gap: 2em;
column-gap: 2em;
-webkit-column-rule: 2px dashed gray;
-moz-column-rule: 2px dashed gray;
column-rule: 2px dashed gray;
}
</style>
</head>
<body>
<div class="cols_ex">
<p>Just at this moment her head struck against the roof of the hall: in fact she was now rather more than nine feet high, and she at once took up the little golden key and hurried off to the garden door.</p>
<p>Poor Alice! It was as much as she could do, lying down on one side, to look through into the garden with one eye; but to get through was more hopeless than ever: she sat down and began to cry again.</p>
<p>"You ought to be ashamed of yourself," said Alice,"a great girl like you" (she might well say this), "to go on crying in this way! Stop this moment, I tell you!"</p>
<p>But she went on all the same, shedding gallons of tears,until there was a large pool all round her, about four inches deep, and reaching half down the hall.</p>
</div>
</body>
</html>
As others have said, .col1 has a fixed width, so at some point, the percentage based widths on the other columns in addition to the fixed width will be greater than 100% width, causing the columns to wrap.
A more modern way to create a row of columns like this is to use display: flex and that will put them in a row and they won't wrap (unless you specify that you want it to wrap using flex-wrap).
And here's an example of a #media query that will lay the columns/rows out differently at different screen widths.
.columns {
min-width: 44%;
margin: auto;
display: flex;
}
.col {
padding: 10px 20px 15px 20px;
}
.col1 {
width: 350px;
height: 100px;
border-left: solid 1px #35488C;
}
.col2 {
margin-left: 10px;
width: 22%;
height: 100px;
border-left: solid 1px #35488C;
}
.col3 {
width: 22%;
height: 100px;
border-left: solid 1px #35488C;
}
.col4 {
margin-right: 10px;
width: 22%;
height: 100px;
border-left: solid 1px #35488C;
}
#media (max-width: 420px) {
.columns {
flex-direction: column;
}
.col {
margin: 0;
width: auto;
}
}
<div class="columns" id="ColumnMain">
<div class="col1 col">content</div>
<div class="col2 col">content</div>
<div class="col3 col">content</div>
<div class="col4 col">content</div>
</div>

HTML extend height of div

div.div1 {
position: relative;
border: 1px solid black;
height: 100px;
width: 100px;
padding: 10px;
}
div.div2 {
background-color: gray;
border: 1px solid black;
padding: 10px;
}
div.div3 {
position: absolute;
border: 1px solid red;
height: 20px;
width: 20px;
bottom: 10px;
left: 10px;
}
<div class="div1">
<div class="div2">Test 123</div>
<div class="div3">A</div>
</div>
I use the above code to display a big div with two divs in it. For the first one I use position: absolute to place it on bottom left of the div.
How can I extend the height of the second gray one so that it's 5 pixels above the first, but without having to measure its exact height in pixel (like the pic below)? I can set height: 50px; for example but is there another way?
I would use a flexbox approach rather than absolute positioning (comments in css below)
div.div1 {
display: flex;
flex-direction:column;
/* add the above styles*/
border: 1px solid black;
min-height: 100px; /*I would also change this to min-height otherwise it may cause issues if your text goes to 2 lines*/
width: 100px;
padding: 10px;
}
div.div2 {
flex-grow:1; /* make div grow to fill the space */
margin-bottom:5px; /* minus the amount of margin you wanted */
background-color: gray;
border: 1px solid black;
padding: 10px;
}
div.div3 {
/* remove absolute positioning */
border: 1px solid red;
height: 20px;
width: 20px;
}
<div class="div1">
<div class="div2">Test 123</div>
<div class="div3">A</div>
</div>
EDIT: I suggest that, if you can focus on the modern browser features, going the flexbox way as shown by Pete is definitely a cleaner approach than the ones I've shown bellow. That being said, here are the alternatives:
You can use calc to dynamically determine the height of div2:
div.div1 {
position: relative;
border: 1px solid black;
height: 100px;
width: 100px;
padding: 10px;
}
div.div2 {
background-color: gray;
border: 1px solid black;
padding: 10px;
height: calc(
100%
- 20px /* div1: padding top and bottom */
- 2px /* div1: border top and bottom */
- 20px /* div3: height */
- 2px /* div3: border top and bottom*/
- 5px /* desired separation*/
);
}
div.div3 {
position: absolute;
border: 1px solid red;
height: 20px;
width: 20px;
bottom: 10px;
left: 10px;
}
<div class="div1">
<div class="div2">Test 123</div>
<div class="div3">A</div>
</div>
You can avoid including padding and border width in your calculations if you set the box-sizing for your divs to border-box (You might want to set this for all elements):
div {
box-sizing: border-box;
}
div.div1 {
position: relative;
border: 1px solid black;
height: 100px;
width: 100px;
padding: 10px;
}
div.div2 {
background-color: gray;
border: 1px solid black;
padding: 10px;
height: calc(
100%
- 20px /* div3: height */
- 5px /* desired separation */
);
}
div.div3 {
position: absolute;
border: 1px solid red;
height: 20px;
width: 20px;
bottom: 10px;
left: 10px;
}
<div class="div1">
<div class="div2">Test 123</div>
<div class="div3">A</div>
</div>
There's this rather new, hip CSS property called 'flex' which you're now going to love because it does it exactly that without the need of positioning absolute etc. I did something similar yesterday where I had a vertical nav bar and I wanted one menu at the top and one at the bottom. In a responsive environment; using your approach of positioning absolute it would've resulted in a nasty mess of working out heights to stop the content from overlapping. Flex prevented this! Yeyyyyy
https://css-tricks.com/snippets/css/a-guide-to-flexbox/
In your example you want to do something like this:
.div1 {
display: flex;
flex-direction: column;
flex-wrap: nowrap;
justify-content: space-around;
}
.div2 {
align-self: flex-start;
flex-grow:1;
width:100%;
}
.div3 {
align-self: flex-end;
width:100%;
}
Now your div 3 will always be at the bottom. Although now .div3 will extend the entire width so within the div insert your content and BOOM done.
You can use calc on the heightsetting as in my snippet below. That setting is 100% minus (20 + 10 + 2) for the height, border and bottom of the lower DIV minus (5 + 2) for the distance and the border of the first DIV minus 10px for the padding of the parent, summing up to 49px .
div.div1 {
position: relative;
border: 1px solid black;
height: 100px;
width: 100px;
padding: 10px;
}
div.div2 {
background-color: gray;
border: 1px solid black;
padding: 10px;
height: calc(100% - 49px);
}
div.div3 {
position: absolute;
border: 1px solid red;
height: 20px;
width: 20px;
bottom: 10px;
left: 10px;
}
<div class="div1">
<div class="div2">Test 123</div>
<div class="div3">A</div>
</div>

How to manage textarea right side overflow in css?

I have to create two <textarea>s in two different <div>s and both are have to come in single line. And both <textarea>s have to occupy 100% width (50% by each) in all types of screen.
However, when I am trying the second <textarea>, the right side is overflowing and even I am not able to manage right margin (in CSS) for <textarea>. How can I avoid right overflow for <textarea>?
.container {
background-color: lightblue;
border: 5px solid black;
min-height: 500px;
}
textarea {
width: 100%;
height: 100%;
border: 3px none #cccccc;
margin: 10px 10px 10px 10px;
border: 1px solid black;
}
.left {
float: left;
width: 50%;
}
.right {
float: left;
width: 50%;
}
<div class='left'>
<textarea>left </textarea>
</div>
<div class='right'>
<textarea>right</textarea>
</div>
Note the change in margin to textarea. That should do it!
.container {
background-color: lightblue;
border: 5px solid black;
min-height: 500px;
}
textarea {
width: 100%;
height: 100%;
border: 3px none #cccccc;
margin: 10px 0px 10px 0px;
border: 1px solid black;
}
.left {
float: left;
width: 50%;
}
.right {
float: left;
width: 50%;
}
<div class='left'>
<textarea>left</textarea>
</div>
<div class='right'>
<textarea>right</textarea>
</div>
you have to remove margin from your textarea because margin calculated form the outer width of the element , you can use padding to .conatiner instead.
and add a box-sizing attribute to remove the border width from the calculate width
html,body,.container{
height:100%;
margin:0;
}
.container{
background-color: lightblue;
border: 5px solid black;
padding:10px;
display: table;
width: 100%;
box-sizing: border-box;
}
textarea {
width: 100%;
height: 100%;
border: 3px none #cccccc;
border: 1px solid black;
box-sizing: border-box;
}
.left{
display: table-cell;
width:50%;
height: 100%;
}
.right{
display: table-cell;
width:50%;
height: 100%;
}
<html>
<body>
<div class="container">
<div class='left'>
<textarea>left </textarea>
</div>
<div class='right'>
<textarea>right</textarea>
</div>
</div>
</body>
</html>
Remove margin from your textarea because margin calculated form the outer width of the element, and give display: table; to container.
Remove margin. Because you are assigning 50% to each left and right textarea. so your total width will be 100%+10px; so it will overflow on x-axis
textarea {
width: 100%;
height: 100%;
border: 3px none #cccccc;
border: 1px solid black;
}
You can use iframes for that. If you use iframes you can fit the overflow to hidden both left and right side

missing pixels css fixed div wrapper

So I'm trying to get divs to fit perfectly in a wrapper using fixed pixels for width and height. Although I'm confused as to how the pixels don't add up properly.
HTML
<div class="div1">
<img src="image.png" alt="image" class="image">
</div>
<div class="div2">
</div>
<div class="div3">
</div>
<div class="div4">
</div>
</div>
CSS
#wrapper {
height: 455px;
width: 690px;
background-color: grey;
margin-left: auto;
margin-right: auto;
margin-top: 10px;
overflow: hidden;
white-space:nowrap;
}
.div1 {
display: inline-block;
margin-bottom: 10px;
vertical-align:top;
}
.image {
max-width: 172px;
max-height: 172px;
border-radius: 2%;
border: 4px solid blue;
}
.div2 {
height: 172px;
width: 277px;
border: 4px solid blue;
display: inline-block;
margin-left: 30px;
background-color: purple;
}
.div3 {
width: 159px;
height: 188px;
display: inline-block;
margin-left: 30px;
border-left: 4px solid blue;
border-right: 2px solid blue;
border-top: 2px solid blue;
vertical-align: top;
background-color: purple;
}
.div4 {
background: url(image.png) no-repeat center;
background-size: cover;
width: 690px;
height: 265px;
}
If the parent div is 690px wide why can't the child divs add up to 690 with calculated widths, margin and boarders.
(div1)180 + 30 + (div2)285 + 30 + (div3)165 = 690px
If you look at div 3 it's right border can't be seen. You have to reduce the width by 7px to see it.
This is also happening vertically with a 190px div3 height meant to touch div4 exactly but is off by 4px.
Is this a browser issue? Default Alignment issues I'm not aware of? I'm really curious to know why this happens!
Any feedback would be appreciated. : )
If you put comments like this in your HTML you can fix the top but for the image in the 2nd line I dont know yet I continue trying
OK SO I did put the 1st line in a div "test" and gaved him display:block and overflow hidden to take away the the space under and then I did give the div1 fixed heigth and width 180px (image+border)
#wrapper {
height: 455px;
width: 690px;
background-color: grey;
margin-left: auto;
margin-right: auto;
margin-top: 10px;
overflow: hidden;
}
.test{
display:block;
overflow: hidden;
}
.div1 {
height:180px;
width:180px;
display: inline-block;
margin-bottom: 10px;
vertical-align:top;
}
.image {
max-width: 172px;
max-height: 172px;
border-radius: 2%;
border: 4px solid blue;
}
.div2 {
height: 172px;
width: 277px;
border: 4px solid blue;
display: inline-block;
margin-left: 30px;
background-color: purple;
}
.div3 {
width: 159px;
height: 188px;
display: inline-block;
margin-left: 30px;
border-left: 4px solid blue;
border-right: 2px solid blue;
border-top: 2px solid blue;
vertical-align: top;
background-color: purple;
}
.div4 {
background: url('http://lorempixel.com/690/265/cats') no-repeat center;
background-size: contain;
width: 690px;
height: 265px;
display:block;
overflow: hidden;
}
<div id="wrapper">
<div class="test">
<div class="div1">
<img src="http://lorempixel.com/172/172/cats" alt="image" class="image">
</div><!--
--><div class="div2">
</div><!--
--><div class="div3">
</div><!--
--> </div><div class="div4">
</div>
</div>
have you checked out box-sizing feature?
Here is some links that might be helpful.
https://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing