Make a flexbox container with wrapped items scrollable - html

I have a grid of images that are spaced into columns dynamically using flex-wrap: wrap. However there is one problem, I don't know how to make the container scrollable because it has a dynamic height. I have searched for solutions to this problem but I don't really know how to adapt them for my use case.
This is my code:
.imagegrid {
display: flex;
width: 100%;
height: 100%;
background-color: var(--background);
}
.image-container {
display: flex;
flex-direction: row;
width: 100%;
height: 100%;
flex-wrap: wrap;
justify-content: space-between;
padding-left: 30px;
padding-right: 30px;
}
.image {
width: auto;
max-height: 270px;
margin-bottom: 10px;
cursor: pointer;
}
I want to make either the image-container or imagegrid scrollable on the y-axis.
This is the HTML, if needed:
<div class="imagegrid">
<div class="image-container">
<img class="image" src="image"/>
<img class="image" src="image2"/>
(multiple images)
</div>
</div>
The images are added dynamically from a database. I do not know what the height of the container will be.

In order for elements to scroll vertically you must do 2 things
Give them an explicit height that makes them have to scroll
Give them an overflow setting of auto or scroll
I've added a working example with both applied:
.imagegrid {
display: flex;
width: 100%;
height: 200px;
overflow: auto;
background-color: var(--background);
}
.image-container {
display: flex;
flex-direction: row;
width: 100%;
height: 100%;
flex-wrap: wrap;
justify-content: space-between;
padding-left: 30px;
padding-right: 30px;
}
.image {
width: auto;
max-height: 270px;
margin-bottom: 10px;
cursor: pointer;
}
<div class="imagegrid">
<div class="image-container">
<img class="image" src="https://source.unsplash.com/random/200x200" />
<img class="image" src="https://source.unsplash.com/random/250x250" /> (multiple images)
</div>
</div>

Related

Flex container works differently in different browsers?

