How to get flexbox columns to be the same height? - html

I am trying to wrap my head around flexbox and I have hit a wall with something very simple that I can't seem to get right.
I have 6 columns that I want all the same height with 3 on each row. I have set the flex items to have a width of 33% but I have not set a height on anything. I thought once the flex items had content it would take the one with the greatest height and match everything to it.
Here is my markup:
.container {
width: 800px;
padding: 0 15px;
}
.row-flex {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
margin-right: -15px;
margin-left: -15px;
flex-wrap: wrap;
}
.flexbox {
flex: 0 0 33%;
padding: 0 15px;
}
.icon-box-1 {
position: relative;
margin-bottom: 50px;
background: #fff;
text-align: center;
border: 1px solid #eee;
padding: 10px;
}
<div class="container">
<div class="row-flex">
<div class="flexbox">
<div class="icon-box-1">
<h1>
One
</h1>
<h3>Title</h3>
<p>lots of random text, lots of random text, lots of random text, lots of random text</p>
</div>
</div>
<div class="flexbox">
<div class="icon-box-1">
<h1>
Two
</h1>
<h3>Title</h3>
<p>lots of random text</p>
</div>
</div>
<div class="flexbox">
<div class="icon-box-1">
<h1>
Three
</h1>
<h3>Title</h3>
<p>lots of random text, lots of random text, lots of random text, lots of random text</p>
</div>
</div>
<div class="flexbox">
<div class="icon-box-1">
<h1>
Four
</h1>
<h3>Title</h3>
<p>lots of random text, lots of random text, lots of random text</p>
</div>
</div>
<div class="flexbox">
<div class="icon-box-1">
<h1>
Five
</h1>
<h3>Title</h3>
<p>lots of random text, lots of random text, lots of random text</p>
</div>
</div>
<div class="flexbox">
<div class="icon-box-1">
<h1>
Six
</h1>
<h3>Title</h3>
<p>lots of random text, lots of random text, lots of random text</p>
</div>
</div>
</div>
</div>

The equal height columns feature comes from align-items: stretch, which is an initial setting on a flex container. It makes flex items consume all available space in the cross axis.
If you check the actual size of each flex item, you will see that they are, in fact, equal height on each row (demo).
The problem is that the content of each item (.icon-box-1) is not stretching full height. It's just height: auto (content height), by default.
In order for the content to stretch full height, add display: flex to each flex item, so align-items: stretch goes into effect, like on the parent (demo).
Then use flex: 1 to make the content fill the remaining space on the main axis (demo).
.container {
width: 800px;
padding: 0 15px;
}
.row-flex {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
margin-right: -15px;
margin-left: -15px;
flex-wrap: wrap;
}
.flexbox {
flex: 0 0 33%;
padding: 0 15px;
border: 1px dashed red; /* for illustration */
display: flex; /* new */
}
.icon-box-1 {
flex: 1; /* NEW */
position: relative;
margin-bottom: 50px;
background: #fff;
text-align: center;
border: 1px solid #eee;
padding: 10px;
}
<div class="container">
<div class="row-flex">
<div class="flexbox">
<div class="icon-box-1">
<h1>
One
</h1>
<h3>Title</h3>
<p>lots of random text, lots of random text, lots of random text, lots of random text</p>
</div>
</div>
<div class="flexbox">
<div class="icon-box-1">
<h1>
Two
</h1>
<h3>Title</h3>
<p>lots of random text</p>
</div>
</div>
<div class="flexbox">
<div class="icon-box-1">
<h1>
Three
</h1>
<h3>Title</h3>
<p>lots of random text, lots of random text, lots of random text, lots of random text</p>
</div>
</div>
<div class="flexbox">
<div class="icon-box-1">
<h1>
Four
</h1>
<h3>Title</h3>
<p>lots of random text, lots of random text, lots of random text</p>
</div>
</div>
<div class="flexbox">
<div class="icon-box-1">
<h1>
Five
</h1>
<h3>Title</h3>
<p>lots of random text, lots of random text, lots of random text</p>
</div>
</div>
<div class="flexbox">
<div class="icon-box-1">
<h1>
Six
</h1>
<h3>Title</h3>
<p>lots of random text, lots of random text, lots of random text</p>
</div>
</div>
</div>
</div>

