Hi chaps. Would I be better off using grid, columns or something else for the following layout? The width of each cell would be about 320px max. I guess I would need to make sure the words came before the image in all cases on mobile.
Are the images and their text descriptions in pairs horizontally or are they going vertically in two columns? Its hard to tell from the screenshot?
Either grid or flex would do but if you wanted items packed vertically like a masonry layout then css columns would be better.
The simplest would be flex in rows of two and then you could use the order property on :even items to move the image to the left.
That’s how I see it, with a class of something like ‘.switch-direction’ on each alternate row for the desktop view.
Edit: I need to learn to read ‘order property on :even items’ lol
Or nth(even) ot nth(odd) ?
Here’s a quick version using both grid and flex for more robustness.
The image size could be controlled either with a max-width or a max-height or just allowed to stretch. It all depends on what’s required ![]()
Thank you, kind sirs, and thanks especially for the Pen, Paul. My aged brain finds these things more complicated these days. ![]()
Just for fun, I thought I would try an alternative approach:
Ha! Spoilt for choice!
Thanks.
It’s a quiet day ![]()
So just for fun this is how we would have set about this 16 years ago. No flex and no grid and no floats needed either.
Will work back to IE8 but no shift of image as :nth-child wasn’t implemented until IE9 (although I could simply have added alternate classes to the mark up). Media queries only available from IE9 (about 12 years ago).
The mark up could have remained unchanged from the flex/grid example if the full length background colours were not added.
We’ve come a long way but display table properties were around in IE8 (2009) and could do very solid layouts.![]()
Cunning! You really need to get out more, squire! ![]()
Thatta smart one, Archibald! I would not have guessed that flex-direction: row-reverse; would not be applied anymore if the elements are stacked as a result of a narrow viewport. Thanx, that makes the CSS for such layouts a lot easier.
The flex-direction: row-reverse still applies on a narrow viewport. With flex-wrap: wrap, we are used to things wrapping when there’s no room on right-hand side but with row-reverse, they wrap when there is no room on the left-hand side.
Got it. Thanx again. ![]()
Hey Paul,
In which case(s) would just flex not be robust enough?
If you wanted the layout to remain in two columns exactly then flex cannot ensure that without fixing dimensions in some way. Grid does it automatically and also allows images to be percentage based on the available space. Sometimes flex does not allow that unless the space is defined.
If in the example from @Archibald you changed the width of one column you get uneven columns which of course may be what you want in some cases but is a different effect.
Flex is more useful for horizontal alignment but grid is best for both horizontal and vertical alignment. Sometimes either/or is fine but grid is more robust for columns and rows.
No right or wrong way for this example but the demo by @Archibald is a little more succinct
and works well without the need for a media query.
My CodePen switches into single column appearance when the container becomes less than 620px wide. That is because of the text and image min-width: 300px together with the gap: 20px. There is no @media. Instead the layout is controlled by the min-width value and gap value.
Here’s one for Paul
:
I have changed the last CSS rule to flex: 1 1 300px; and deleted the min-width.
With just the hairpin bend image, why do the widths of the text and image elements not grow or shrink equally starting at 300px flex basis?
flex-basis is really just a suggestion but in your case the natural image width of the hairpin bend is 600px so the 300px basis is ignored and the natural intrinsic width of the image takes over. If you set img {width:300px} as well it should revert all the images to the same size initially but still allow them to flex.
.text, img {
flex: 1 1 300px;
}
img{width:300px}
You could also do it with a wrapper for the image and then size the image to fit the wrapper.
e.g.
.text, .imgwrap {
flex: 1 0 300px;
}
img{
width:100%;
}
html:
<div class="item">
<div class="text">
<h2>Heading 2</h2>
<p>Description for item 2. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Adipisci vel nulla fugit ex molestiae nemo quasi iure ipsum, sint atque ullam enim ratione, mollitia laudantium unde iusto sequi et quidem?</p>
</div>
<div class="imgwrap">
<img src="https://picsum.photos/id/237/300/200" alt="example pic">
</div>
</div>
Of course there are probably other ways ![]()
Thanks for the workarounds Paul. It turns out the workaround I had used in my first CodePen was to set a value of min-width on the images. This was very surprising until I read this in the flex-basis specification:
By default, flex items won’t shrink below their minimum content size (the length of the longest word or fixed-size element). To change this, set the min-width or min-height property. (See § 4.5 Automatic Minimum Size of Flex Items.)
There are interesting possibilities if text and images have differing flex-grow values..
I just remembered we discussed some of these things before. ![]()
I still have to double check my understanding as there’s a lot more to flex than meets the eye ![]()
You have a very good memory Paul.
I have now read 4.5 Automatic Minimum Size of Flex Items. The behaviour of images as flex items continues to make no sense to me. The reasoning for the behaviour is said to be:
To provide a more reasonable default minimum size for flex items . . . .
When designing a web page, I would be more concerned about images stretching so their resolution starts to look poor than about images becoming smaller than their intrinsic dimensions.
It may be worth noting that <video> elements behave in the same way when flex items and some other elements can behave in the same way.
For me the work-around is to use min-width: 0 or some other value; not to put images in containers unnecessarily.
I was expecting to see tables, but that is possibly a bit further back. The good ol’days of tag soup. ![]()
