Image width 100% of the Flex div - css

I want to make an image have a max-width 100% of the parent div, where the parent div is a flex element.
But when I give image 100% width, the image overflows the content!
Fiddle:
https://jsfiddle.net/3f8k19g5/1/
<div class="container">
<div class="image">
<img src="https://m.xcite.com/media/catalog/product/cache/1/image/9df78eab33525d08d6e5fb8d27136e95/b/u/buy_apple_imac_21.5_inch_all_in_one_desktop__lowest_price_in_ksa_2.jpg" alt="">
</div>
<div class="text">This is an iMac</div>
</div>
CSS:
.container{
width: 800px;
background-color: red;
display: flex;
}
.image{
background-color: blue;
flex-grow: 2;
max-width: 100%;
}
.text{
background-color: yellow;
flex-grow: 1;
}

I went ahead and updated your code. Run the snippet below.
The image class was being applied to the parent div, I instead moved it to the img tag so the image take 100% of the container div.
.container{
width: 800px;
background-color: red;
display: flex;
}
.image{
background-color: blue;
flex-grow: 2;
max-width: 100%;
width: 100%;
}
.text{
background-color: yellow;
flex-grow: 1;
}
<div class="container">
<!= Feel free to remove the empty div around the image tag if you arent using it ->
<div>
<img class="image" src="https://m.xcite.com/media/catalog/product/cache/1/image/9df78eab33525d08d6e5fb8d27136e95/b/u/buy_apple_imac_21.5_inch_all_in_one_desktop__lowest_price_in_ksa_2.jpg" alt="">
</div>
<div class="text">This is an iMac</div>
</div>

Related

How do I keep flexbox containers 50/50 with a large image involved?

I'm trying to create a Flexbox setup comprised of two div elements which are both taking up 50% of the width of the screen equally.
The left side will have some text and the right side will have an image which will only fill the whole of it's 50% of the width, shrinking larger images down if necessary.
What's the best way to achieve this? I'm fairly new to Flexbox.
.content{
position: relative;
display: flex;
width: 100%;
height: 600px;
}
.content div{
flex-direction: column;
justify-content: center;
flex: 1;
}
.text{
background-color: pink;
}
.image{
background-color: paleturquoise;
}
<section class="content">
<div class="text">
<p>text goes here</p>
</div>
<div class="image">
<img src="https://i.imgur.com/rcZLIwH.jpg" alt="image">
</div>
</section>
You can make the .image position: relative and set the width of the image to 100%:
.content{
position: relative;
display: flex;
width: 100%;
height: 600px;
}
.content div{
flex-direction: column;
justify-content: center;
flex: 1;
}
.text{
background-color: pink;
}
.image{
background-color: paleturquoise;
/* make the parent position relative */
position: relative;
}
.image img {
/* make the width of the image equal to the parent width */
width: 100%;
}
<section class="content">
<div class="text">
<p>text goes here</p>
</div>
<div class="image">
<img src="https://i.imgur.com/rcZLIwH.jpg" alt="image">
</div>
</section>

Absolute scrollable div inside flex container without fixed height, is it possible?