Try adding "display: flex" to .flexbox and "flex: 0 1 auto" to the icon box so it fills the heights out. Here ya go:
.container {
width: 800px;
padding: 0 15px;
}
.row-flex {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
margin-right: -15px;
margin-left: -15px;
flex-wrap: wrap;
}
.flexbox {
flex: 0 0 33%;
padding: 0 15px;
display: flex;
flex-wrap: wrap;
flex-direction: column;
}
.icon-box-1 {
position: relative;
margin-bottom: 50px;
background: #fff;
text-align: center;
border: 1px solid #eee;
padding: 10px;
flex: 1 0 auto;
}
<div class="container">
<div class="row-flex">
<div class="flexbox">
<div class="icon-box-1">
<h1>
One
</h1>
<h3>Title</h3>
<p>lots of random text, lots of random text, lots of random text, lots of random text</p>
</div>
</div>
<div class="flexbox">
<div class="icon-box-1">
<h1>
Two
</h1>
<h3>Title</h3>
<p>lots of random text</p>
</div>
</div>
<div class="flexbox">
<div class="icon-box-1">
<h1>
Three
</h1>
<h3>Title</h3>
<p>lots of random text, lots of random text, lots of random text, lots of random text</p>
</div>
</div>
<div class="flexbox">
<div class="icon-box-1">
<h1>
Four
</h1>
<h3>Title</h3>
<p>lots of random text, lots of random text, lots of random text</p>
</div>
</div>
<div class="flexbox">
<div class="icon-box-1">
<h1>
Five
</h1>
<h3>Title</h3>
<p>lots of random text, lots of random text, lots of random text</p>
</div>
</div>
<div class="flexbox">
<div class="icon-box-1">
<h1>
Six
</h1>
<h3>Title</h3>
<p>lots of random text, lots of random text, lots of random text</p>
</div>
</div>
</div>
</div>

Related

How do I put multiple images in columns with centered text under them?

I'd like to put images with centered text underneath each image in columns, I'd also like to size the images to a specific width and height each and I also want to make it so that when the text gets too long the text gets split into 2 lines, but I dont want it to move the image up and down at the same time. What code should I use? I used some code I found on the internet which is linked below but that didn't work as I expected it to (the code can be found below). Thanks!
So far, I've used this code but it doesn't center the text and also skips spots which I don't want to happen. Please check the image I've attached to see the skipped spotsskipped spot
HTML
<div class="column">
<img src="extra/road96.jpg" alt="Road 96"style="width:180px;height:180px;"/\>
<a class='neon-button' href='https://www.mediafire.com/file/4a05b4tkaal5e50/Road_96.zip/file'\>Road 96
<a/>
<div/>
CSS
.column {
float: left;
width: 13.33%;
padding: 5px;
}
.row::after {
content: "";
clear: both;
}
.sjamg {
text-align: justify;
width: [width of img];
}
.sjamg img {
display: block;
margin: 0 auto;
}
try using flex, and by using flex-direction change the direction of the container's items to Column
.main-container {
display: flex;
width: 100%;
height: 100vh;
flex-direction: Column;
justify-content: space-evenly;
}
.main-container p {
margin-left: 64px;
height: 5%;
width: auto;
}
.small-container {
height: 180px;
width: 180px;
background-color: blue;
}
<!DOCTYPE html>
<html>
<body>
<div class="main-container">
<div class="small-container"></div>
<p> your text </p>
<div class="small-container"></div>
<p> your text </p>
<div class="small-container"></div>
<p> your text </p>
<div class="small-container"></div>
<p> your text </p>
</div>
</body>
</html>
Try this:
.main-container {
display: flex;
width: 100%;
justify-content: space-evenly;
}
.mycolumn {
display: flex;
flex-direction: column;
width: 100%;
justify-content: space-evenly;
}
.main-container p {
margin: auto;
height: 5%;
width: auto;
}
.small-container {
height: 180px;
width: 50%;
background-color: red;
margin: auto;
}
<!DOCTYPE html>
<html>
<body>
<div class="main-container">
<div class="mycolumn">
<div class="small-container"></div>
<p> your text </p>
<div class="small-container"></div>
<p> your text </p>
<div class="small-container"></div>
<p> your text </p>
<div class="small-container"></div>
<p> your text </p>
</div>
<div class="mycolumn">
<div class="small-container"></div>
<p> your text </p>
<div class="small-container"></div>
<p> your text </p>
<div class="small-container"></div>
<p> your text </p>
<div class="small-container"></div>
<p> your text </p>
</div>
<div class="mycolumn">
<div class="small-container"></div>
<p> your text </p>
<div class="small-container"></div>
<p> your text </p>
<div class="small-container"></div>
<p> your text </p>
<div class="small-container"></div>
<p> your text </p>
</div>
<div class="mycolumn">
<div class="small-container"></div>
<p> your text </p>
<div class="small-container"></div>
<p> your text </p>
<div class="small-container"></div>
<p> your text </p>
<div class="small-container"></div>
<p> your text </p>
</div>
</div>
</body>
</html>