I am making a web-site. There is content part with specific width. Inside there are flex-boxes with image. The number of images may be different (not more than 5) and the width of each image must be calculated to fit them all.
The strange thing is that in FireFox this work fine, but in Chrome or Yandex.
Seem, that images don't auto-fit in flex-box, because of height: 400px; the width: 100% tries to correspond that 400px height.
Here is HTML and CSS parts:
HTML
<div class="article-images">
<img src="../images/newsImages/img_6_4.jpg" class="article-images-item" />
<img src="../images/newsImages/img_6_5.jpg" class="article-images-item" />
<img src="../images/newsImages/img_6_6.jpg" class="article-images-item" />
<img src="../images/newsImages/img_6_9.jpg" class="article-images-item" />
</div>
CSS
.article-images {
display: flex;
flex-direction: row;
justify-content: space-evenly;
gap: 20px;
width: 100%
}
.article-images-item {
width: 100%;
height: 400px;
object-fit: cover;
border-radius: 2px;
cursor: pointer
}
How it should be (current in FireFox):
How it looks now (in Chrome or other browser)
The following example should help solve it (though we didn't use object-fit in this example).
You can optionally set it up without the image DIV's:
stack post
.flex-container {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: center;
background-color: rgb(0,150,255);
align-items: stretch;
}
.flex-container > div {
background-color: #f1f1f1;
width: 200px; /*--control image size--*/
margin: 5px;
border: 2px solid #fff;
border-radius: 7px;
}
img {
width: 100%;
height:auto;
border-radius: 5px;
cursor: pointer;
display: block;
margin-left: auto;
margin-right: auto;
}
#outer {padding:2px;}
<div id="outer">
<div class="flex-container">
<div style="flex-grow: 1 3 1"><img src="https://via.placeholder.com/100x100.gif?text=1"></div>
<div style="flex-grow: 1 3 1"><img src="https://via.placeholder.com/100x100.gif?text=2"></div>
<div style="flex-grow: 1 3 1"><img src="https://via.placeholder.com/100x100.gif?text=3"></div>
<div style="flex-grow: 1 3 1"><img src="https://via.placeholder.com/100x100.gif?text=4"></div>
</div>
</div>

wrap a flexbox to allow maximum child scaling, while preserving aspect ratios

I'd like to display images in a row, using a flexbox container. In order to play nicely with the other elements onscreen, the container must have a height of exactly 30vh.
The images inside should be scaled as large as possible, while keeping their aspect ratio and not overflowing the row.
The problem is wrapping. On a very wide screen, the images should all be in one row.
But on a tall screen, the row should wrap automatically. This is something I can't manage to do. Either the elements in the flexbox shrink to fit, or they wrap around. But I can't get the to wrap and scale at the same time.
Is it possible to do this with flexbox?
Here's my approach so far. I'm using scss:
.App {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100vh;
background-color: yellow;
}
.row {
display: flex;
flex-direction: row;
justify-content: center;
flex-wrap: wrap;
background-color: blue;
height: 30vh;
}
.item {
// make items grow
flex-basis: 0;
flex: 1;
// only as large as necessary
width: max-content;
height: max-content;
// align image and text
display: flex;
flex-direction: column;
align-items: center;
// just a visual helper
background-color: red;
border-style: solid;
}
img {
// make image shrink to fit
min-width: 0;
min-height: 0;
// contain in parent
max-height: 100%;
max-width: 100%;
// keep aspect ratio
width: auto;
height: auto;
}
A minimal fiddle: https://jsfiddle.net/89jekw4p/8/
Here's a screenshot that illustrates the problem. These images could be much larger, if the row would wrap around:
I might have an idea what is the solution to your problem. First of all, I removed
// make image shrink to fit min-width: 0; , min-height: 0; // contain in parent max-height: 100%; max-width: 100%; // keep aspect ratio width: auto; height: auto;. Because when you have written repeatedly browser only sees what's written on the end of the line so the browser only seeing the width: auto; height: auto; so that is why images keep getting smaller and flex-wrap: wrap does not work. But right now it will work. I hope I could explain it.
<div class="App">
<div class="row">
<div class="item">
<img src="https://www.fillmurray.com/200/300"></img>
</div>
<div class="item">
<img src="https://www.fillmurray.com/200/300"></img>
</div>
<div class="item">
<img src="https://www.fillmurray.com/200/300"></img>
</div>
<div class="item">
<img src="https://www.fillmurray.com/200/300"></img>
</div>
<div class="item">
<img src="https://www.fillmurray.com/200/300"></img>
</div>
</div>
</div>
.App {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
min-height: 100vh;
background-color: yellow;
}
.row {
display: flex;
flex-direction: row;
justify-content: center;
flex-wrap: wrap;
flex: 0 0 100%;
background-color: blue;
height: 30vh;
}
.item {
height: 30vh;
width: auto;
}
img {
max-width: 100%;
height: 30vh;
}

Vertical scrolling for multiple div tags inside a div tag

I am trying to create a scrollable file tree. Minimal code can be found below.
https://jsfiddle.net/3kLmchot/1/
Problem is when I try to add overflow-y: scroll;, to the filebrowse-outer div, the first few items are not visible at all. This problem gets worse when I add more divs.
It seems like items are added about the center of the filebrowse-outer div, so the items that are added at the bottom can be found via scrolling, but the items that are added at the top are invisible. (see the visual aid below)
item 1
item 2
center of the div
item 3
item 4
Scroll bar forms at around item 2, which makes item 1 invisible. Does anyone know why this is happening, and potential solutions?
I got it to work with the following styles, specifically removing justify-content: center; from your .flex-container that is being used by multiple divs and only applying it to the one that is for .flex-container.filebrowse-inner
.side-bar {
position: fixed;
width: 20%;
height: 200px;
display: flex;
flex-direction: column;
}
.flex-container {
display: flex;
/* justify-content: center; <-- THIS LINE IS CAUSING THE ISSUE */
align-items: center;
}
.flex-container.filebrowse-outer {
flex-direction: column;
border: 1px solid #f00;
overflow-y: scroll;
align-items: stretch;
}
.flex-container.filebrowse-inner {
flex-direction: row;
justify-content: center;
width: 100%;
padding-bottom: 15px;
text-align: left;
position: relative;
}
/* .display-container {
width: 70%;
overflow: auto;
} */
I think that you meant to have scroll bar in the external div with class 'side-bar', if yes:
.side-bar {
position: fixed;
width: 20%;
height: 200px;
display: flex;
flex-direction: column;
overflow-y:scroll;
}
.flex-container {
display: flex;
justify-content: center;
align-items: center;
}
.flex-container.filebrowse-outer {
flex-direction: column;
border: solid;
min-height: max-content; /* For safari*/
/* overflow-y: scroll; */
align-items: stretch;
}
.flex-container.filebrowse-inner {
flex-direction: row;
width: 100%;
min-height: max-content; /* For safari*/
padding-bottom: 15px;
text-align: left;
position: relative;
}
.display-container {
width: 70%;
overflow: auto;
}
<div class="side-bar">
<div class="flex-container filebrowse-outer">
<div class="flex-container filebrowse-inner">
<div class="display">
<p>Click Me 1!</p>
</div>
</div>
<div class="flex-container filebrowse-inner">
<div class="display">
<p>Click Me 2!</p>
</div>
</div>
<div class="flex-container filebrowse-inner">
<div class="display">
<p>Click Me 3!</p>
</div>
</div>
<div class="flex-container filebrowse-inner">
<div class="display">
<p>Click Me 4!</p>
</div>
</div>
</div>
</div>
You can then move the border to 'side-bar' class.

Have a div with the same height as a sibling image

I'm trying to do a responsive design of a panel consisting of an image and another container with its own internal elements, both side-by-side.
I have a parent div and inside an img and another div tags. Those two children tags have are floated block with a width in % and that works.
The problem is, when I shrink the page, the img shrinks to respect the % width rule and so does its height and it should stay that way, but the div on the side doesn't change its height to be the same as the sibling image.
I wrapped them in another div and put the internal div at height: 100% in hope that would do the trick but nothing.
I'd like to get the right div to change its height according to the left image.
.img-container {
display: block;
width: 59%;
float: left;
}
img {
width: 100%;
}
.product-container {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 41%;
float: left;
background-color: #e4d233;
}
.product-img {
width: 45%
}
<div class="imgProductContainer">
<div class="img-container">
<img src="http://pngimg.com/uploads/running_shoes/running_shoes_PNG5815.png"/>
</div>
<div class="product-container">
<img id="product2Img" class="product-img" src="http://pluspng.com/img-png/png-gym-shoes-shoe-away-hunger-is-a-partnering-program-where-footwear-is-turned-around-to-provide-an-eco-friendly-means-of-support-for-our-feeding-the-futures-programs-520.png">
<p><span id="product2Name"></span><br>
<span>2.00 €</span></p>
</div>
</div>
.imgProductContainer {
display: flex;
flex-direction: row;
/*
justify-content: center;
  align-items: center;
*/
}
.img-container {
width: 59%;
}
img {
width: 100%;
}
.product-container {
width: 41%;
background-color: #e4d233;
}
.product-img {
width: 45%
}
<div class="imgProductContainer">
<div class="img-container">
<img src="http://pngimg.com/uploads/running_shoes/running_shoes_PNG5815.png" />
</div>
<div class="product-container">
<img id="product2Img" class="product-img" src="http://pluspng.com/img-png/png-gym-shoes-shoe-away-hunger-is-a-partnering-program-where-footwear-is-turned-around-to-provide-an-eco-friendly-means-of-support-for-our-feeding-the-futures-programs-520.png">
<p><span id="product2Name"></span><br>
<span>2.00 €</span></p>
</div>
</div>
i guess thats how it should look like ?
i am not sure what .product-img class was for so i replaced productImg class with it.
i also removed all floats an just made the main container a flex box with its child aligned, you should look deeper into flexbox if you want something else here.
hope it helps
You can force equal height for the containers using CSS Grid:
.img-container {
display: flex;
width: 100%;
flex-direction: column;
justify-content: center;
align-items: center;
}
img {
width: 100%;
}
.imgProductContainer {
display: grid;
grid-template-columns: 1fr 1fr;
}
.product-container {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 100%;
background-color: #e4d233;
}
.product-img {
width: 100%;
}
<div class="imgProductContainer">
<div class="img-container">
<img src="http://pngimg.com/uploads/running_shoes/running_shoes_PNG5815.png"/>
</div>
<div class="product-container">
<img id="product2Img" class="productImg" src="http://pluspng.com/img-png/png-gym-shoes-shoe-away-hunger-is-a-partnering-program-where-footwear-is-turned-around-to-provide-an-eco-friendly-means-of-support-for-our-feeding-the-futures-programs-520.png">
<p><span id="product2Name"></span><br>
<span>2.00 €</span></p>
</div>
</div>

Image exceeds flex parent size [duplicate]

This question already has answers here:
flex child is growing out of parent
(3 answers)
Closed 4 years ago.
I am having an issue with making <img> flexible inside a flex parent. Image start exceeding parent dimensions. I would like to leave parent with display: flex; and restrict image from crossing parent's dimensions.
.full
{
width: 400px;
height: 200px;
background-color: blue;
display: flex;
flex-direction: row;
justify-content: flex-start;
}
.half
{
width: 50%;
background-color: red;
padding: 20px;
}
img
{
width: auto;
height: auto;
max-width: 100%;
max-height: 100%;
}
<div class="full">
<div class="half">
<h1>title</h1>
<img src="http://placehold.it/90x200">
</div>
</div>
Can you please explain and give some useful links that would explain the shown behavior and possible solution of it?
I am using both Firefox and Chrome to view that. Issue persist in both browsers.
It seems that question is duplicate of this question
In order for it to work .half div also needs to be a flexbox container and the image needs to have min-height: 0, as explained here.
.full
{
width: 400px;
height: 200px;
background-color: blue;
display: flex;
flex-direction: row;
justify-content: flex-start;
}
.half
{
width: 50%;
background-color: red;
padding: 20px;
display: flex;
flex-flow: column nowrap;
justify-content: flex-start;
}
img
{
min-height: 0;
max-width: 100%;
max-height: 100%;
}
<div class="full">
<div class="half">
<h1>title</h1>
<img src="http://placehold.it/90x200">
</div>
</div>