css3 flex: why img take more width than contains? - html

Why .itm in this case take width 400px instead of 160px? In other cases div take same width like child, but when img is bigger and browser scale it - I got empty space
How to fix it? I fount only one way: set <img height="..." width="..." />, but I want more more suitable way because I don't know real image size.
.box {
display: flex;
}
.box .itm {
max-height: 400px;
max-width: 400px;
background: red;
margin-right: 10px;
}
.box .itm img {
max-height: 100%;
max-width: 100%;
}
.box .itm .tst {
width: 160px;
height: 400px;
background: lime;
}
<div class="box">
<div class="itm">
<img src="https://picsum.photos/300/750"/>
</div>
<div class="itm">
<div class="tst">same block with 160x400 sime like img</div>
</div>
</div>

Problem
As the flex items do not have width or flex-basis properties defined, flex container space distributed as first element will take the max-width size, and the second item will take the remaining space.
Solution
Add width and flex-basis properties to flex items

I didn't understand why this is happening
I fixed this by moving the max-width directly to each image. In my case, this solves the problem, but it would not help if there was not only a picture but also other content in the container.
.box {
display: flex;
}
.box .itm {
display: flex;
background: red;
margin-right: 10px;
}
.box .itm img {
max-height: 400px;
max-width: 400px;
}
.box .itm .tst {
width: 160px;
height: 400px;
background: lime;
}
<div class="box">
<div class="itm">
<img src="https://picsum.photos/300/750"/>
</div>
<div class="itm">
<div class="tst">same block with 160x400 sime like img</div>
</div>
</div>

Related

Force one div to change size of other div inside the same parent, so the first one can be seen