HTML/SCSS Align images flush above a text

I use splidejs to create a slider for image and text content. The size of the sliderList (ul) is based on the largest list item (sliderItem --> li).
Each SliderItem consists of a wrapper (item-wrapper), which contains an image and a text. Both the image and the text can be of different length/highness.
Now the SliderItems should be aligned so that each image element is above the text, but the texts are aligned at the bottom of the container (with a dynamic height) and each text starts at the same height. That is, the texts are all placed at the same height at the end of the container and the image should be placed directly above them with a defined margin. Is this somehow possible using SCSS? In case of need I can also use JS to reposition something if needed.
Attached is a mockup of how it should look:
Some code snippet:
HTML
<div class="splide">
<div class="splide__track">
<ul class="splide__list"> //Slider List
<li class="splide__slide"> //Slider Item
<div class="item-wrapper">
<div class="image">
<img/>
</div>
<div class="text">
<h2>Some text</h2>
Some other text
</div>
</div>
</li>
CSS
.splide {
width:100%;
height: 100%;
}
.splide__list {
display: flex;
.splide__slide{
.item-wrapper{
display: flex;
flex-direction: column;
justify-content: space-between;
height: 100%;
width: 100%;
.image {
img {
width: 100%
height: auto
}
}
.text {
}
}
}
}
If you wanted to solve this placement with CSS then it has grid written all over it. Here's an example of what that solution would look like retaining your HTML structure.
ul {
display: grid;
grid-template-rows: 1fr 1fr;
grid-auto-flow: column;
grid-auto-columns: 1fr;
list-style: none;
margin: 0;
padding: 0;
}
.splide__slide,
.item-wrapper {
display: contents;
}
.image {
display: flex;
align-items: flex-end;
}
https://jsfiddle.net/yd0or3je/
Notice that the li and .item-wrapper had to be eliminated from the layout using display: contents and unless that slider js thingy is only manipulating the ul scroll position or something, it will probably no longer work after these changes.
Other than that you could use javascript to find the highest .image after the page loads and then apply the same height to all the .image elements.
Or the third option would be to just not use the slider js thingy and write some custom js for the slider while retaining the grid css for the layout.
Hope this helps you.
Your code snippet seems to have lost some material somewhere. However, if I have worked it out correctly, then the code example below I think satisfies the following requirements:
maintains your HTML structure (so it should still work with your
slider?)
aligns the boundaries between images and text
does not require javascript
The approach in the code below is to create a reference line for each image and text pairing which can also be referenced to an outer container. This is done by decoupling the layout flow for the image and the text from its parent using 'position'. Decoupling both elements from their shared parent results in the parent collapsing to an element with 0 height, ie, a "line", because it no longer has any layout content. This "line" can then be referenced back a common ancestor, for all image text pairs, again using 'position'.
.splide {
width:100%;
height: 100%;
}
.splide__list {
list-style-type: none;
display: flex;
flex-direction: row;
/* Establish common reference context */
position: absolute;
top: 50%;
}
.splide__slide {
}
.item-wrapper {
margin-left: 5px;
margin-right: 5px;
width: 20vw;
/* Establish image text pairing parent position reference */
position: relative;
}
.image {
border: 2px solid black; /* If the black border is not required, then remove this property */
padding: 5px;
/* Align the bottom of the image, and center the image */
position: absolute;
bottom: 5px;
left: 5px;
right: 5px;
}
img {
width: 100%;
}
.text {
border: 2px solid black; /* If the black border is not required, then remove this property */
padding: 5px;
/* Align the top of the text, and center the text */
position: absolute;
top: 5px;
left: 5px;
right: 5px;
}
.upperGreenBorder { /* If the lime border is not required, then remove this class */
border-left: 2px solid lime;
border-top: 2px solid lime;
border-right: 2px solid lime;
position: absolute;
top: -7px;
bottom: -7px;
left: -7px;
right: -7px;
}
.lowerGreenBorder { /* If the lime border is not required, then remove this class */
border-left: 2px solid lime;
border-bottom: 2px solid lime;
border-right: 2px solid lime;
position: absolute;
top: -7px;
bottom: -7px;
left: -7px;
right: -7px;
}
<div class="splide">
<div class="splide__track">
<ul class="splide__list">
<li class="splide__slide">
<div class="item-wrapper">
<div class="image">
<div class="upperGreenBorder"></div><!-- If the lime border is not required, then remove this div -->
<img height="400px" src="https://dummyimage.com/1400x600/ff4400/fff.png&text=1">
</div>
<div class="text">
<div class="lowerGreenBorder"></div><!-- If the lime border is not required, then remove this div -->
<h2>Some header text 1</h2>
<p>Some other text for text number one Some other text for text number one Some other text for text number one</p>
<p>Some other text for text number one</p>
<p>Some other text for text number one</p>
<p>Some other text for text number one</p>
<p>Some other text for text number one</p>
<p>Some other text for text number one</p>
<p>Some other text for text number one</p>
<p>Some other text for text number one</p>
<p>Some other text for text number one</p>
</div>
</div>
</li>
<li class="splide__slide">
<div class="item-wrapper">
<div class="image">
<div class="upperGreenBorder"></div><!-- If the lime border is not required, then remove this div -->
<img height="500px" src="https://dummyimage.com/1400x600/ff4400/fff.png&text=2">
</div>
<div class="text">
<div class="lowerGreenBorder"></div><!-- If the lime border is not required, then remove this div -->
<h2>Some header text 2</h2>
<p>Some other text for text number two Some other text for text number two Some other text for text number two</p>
<p>Some other text for text number two</p>
</div>
</div>
</li>
<li class="splide__slide">
<div class="item-wrapper">
<div class="image">
<div class="upperGreenBorder"></div><!-- If the lime border is not required, then remove this div -->
<img height="200px" src="https://dummyimage.com/1400x600/ff4400/fff.png&text=3">
</div>
<div class="text">
<div class="lowerGreenBorder"></div><!-- If the lime border is not required, then remove this div -->
<h2>Some header text 3</h2>
<p>Some other text for text number three</p>
<p>Some other text for text number three</p>
<p>Some other text for text number three</p>
<p>Some other text for text number three</p>
<p>Some other text for text number three</p>
<p>Some other text for text number three</p>
<p>Some other text for text number three</p>
<p>Some other text for text number three</p>
<p>Some other text for text number three</p>
</div>
</div>
</li>
<li class="splide__slide">
<div class="item-wrapper">
<div class="image">
<div class="upperGreenBorder"></div><!-- If the lime border is not required, then remove this div -->
<img height="300px" src="https://dummyimage.com/1400x600/ff4400/fff.png&text=4">
</div>
<div class="text">
<div class="lowerGreenBorder"></div><!-- If the lime border is not required, then remove this div -->
<h2>Some header text 4</h2>
<p>Some other text for text number four</p>
<p>Some other text for text number four</p>
<p>Some other text for text number four</p>
<p>Some other text for text number four</p>
</div>
</div>
</li>
<li class="splide__slide">
<div class="item-wrapper">
<div class="image">
<div class="upperGreenBorder"></div><!-- If the lime border is not required, then remove this div -->
<img height="400px" src="https://dummyimage.com/1400x600/ff4400/fff.png&text=5">
</div>
<div class="text">
<div class="lowerGreenBorder"></div><!-- If the lime border is not required, then remove this div -->
<h2>Some header text 5</h2>
<p>Some other text for text number five</p>
<p>Some other text for text number five</p>
<p>Some other text for text number five</p>
<p>Some other text for text number five</p>
<p>Some other text for text number five</p>
<p>Some other text for text number five</p>
<p>Some other text for text number five</p>
<p>Some other text for text number five</p>
<p>Some other text for text number five</p>
<p>Some other text for text number five</p>
<p>Some other text for text number five</p>
<p>Some other text for text number five</p>
<p>Some other text for text number five</p>
</div>
</div>
</li>
<li class="splide__slide">
<div class="item-wrapper">
<div class="image">
<div class="upperGreenBorder"></div><!-- If the lime border is not required, then remove this div -->
<img height="50px" src="https://dummyimage.com/1400x600/ff4400/fff.png&text=6">
</div>
<div class="text">
<div class="lowerGreenBorder"></div><!-- If the lime border is not required, then remove this div -->
<h2>Some header text 6</h2>
<p>Some other text for text number six</p>
</div>
</div>
</li>
</ul>
</div>
You should set the height of all your splide elements to 100%. Inside your splide__slide, set the .image CSS class into height: 60% and .text class height: 40%, or whichever proportion you prefer. Then, turn the .image CSS class into a flex container and set the img element to be align-self: end. I tried matching your HTML and CSS. Here's a working version with imports for SplideJS:
https://jsfiddle.net/opLsgf9v/
Thanks for all your answers. I made it work by some hacky js:
First i need to wait for my document to be fully loaded calling
document.addEventListener('readystatechange', () => {
if (document.readyState === 'complete') {
this.calculateImages();
}
});
then i process every image and calculcate the tallest image (get the height of the tallest element in pixels). After this, i move every image by its height difference (difference actuall image to max height image) by applying the height difference with a margin-top. Thats it for me. I guess a bit hacky but it works.

