Aligning a flexible number of items horizontally in one row.
Horizontal positioning
I often use what I call a split, with which I mean aligning a flexible number of items horizontally in a single row, each item maintaining an equal width without overflowing the container that holds the items.
A basic split with images looks like:
Start with the most basic HTML:
<figure class="split">
<img src="/img/code/DSCF1384.webp">
<img src="/img/code/DSCF1390.webp">
<img src="/img/code/DSCF1402.webp">
</figure>
and apply the horizontal positioning by assigning the following CSS class named split
:
.split {
display: grid; /* use grid layout */
grid-auto-columns: minmax(0, 1fr); /* use a variable amount of columns and make each column the same size */
grid-auto-flow: column; /* add new columns as necessary */
gap: 3rem; /* have a gap between each column */
}
.split img {
object-fit: scale-down; /* if images are too wide, they have to be scaled down to fit into the row */
}
.split > * {
margin: 0; /* what is placed inside a column should not have a margin */
}
Probably you would not only show the images within the figure
tag, but also have a figcaption
for each image, like below:
In that case your CSS does not change and your html will be expanded like follows:
<figure class="split">
<figure>
<img src="/img/code/a.webp">
<figcaption>Caption A</figcaption>
</figure>
<figure>
<img src="/img/code/b.webp">
<figcaption>Caption B</figcaption>
</figure>
<figure>
<img src="/img/code/c.webp">
<figcaption>Caption C</figcaption>
</figure>
</figure>
Vertical positioning
You can push the content of each split column to the bottom, like:
For the bottom-push appearance you will again use the same HTML and assign the CSS classes split end
. The end
class will introduce a flexbox layout for each column inside of the split grid:
.split.end > * {
display: flex; /* display each direct child of the split container with flexbox layout */
flex-direction: column; /* the main-axis of the flexbox will go top to bottom */
justify-content: end; /* the items on the main-axis will be pushed to the bottom */
}
Vertically centering each column can be achieved with:
.split.center > * {
display: flex;
flex-direction: column;
justify-content: center; /* center the items on the main-axis */
}
Explicitly aligning to the top (which is default) will require:
.split.start > * {
display: flex;
flex-direction: column;
justify-content: start; /* push items on the main-axis to the top */
}
The complete CSS
Here the complete CSS in one go.
.split {
display: grid; /* use grid layout */
grid-auto-columns: minmax(0, 1fr); /* use a variable amount of columns and make each column the same size */
grid-auto-flow: column; /* add new columns as necessary */
gap: 3rem; /* have a gap between each column */
}
.split img {
object-fit: scale-down; /* if images are too wide, they have to be scaled down to fit into the row */
}
.split > * {
margin: 0; /* what is placed inside a column should not have a margin */
}
.split.start > * {
display: flex;
flex-direction: column;
justify-content: start; /* push items on the main-axis to the top */
}
.split.center > * {
display: flex;
flex-direction: column;
justify-content: center; /* center the items on the main-axis */
}
.split.end > * {
display: flex; /* display each direct child of the split container with flexbox layout */
flex-direction: column; /* the main-axis of the flexbox will go top to bottom */
justify-content: end; /* the items on the main-axis will be pushed to the bottom */
}
Tailwind CSS
Less code is required to achieve the same with Tailwind CSS:
/* Tailwind CSS */
.split {
@apply grid auto-cols-fr grid-flow-col gap-12;
}
.split img {
@apply object-scale-down;
}
.split > * {
@apply m-0;
}
.split.start > * {
@apply flex flex-col justify-start;
}
.split.center > * {
@apply flex flex-col justify-center;
}
.split.end > * {
@apply flex flex-col justify-end;
}