I have a div with two contents: an image (on top) and text (on bottom).
Height of image plus height of the text is bigger than the height of the parent.
I want an image to shrink, so the whole text will be visible.
So - now it looks like this:
And I want it to look like this:
How to achieve this?
I tried it with display: flex and flex-shrink or flex-grow, but it's not working.
Solution with flex will be much appreciated :)
Here's a codepen with an example:
https://codepen.io/anon/pen/zQXyLb
And here's code used:
<html>
<head></head>
<body style="background: yellow;">
<div style="
width: 150px;
height: 150px;
background: #ddd;
overflow: hidden;
display: flex;
flex-direction: column;
">
<div>
<img src="https://emojipedia-us.s3.dualstack.us-west-1.amazonaws.com/thumbs/120/apple/198/skull_1f480.png">
</div>
<div>
<div>Here i have some text</div>
<div>which is multiline</div>
<div>and it should make</div>
<div>the skull smaller</div>
</div>
</div>
</body>
</html>
Instead of img tag try div with background-image.
flex: is short form of: flex-grow, flex-shrink, flex-basis.
0 0 auto means that element will take just as much space as needed.
1 1 auto means that element will take all available space — so image takes box size minus text size. And text is always visible.
.box {
display: flex;
flex-direction: column;
margin-bottom: 20px;
width: 150px;
height: 150px;
background: #ddd;
}
.image {
flex: 1 1 auto;
background: url(https://emojipedia-us.s3.dualstack.us-west-1.amazonaws.com/thumbs/120/apple/198/skull_1f480.png) 0 0 no-repeat;
background-size: contain;
}
.text {
flex: 0 0 auto;
}
<div class="box">
<div class="image"></div>
<div class="text">
<div>Here I have some text</div>
<div>which is multiline</div>
<div>and it should make</div>
<div>the skull smaller</div>
</div>
</div>
<div class="box">
<div class="image"></div>
<div class="text">
<div>Here I have small text</div>
</div>
</div>
You can also keep image in the HTMl if you inbricate flex boxes to allow img container to shrink and img understand max-height:100%;
body {
background-color: #a3d5d3;
}
[class],
[class]>div {
display: flex;
flex-direction: column;
overflow: hidden;
}
img {
max-height: 100%;
margin-right: auto;
}
[class]>div[id] {
flex-grow: 1;
flex-shrink: 0;
}
<div class style="
width: 150px;
height: 150px;
background: #ddd;
">
<div>
<img src="https://emojipedia-us.s3.dualstack.us-west-1.amazonaws.com/thumbs/120/apple/198/skull_1f480.png">
</div>
<div id>
<div>Here i have some text</div>
<div>which is multiline</div>
<div>and it should make</div>
<div>the skull smaller</div>
</div>
</div>
Resize the image using css.
img{
max-width:50px;
}
The above code should make the image flexible and allow it to be smaller.
Also you can put variable height to the parent div, i.e.
<div style="
width: 150px;
max-height: 250px; //added this part
background: #ddd;
overflow: hidden;
display: flex;
flex-direction: column;
">
But this way the image will stay large but the parent's height will increase. Allowing the text to appear in the enlarged div.

Style height of div with image to fill height of parent

Refer to this Fiddle.
I have a top-level div whose height is configured as one screen height (height:100vh). Within this div, there is a fixed-height (60px) child div and another child div I want to grow to fill the remaining height (so as to be responsive with different screen sizes).
This child div has an image and some text. Currently, its width is hard-coded, or else the image fills the entire screen (and exceeds the length of its parent). Setting height:100% (or even calc(100% - 60px)) doesn't scale the div as I'd hoped.
.one-page {
min-height: 100vh;
max-height: 100vh;
background-color: #FF5555;
}
.fixed-size {
height: 60px;
border-style: solid;
}
.main-container {
background-color: #55FF55;
width: 300px;
margin: auto;
}
.subtitle {
text-align: center
}
.other {
background-color: blue;
}
img {
vertical-align: middle;
width: 100%;
height: auto;
}
<body>
<div class="one-page">
<div class="fixed-size">
this div is a fixed size
</div>
<div class="main-container">
<p>
<img src="http://images.clipartpanda.com/square-clip-art-clipart-square-shield-256x256-e296.png">
</p>
<div class="subtitle">
subtitle text
</div>
</div>
</div>
<div class="other">
something else
</div>
</body>
Try to use height:calc(100vh - 60px).
.main-container {
background-color: #ff00ff;
width: 300px;
margin: auto;
padding:0;
height:calc(100vh - 60px);
}
DEMO
Use flexbox to work it out. Run the below snippet and you'll understand. flex-grow: 1 will basically give all the remaining height to the second child.
.p {
height: 100vh;
display: flex;
flex-direction: column;
}
.c1 {
height: 60px;
background-color: green;
}
.c2 {
flex-grow: 1;
background-color: red;
}
<div class="p">
<div class="c1"></div>
<div class="c2"></div>
</div>

responsive 3-columns layout with third column having fixed size

I am trying to create a simple element consisting of 3 columns, the 3. column being an icon-image.
I want the element to be responsive, but the icon-image should always have the same size (e.g. 40x40 px).
So, the 1. and 2. column should have % values, the 3. column should have width 40px. I don't want the icon-image to resize on smaller screens. The icon should always have width 40px.
.container {
width: 80%;
}
.text1 {
float: left;
width: 30%;
}
.text2 {
float: left;
width: 50%;
}
.image {
float: right;
width: 120px;
}
<div class="container">
<p class="text1">Some Titel</p>
<h3 class="text2">Some Text and some more text...</h3>
<img src="image1.jpeg" alt="" class="image" />
</div>
https://jsfiddle.net/mkrizanek/usfmk6r7
Kind regards,
Milan
I have tweaked a little bit with HTML and CSS. But I hope you will get the logic. I have changed the display-type of container to flex. You can change the with of elements inside container as per your requirements.
.container {
background-color: #DDDDDD;
width: 80%;
display: flex;
}
.text {
background-color: #BBBBBB;
width: 50%;
}
.heading {
background-color: #999999;
width: 50%;
}
img {
max-width: 120px;
max-height: 120px;
}
<div class="container">
<p class="text">Some Text</p>
<h3 class="heading">Heading</h3>
<img src="https://www.w3.org/html/logo/downloads/HTML5_Logo_512.png" class="image" />
</div>
Your best option is probably to use flex.
Set "display: flex; justify-content: space-between" on the container div, and "flex: 1;" on each section that you want responsive.
If you want the text in the second div to push all the way to the image, you can also add "text-align: right;" to it.
.container {
display: flex;
justify-content: space-between;
}
.text1 {
flex: 1;
}
.text2 {
flex: 1;
}
.image {
width: 40px;
height: 40px;
background: #088;
}
<div class="container">
<p class="text1">Some Title</p>
<h3 class="text2">Some Text and some more text...</h3>
<img alt="" class="image" />
</div>
Here is a good resource for flexbox: https://css-tricks.com/snippets/css/a-guide-to-flexbox/.

float:left even if parent div is too small

The issue I am facing here has to do with the fact that the total width of the child divs is larger than the width of the parent div. I need the child divs to float to the left of each other even if they overflow the parent div.
I have this HTML:
<div class="gallery_container">
<div id="viewport">
<div class="gallery_img_container">
<img src="images/1/1.png" class="gallery_img">
</div>
<div class="gallery_img_container">
<img src="images/1/2.png" class="gallery_img">
</div>
<div class="gallery_img_container">
<img src="images/1/3.png" class="gallery_img">
</div>
</div>
</div>
And this CSS:
.gallery_container {
width: 70%;
height: 100%;
float: left;
background-color: #171717;
}
#viewport {
height: 100%;
width: 100%;
}
.gallery_img_container {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.gallery_img {
height: 95%;
}
How can I get all divs with of class gallery_img_container to float to the left of each other? I've tried adding float:left .gallery_img_container but it doesn't do anything. They go underneath each other instead of side by side.
Another note is that .gallery_img_container must have the display:flex property
Thanks in advance for any help!
EDIT: .gallery_img_container must have the width:100% property
You have "width:100%;" applied to the ".gallery_img_container" class causing each container to break into next line, remove this and add "float: left;" then it will work.
Edited based on comments.
.gallery_container {
width: 70%;
height: 100%;
background-color: #171717;
}
#viewport {
height: 100%;
width: 100%;
display: flex;
}
.gallery_img_container {
width: 100%;
height: 100%;
display: flex;
flex-direction: row;
justify-content: flex-start;
flex-wrap: wrap;
}
.gallery_img {
height: 95%;
}
<div class="gallery_container">
<div id="viewport">
<div class="gallery_img_container">
<img src="images/1/1.png" class="gallery_img">
</div>
<div class="gallery_img_container">
<img src="images/1/2.png" class="gallery_img">
</div>
<div class="gallery_img_container">
<img src="images/1/3.png" class="gallery_img">
</div>
</div>
</div>
Farasat,
I'm not entirely sure what you are trying to accomplish. Let me see if I can confirm what I think you are seeking. You want to achieve a result where you have a set of images which are, collectively, wider than #viewport, but you want them to keep "piling up" to the right. That is, you don't want them to wrap. If we consider [] the bounds of the viewport and # to be an image, you want (for example), something like this:
[#]##
Is this right?
If so, I think a key thing to note is that your gallery_img_container is of display flex, which means it is a block, not inline, style. This will cause the gallery_img_containers to stack, not flow to the right.
I think all you need to do is to say "white-space: nowrap;" in #viewport (to keep things from wrapping), and then to make gallery_img_container to be of type inline-flex, so that they do not stack.
I'm attaching an example to hopefully demonstrate what I mean (notes: I just grabbed a random image off the web to make this more concrete. Also note that since your gallery_img_container is 100%, each image is the size of the #viewport. I'm not sure if that's what you want).
.gallery_container {
width: 70%;
height: 100%;
background-color: #171717;
}
#viewport {
height: 100%;
width: 100%;
white-space: nowrap;
}
.gallery_img_container {
width: 100%;
height: 100%;
display: inline-flex;
justify-content: center;
align-items: center;
}
.gallery_img {
height: 95%;
}
<div class="gallery_container">
<div id="viewport">
<div class="gallery_img_container">
<img src="https://wildfiregames.com/forum/uploads/monthly_2016_07/elephant.png.d12017f872cf14f8b046706f497701ba.png" class="gallery_img">
</div>
<div class="gallery_img_container">
<img src="https://wildfiregames.com/forum/uploads/monthly_2016_07/elephant.png.d12017f872cf14f8b046706f497701ba.png" class="gallery_img">
</div>
<div class="gallery_img_container">
<img src="https://wildfiregames.com/forum/uploads/monthly_2016_07/elephant.png.d12017f872cf14f8b046706f497701ba.png" class="gallery_img">
</div>
</div>
</div>

