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;
}
Related
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>
I have pics that have different width and height, but I want to make them cover fit in the item flexbox, how can I do that?
.item-here img {
width: 100%;
height: auto;
object-fit: cover;
}
.section-grid {
max-width: 1200px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
justify-content: center;
}
.item-here {
width: 200px;
padding: 10px;
height: 300px;
box-sizing: border-box;
text-align: center;
display: flex;
}
<div class="section-grid" id="list-product">
<div class="item-here">
<img class="" src="https://www.lindemans.com/-/media/Images/Lindemans2016/Wine-Bottleshots/Bin-Series/New-Bin-Bromley/Lindemans-Chardonnay-Bin-65-BS.ashx?la=en&sc=1&modified=20190521001727&mw=1382&hash=AE8135A39D9B975147D12D1382ABD0926A327983">
</div>
<div class="item-here">
<img class="" src="https://www.lindemans.com/-/media/Images/Lindemans2016/Wine-Bottleshots/Bin-Series/New-Bin-Bromley/Lindemans-Chardonnay-Bin-65-BS.ashx?la=en&sc=1&modified=20190521001727&mw=1382&hash=AE8135A39D9B975147D12D1382ABD0926A327983">
</div>
</div>
i want to make this box responsive so when in mobile it must be wrap
Change image setting to => object-fit: contain (not cover in your case):
contain The replaced content is scaled to maintain its aspect ratio while fitting within the element’s content box.
https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit
.item-here img {
width: 100%;
height: auto;
object-fit: contain;
}
.item-here {
border: 1px solid red;
width: 200px;
padding: 10px;
height: 300px;
box-sizing: border-box;
text-align: center;
display: flex;
}
.section-grid {
max-width: 1200px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
justify-content: center;
}
<div class="section-grid" id="list-product">
<div class="item-here">
<img class="" src="https://www.lindemans.com/-/media/Images/Lindemans2016/Wine-Bottleshots/Bin-Series/New-Bin-Bromley/Lindemans-Chardonnay-Bin-65-BS.ashx?la=en&sc=1&modified=20190521001727&mw=1382&hash=AE8135A39D9B975147D12D1382ABD0926A327983">
</div>
<div class="item-here">
<img class="" src="https://www.lindemans.com/-/media/Images/Lindemans2016/Wine-Bottleshots/Bin-Series/New-Bin-Bromley/Lindemans-Chardonnay-Bin-65-BS.ashx?la=en&sc=1&modified=20190521001727&mw=1382&hash=AE8135A39D9B975147D12D1382ABD0926A327983">
</div>
</div>
VS object-fit: cover (Your code):
cover The replaced content is sized to maintain its aspect ratio while filling the element’s entire content box. If the object's aspect
ratio does not match the aspect ratio of its box, then the object will
be clipped to fit. https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit
** In general, it's not the best idea to give fixed height to content cols on a responsive site (Could cause to overflow-y issues).
I am trying to create a 2x2 grid where the height of the four individual boxes (red, blue, green, yellow) are all equal despite how much content they contain.
#rowTwo {
background-color: pink;
min-height: 25%;
display: flex;
flex-direction: column;
align-items: center;
}
#grid2x2 {
display: flex;
flex-direction: row;
flex-wrap: wrap;
background-color: orange;
width: 80%;
justify-content: center;
}
.box {
display: flex;
flex-basis: calc(50% - 20px);
margin: 5px;
justify-content: center;
padding-top: 5%;
overflow: hidden;
}
<div id={styles.rowTwo}>
<Heading title="My Title"/>
<div id={styles.grid2x2}>
<div id={styles.boxOne} className={styles.box}>
<DescriptionBoxItemWithHeading item={this.state.sectionTwoItems[0]}/>
</div>
<div id={styles.boxTwo} className={styles.box}>
<DescriptionBoxItemWithHeading item={this.state.sectionTwoItems[1]}/>
</div>
<div id={styles.boxThree} className={styles.box}>
<DescriptionBoxItemWithHeading item={this.state.sectionTwoItems[2]}/>
</div>
<div id={styles.boxFour} className={styles.box}>
<DescriptionBoxItemWithHeading item={this.state.sectionTwoItems[3]}/>
</div>
</div>
</div>
The issue I face is that a box expands to the height of the largest content in a row.
Here is an image outlining my problem:
Would anyone know how I could achieve this?
You can do this in CSS by using padding-top to add the height and then absolute positioning to draw your content on top of this padding.
Here is an example: https://codepen.io/anon/pen/xpwooz
#grid2x2 {
display: flex;
flex-wrap: wrap;
background-color: orange;
}
.box {
display: flex;
flex-basis: calc(50% - 20px);
margin: 5px;
justify-content: center;
overflow: hidden;
background: red;
padding-top: 100px;
position: relative;
}
.content {
position: absolute;
background: green;
top: 0;
width: 100%;
}
The problem is you can't change this height dynamically based on the content height. You can either set it to a fixed size or set it to a percentage and have it change size based on it's parents width. I think you'll need to use javascript if you want the height to change based on the largest content element.
I'm trying to fit an image vertically in a flex container which has a specific height.
The flex-direction is column, and the image is contained in a flex-item with flex-basis: 100%.
In addition, the image's max-height is 100%.
As you can see in the example, the image does not fit into the red container.
#container {
background-color: red;
display: flex;
flex-direction: column;
flex-wrap: wrap;
height: 200px;
width: 320px;
justify-content: space-between;
}
#container > * {
padding: 5px;
}
#img {
flex: 0 1 100%;
/* height: 100%; */
}
img {
max-height: 100%;
max-width: 100%;
}
<div id="container">
<div id="img">
<img src="https://placeholdit.imgix.net/~text?txtsize=33&txt=img&w=340&h=500">
</div>
<div>
Something else
</div>
</div>
Shouldn't the image shrink to fit vertically into the flex container, according to the specification?
The workaround I found is to set the height of #img to 100%, but I have the sensation that it's not the way it should be done.
As an additional note, if I set flex-direction: row to the container, it fits the image horizontally (which is the behaviour I would expect).
You wrote:
The workaround I found is to set the height of #img to 100%, but I have the sensation that it's not the way it should be done.
Actually, it is the way it should be done. The predominant implementation of the spec requires that the height property be applied to the parent when using percentage heights on the child. (Although this is slowly evolving. See my second reference below.)
References:
Working with the CSS height property and percentage values
Heights rendering differently in Chrome and Firefox (includes alternative solutions)
CSS height property definition (W3C)
For some reason, I couldn't get the <img> to behave (probably because it's a replaced element). So I removed it, and used the .img div with an image as background.
Relevant Changes
.container {
...
justify-content: center;
align-items: center;
}
.img {
flex: 1 0 auto;
background: url(https://upload.wikimedia.org/wikipedia/en/2/24/Lenna.png) no-repeat;
background-size: contain;
background-position: center;
width: 100%;
}
SNIPPET
.container {
background-color: red;
display: flex;
flex-direction: column;
flex-wrap: wrap;
height: 200px;
width: 320px;
justify-content: center;
align-items: center;
}
.container > * {
padding: 5px;
}
.somethingElse {
outline: 1px dashed yellow;
background: rgba(128,0,255,.3);
color: white;
}
.img {
flex: 1 0 auto;
background: url(https://upload.wikimedia.org/wikipedia/en/2/24/Lenna.png) no-repeat;
background-size: contain;
background-position: center;
width: 100%;
}
<figure class="container">
<div class="img">
</div>
<figcaption class="somethingElse">
True Dimentions: 512 x 512 px
</figcaption>
</figure>
try this css. its works fine.
#container {
background-color: red;
/*display: flex;*/
flex-direction: column;
flex-wrap: wrap;
height: 200px;
width: 320px;
justify-content: space-between;
}
#img {
height: 85%;
width: 100%;
}
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>