How do I set a div as scrollable (absolute) without fixed height filling entire view, while inside a flex-box?
(https://imgur.com/7v5OFas)
(typo at the right section, its fixed width, the only height expected is to be fullpage everything)
https://codepen.io/anon/pen/oJyOOp?editors=1000
(if I add height to the relative parent of the red section, it works, but I cant have a fixed height. Adding 100% from html to the relative parent also works, but I can't also do that.)
currently it goes:
<div style="display:flex">
<div style="flex-grow:1">
<div style="display:flex">
<div style="width:45px...">
....
</div>
<div ...header code>
....
</div>
<div style="flex-grow:1; top:70px; position: relative">
<div style="position: absolute; top:0; left:0; right:0; bottom: 0; overflow: auto>
</div>
</div>
</div>
</div>
<div style="width:45px...">
....
</div>
</div>
It ends up filling the header height.
I would drop the idea of absolute content if its not necesarry and try something similiar to:
html, body {
min-height: 100%;
height: 100%;
margin: 0;
}
.container{
background: blue;
display: flex;
height: 100%;
flex-flow: row;
}
.sidebar{
background: red;
height: 100%;
width: 200px;
}
.contentWrapper{
display: flex;
flex-flow: column;
flex: 1;
}
.header {
background: yellow;
height: 100px;
width: 100%;
}
.content {
flex: 1;
overflow: auto;
}
.scrollableContent {
height: 3000px;
}
<div class="container">
<div class="sidebar"></div>
<div class="contentWrapper">
<div class="header"></div>
<div class="content">
<div class="scrollableContent">
</div>
</div>
</div>
</div>
Where you basically make every container a flex and the non scalable part of its content will have fix width/height and the other part get flex: 1 which is shorthand for taking rest of the space.

How can I shrink a img to fit its flex container?

In this JSFiddle how can I downsize the img / img-container to be only as wide as its widest sibling div?
.outer {
display: inline-flex;
flex-flow: column;
}
.outer span {
display: flex;
}
div {
border: 1px dotted black;
}
<div class="outer">
<div>
<span>text</span>
<span>more text</span>
</div>
<div>
<img src="https://cdn.sstatic.net/Sites/stackoverflow/img/apple-touch-icon#2.png?v=73d79a89bded">
</div>
<div>
<span>this should determine width</span>
</div>
</div>
I'm not sure how cross-browser compatible this solution is, but it works on Chrome 64, Safari 11, and Firefox 57.
Give the element containing the img a width: 0; min-width: 100%; max-width: 100%;, and the img itself a width: 100%;.
Like this:
div {
border: 1px dotted black;
}
.outer {
display: inline-flex;
flex-flow: column wrap;
}
.child {
width: 0;
min-width: 100%;
max-width: 100%;
}
.img {
width: 100%;
}
<div class="outer">
<div>
<span>text</span>
<span>more text</span>
</div>
<div class="child">
<img class="img" src="https://cdn.sstatic.net/Sites/stackoverflow/img/apple-touch-icon#2.png?v=73d79a89bded" />
</div>
<div class="main">
<span contenteditable>this should determine width</span>
</div>
</div>
Another Solution
Use a background-image instead of an img. This allows us to make the image scale with the width of the widest element in the flexbox.
The trick is to set a padding-bottom on the element with the image proportional to the image proportions. In this case the image is square, so I'll set `padding-bottom: 100%; so it creates a square element.
If the image was a wide rectangle, 200 x 100 px, I would set padding-bottom: 50%. Or, if the image was a tall rectangle, 100 x 200 px, I would set padding-bottom: 200%.
Like this:
div {
border: 1px dotted black;
}
.outer {
display: inline-flex;
flex-flow: column wrap;
}
.img {
background-image: url(https://cdn.sstatic.net/Sites/stackoverflow/img/apple-touch-icon#2.png?v=73d79a89bded);
background-repeat: no-repeat;
background-size: cover;
padding-bottom: 100%;
}
<div class="outer">
<div>
<span>text</span>
<span>more text</span>
</div>
<div class="img">
</div>
<div>
<span contenteditable>this should determine width</span>
</div>
</div>
You can do this with CSS table layout and set width: 1% on table and white-space: nowrap on text elements.
.outer {
display: table;
width: 1%;
}
.outer span {
white-space: nowrap;
}
div {
border: 1px dotted black;
}
img {
max-width: 100%;
}
<div class="outer">
<div><span>text</span><span>more text</span></div>
<div class="image">
<img src="https://cdn.sstatic.net/Sites/stackoverflow/img/apple-touch-icon#2.png?v=73d79a89bded">
</div>
<div><span>this should determine width</span></div>
</div>
As you asked about it for flexbox layout particularly, here is trick playing with pseudo and positions. Note, it only works if you know the image aspect ratio already, example below for a square image.
div {
border: 1px dotted black;
}
.outer {
display: inline-flex;
flex-flow: column;
}
.image {
position: relative;
}
.image:before {
content: "";
display: block;
padding-top: 100%;
/*https://stackoverflow.com/a/10441480/483779*/
}
.image img {
position: absolute;
left: 0;
top: 0;
max-width: 100%;
}
<div class="outer">
<div class="image">
<img src="https://cdn.sstatic.net/Sites/stackoverflow/img/apple-touch-icon#2.png?v=73d79a89bded">
</div>
<div>this should determine width</div>
</div>
Your CSS container is already as wide as its widest sibling div. You just need to shrink the border of the picture with paint or photoshop.

Auto-resize image in flex item

I have the following html :
<div class="main-container">
<h1>A title</h1>
<p>Some text</p>
<div class="sub-container">
<img src="">
</div>
</div>
With the following CSS :
.main-container{
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
}
.sub-container{
flex-grow:2;
background-color: green;
}
Please note that I don't know the size of the container above "main-container". I'm using flex because I want the div in "main-container" to occupy all the remaining space at the bottom.
What I want is to have an image in "sub-container" which fits its parent's size in both directions (height and width). Right now if I add an image into "sub-container" it overflows and doesn't get scaled at all.
I know that flex only works for immediate children (i.e. "sub-container" but not the image inside). I tried to use flex on "sub-container" too, but I couldn't achieve anything satisfactory.
Is this layout you wanted?
Using flex: 1 1 0 to control the sub-container and using width: 100% could make the image to fit the container.
.main-container{
border: 3px solid green;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
}
.sub-container{
flex-grow: 1 1 0;
background-color: green;
display: flex;
}
.sub-container img {
width: 100%;
height: 100%;
}
<div class="main-container">
<h1>A title</h1>
<p>Some text</p>
<div class="sub-container">
<img src="https://picsum.photos/1080/600">
</div>
</div>
You can use this class:
.img-fluid {
max-height:100%;
height:auto;
}
Don't forget to add .img-fluid to your img

Flex item override max-width property

I am trying to make a flex container of divs in which all the divs will have the same width (two divs per line, 50% width of the container each of them).
I have set the divs inside the container with max-width: 50%; because I want them to be equals but it does not seem to respect this max-width when there is only one item in this line.
HTML:
<div id="container">
<div id="left" class="block">Left</div>
<div id="center" class="block">
<div class="flexContainer">
<div class="flexDiv"></div>
</div>
<div class="flexContainer">
<div class="flexDiv"></div>
</div>
<div class="flexContainer">
<div class="flexDiv"></div>
</div>
</div>
<div id="right" class="block">Right</div>
</div>
CSS:
html, body{
width: 100%;
height: 100%;
}
#container{
display: flex;
height: 100%;
background-color: blue;
}
.block{
flex: 1;
}
#left{
background-color: green;
}
#center{
display: flex;
flex: 1;
flex-wrap: wrap;
align-content: flex-start;
}
#right{
background-color: orange;
}
.flexContainer{
flex: 1;
min-width: 100px;
max-width: 50%;
height: 150px;
background-color: red;
padding: 10px;
}
.flexDiv{
width: 100%;
height: 100%;
background-color: yellow;
}
JSFiddle in which you can see how the width of the third element is bigger than the others.
Why the flex divs inside the container are not respecting max-width property?
Thanks in advance!
you can reset or switch box model to include padding within width calculation:
https://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing
https://www.w3.org/TR/css-ui-3/#box-sizing
.flexContainer{
flex: 1;
min-width: 100px;
max-width: 50%;
height: 150px;
background-color: red;
padding: 10px;
box-sizing:border-box;/* includes borders & padding within width calculation
}
https://jsfiddle.net/b5h9rjcd/1/

Resources