Justify elements with fix space (variable width)

I have a container with a variable number of elements in it.
The elements should be justified but with a fix space between (e.g. 20px).
That means the width of every element has to adapt.
For example this:
HTML
<div class="container">
<div>
<img src="...">
</div>
<div>
<img src="...">
</div>
<div>
<img src="...">
</div>
</div>
CSS
div.container {
text-align: justify;
}
div.container div {
display: inline-block;
margin-right: 20px;
}
div.container div img {
width: 100%;
}
At the end it should look like this (this picture shows two examples: 2 elements and 3 elements; the width is dynamic but the space fix [20px]):
It should work with a different number of child elements.
Is there a professional way to do this with CSS?
EDIT: I should mention that this fix space is a %-value!
If using Flexbox is an option, you could add flex: 1 to the flex items and also a margin property with a fixed value as follows:
EXAMPLE HERE
div.container { display: flex; }
div.container div {
height: 50px; /* Just for demo */
flex: 1;
margin-left: 20px;
}
div.container :first-child { margin-left: 0; }
Actually, flex: 1 is a shorthand of flex-grow: 1; in this case.
You can use display: table and display: table-cell for this:
.container {
display: table;
width: 100%;
border-spacing: 10px 0;
border-collapse: separate;
background: palevioletred;
}
.container div {
display: table-cell;
}
.container img {
display: block;
width: 100%;
height: auto;
}
<div class="container">
<div><img src="//dummyimage.com/200x100/000/CCC"></div>
<div><img src="//dummyimage.com/300x100/000/CCC"></div>
<div><img src="//dummyimage.com/400x100/000/CCC"></div>
</div>
<hr/>
<div class="container">
<div><img src="//dummyimage.com/200x100/000/CCC"></div>
<div><img src="//dummyimage.com/400x100/000/CCC"></div>
</div>
<hr/>
<div class="container">
<div><img src="//dummyimage.com/600x100/000/CCC"></div>
</div>