Taking up maximum space inside a box before wrapping?

So I need to display a box (position absolute) above my page when clicking on some button designed, inside this box will be a list of "tags" which should be displayed in a row.
But my problem is that I cannot manage to make the tags wrap properly, taking the maximum space of the box. I want to display as many tags as possible in a single row.
Any idea if this is possible ?
https://jsfiddle.net/e18d2ajh/
.vectors {
display: inline-flex;
min-width: 20vw;
max-width: 50vw;
background-color: #333;
padding: 15px;
margin-bottom: 15px;
}
.vector {
display: flex;
padding: .35rem;
background-color: #c0c0c0;
margin-right: .5rem;
}
<h5>
with few boxes
</h5>
<div class="vectors">
<div class="vector">
Random text
</div>
<div class="vector">
Random text
</div>
<div class="vector">
Random text
</div>
<div class="vector">
Random text
</div>
</div>
<h5>
with many boxes
</h5>
<div class="vectors">
<div class="vector">
Random text
</div>
<div class="vector">
Random text
</div>
<div class="vector">
Random text
</div>
<div class="vector">
Random text
</div>
<div class="vector">
Random text
</div>
<div class="vector">
Random text
</div>
<div class="vector">
Random text
</div>
<div class="vector">
Random text
</div>
</div>
Use flex-wrap property to wrap contents to next line
.vectors {
...
flex-wrap: wrap;
...
}
.vectors {
display: inline-flex;
flex-wrap: wrap;
min-width: 20vw;
max-width: 50vw;
background-color: #333;
padding: 15px;
margin-bottom: 15px;
}
.vector {
display: flex;
padding: .35rem;
background-color: #c0c0c0;
margin-right: .5rem;
}
<h5>
with few boxes
</h5>
<div class="vectors">
<div class="vector">
Random text
</div>
<div class="vector">
Random text
</div>
<div class="vector">
Random text
</div>
<div class="vector">
Random text
</div>
</div>
<h5>
with many boxes
</h5>
<div class="vectors">
<div class="vector">
Random text
</div>
<div class="vector">
Random text
</div>
<div class="vector">
Random text
</div>
<div class="vector">
Random text
</div>
<div class="vector">
Random text
</div>
<div class="vector">
Random text
</div>
<div class="vector">
Random text
</div>
<div class="vector">
Random text
</div>
</div>
You need a flex-wrap: wrap for .vectors and a flex-grow: 1 for .vector so the children occupy empty space left in the row after wrapping. Note, that might look ugly for the last row, solution is using pseudo element. Summary:
.vectors {
flex-wrap: wrap;
}
.vectors::after {
content: '';
flex: 100 0 0;
}
.vector{
flex-grow: 1;
}
Here's the codepen
You could set max-width:max-content on .vectores with flex-wrap:wrap and it would do the trick, like so:
.vectors {
display: inline-flex;
min-width: 20vw;
max-width: max-content;
background-color: #333;
padding: 15px;
margin-bottom: 15px;
/* lines I added */
flex-wrap:wrap;
gap:.5rem;
}
.vector {
display: flex;
padding: .35rem;
background-color: #c0c0c0;
}
<h5>
with few boxes
</h5>
<div class="vectors">
<div class="vector">
Random text
</div>
<div class="vector">
Random text
</div>
<div class="vector">
Random text
</div>
<div class="vector">
Random text
</div>
</div>
<h5>
with many boxes
</h5>
<div class="vectors">
<div class="vector">
Random text
</div>
<div class="vector">
Random text
</div>
<div class="vector">
Random text
</div>
<div class="vector">
Random text
</div>
<div class="vector">
Random text
</div>
<div class="vector">
Random text
</div>
<div class="vector">
Random text
</div>
<div class="vector">
Random text
</div>
</div>

flexbox - last box heigher than others

I have a problem with flexbox. The last box in a row has more height than others. I see that if I give specific height to the boxes I will achieve the same height on the boxes but since I am trying to make responsive site I wondering it is better way to define height and not using px sizing. The boxes including images and text inside. I have tried to put % on the height but it doesn't change anything. What is the best way to use in this case to avoid many jobs in media query later? is the px the only solution?
Thank you in advance
the boxes look like this:
Code:
.footer-box {
display: flex;
justify-content: center;
width: 100%;
flex-wrap:wrap; // using wrap for wraping on smaller devices
}
.box {
text-align: center;
width:20%;
height: auto;
margin: 10px;
}
<div class="footer-box">
<div class="box box1">
<img src="./images/other/pic1.jpg" alt="">
<p>lorem text</p>
</div>
<div class="box box2">
<img src="./images/other/pic1.jpg" alt="">
<p>lorem text</p>
</div>
<div class="box box3">
<img src="./images/other/pic1.jpg" alt="">
<p>lorem text</p>
</div>
<div class="box box4">
<img src="./images/other/pic1.jpg" alt="">
<p>lorem text</p>
</div>
Thank you in advance
You can use flexbox and flex-direction:column for .box.
Also you should use align-items: stretch for .footer-box. Because all child items will have same heights with this code.
Lastly, through flex: 1 1 auto; we can fill with img.
And bonus: object-fit: cover is for your img sizes.
.footer-box {
display: flex;
justify-content: center;
width: 100%;
flex-wrap: wrap; // using wrap for wraping on smaller devices
align-items: stretch;
}
.box {
text-align: center;
width: 20%;
height: auto;
margin: 10px;
display: flex;
flex-direction: column;
}
.box img {
flex: 1 1 auto;
object-fit: cover;
}
<div class="footer-box">
<div class="box box1">
<img src="https://dummyimage.com/50x50/000/fff" alt="">
<p>lorem text</p>
</div>
<div class="box box2">
<img src="https://dummyimage.com/50x50/000/fff" alt="">
<p>lorem text</p>
</div>
<div class="box box3">
<img src="https://dummyimage.com/50x50/000/fff" alt="">
<p>lorem text</p>
</div>
<div class="box box4">
<img src="https://dummyimage.com/50x70/000/fff" alt="">
<p>lorem text</p>
</div>
</div>

Styling the last column of a flexbox

I have to implement a design looking like this:
This will be the index.php page for WordPress and therefore it will be using the WordPress loop to output the blog articles as individual "resources".
Normally I would implement this as a flexbox, because the number of items is variable and I need it to be responsive, however this time our designer has added borders in between the items.
This would be fine but the borders are not included before or after the end of the rows. I cant solve this any of the pseudo selectors that I know of.
Currently my HTML and CSS look something like this:
section {
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
}
section div {
display: flex;
flex-direction: column;
border-right: 1px solid red;
padding-right: 20px;
margin-right: 20px;
margin-bottom: 10px;
}
<section>
<div>
<img class="http://lorempixel.com/output/fashion-q-c-200-200-6.jpg">
<p>
This is some text
</p>
</div>
<div>
<img class="http://lorempixel.com/output/fashion-q-c-200-200-6.jpg">
<p>
This is some text
</p>
</div>
<div>
<img class="http://lorempixel.com/output/fashion-q-c-200-200-6.jpg">
<p>
This is some text
</p>
</div>
<div>
<img class="http://lorempixel.com/output/fashion-q-c-200-200-6.jpg">
<p>
This is some text
</p>
</div>
<div>
<img class="http://lorempixel.com/output/fashion-q-c-200-200-6.jpg">
<p>
This is some text
</p>
</div>
<div>
<img class="http://lorempixel.com/output/fashion-q-c-200-200-6.jpg">
<p>
This is some text
</p>
</div>
<div>
<img class="http://lorempixel.com/output/fashion-q-c-200-200-6.jpg">
<p>
This is some text
</p>
</div>
<div>
<img class="http://lorempixel.com/output/fashion-q-c-200-200-6.jpg">
<p>
This is some text
</p>
</div>
<div>
<img class="http://lorempixel.com/output/fashion-q-c-200-200-6.jpg">
<p>
This is some text
</p>
</div>
<div>
<img class="http://lorempixel.com/output/fashion-q-c-200-200-6.jpg">
<p>
This is some text
</p>
</div>
</section>
Is this something I can solve with CSS grid and is there a way to achieve this using flexbox or another layout that isn't grid?
This really depends on the background under the items, but if it is made of one color, you could use the solution of simply overlapping the left border with the pseudo element, like this:
section {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
position: relative;
margin-left: -20px;
}
section::before {
content: "";
position: absolute;
top: 0;
bottom: 0;
left: 20px;
width: 1px;
background: #fff;
}
section div {
display: flex;
flex-grow: 1;
flex-direction: column;
border-left: 1px solid red;
padding-left: 20px;
margin-left: 20px;
text-align: center;
}
<section>
<div>
<img class="http://lorempixel.com/output/fashion-q-c-200-200-6.jpg">
<p>
This is some text
</p>
</div>
<div>
<img class="http://lorempixel.com/output/fashion-q-c-200-200-6.jpg">
<p>
This is some text
</p>
</div>
<div>
<img class="http://lorempixel.com/output/fashion-q-c-200-200-6.jpg">
<p>
This is some text
</p>
</div>
<div>
<img class="http://lorempixel.com/output/fashion-q-c-200-200-6.jpg">
<p>
This is some text
</p>
</div>
<div>
<img class="http://lorempixel.com/output/fashion-q-c-200-200-6.jpg">
<p>
This is some text
</p>
</div>
</section>
I kind of have what you need, I'm displaying the right border with pseudo element and pushing it off screen if its the last element of a row, and some empty divs to push a new row to keep the layout.
section {
display: flex;
align-items: center;
flex-wrap: wrap;
overflow: hidden;
}
section div {
display: flex;
flex-grow: 1;
flex-direction: column;
padding: 0 20px;
position: relative;
}
section div:nth-last-child(9) ~ div{
height: 0;
width: 140px;
}
section div::after {
content: '';
position: absolute;
border-right: 1px solid red;
left: 100%;
display: block;
height: 100%;
}
section div:nth-last-child(9)::after {
border: none;
}
section div p { width: 140px; }
<section>
<div>
<img class="http://lorempixel.com/output/fashion-q-c-200-200-6.jpg">
<p>
This is some text
</p>
</div>
<div>
<img class="http://lorempixel.com/output/fashion-q-c-200-200-6.jpg">
<p>
This is some text
</p>
</div>
<div>
<img class="http://lorempixel.com/output/fashion-q-c-200-200-6.jpg">
<p>
This is some text
</p>
</div>
<div>
<img class="http://lorempixel.com/output/fashion-q-c-200-200-6.jpg">
<p>
This is some text
</p>
</div>
<div>
<img class="http://lorempixel.com/output/fashion-q-c-200-200-6.jpg">
<p>
This is some text
</p>
</div>
<div>
<img class="http://lorempixel.com/output/fashion-q-c-200-200-6.jpg">
<p>
This is some text
</p>
</div>
<div>
<img class="http://lorempixel.com/output/fashion-q-c-200-200-6.jpg">
<p>
This is some text
</p>
</div>
<div>
<img class="http://lorempixel.com/output/fashion-q-c-200-200-6.jpg">
<p>
This is some text
</p>
</div>
<div>
<img class="http://lorempixel.com/output/fashion-q-c-200-200-6.jpg">
<p>
This is some text
</p>
</div>
<div>
<img class="http://lorempixel.com/output/fashion-q-c-200-200-6.jpg">
<p>
This is some text
</p>
</div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</section>