Split

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:

Adventures of a small chair, part I.
Adventures of a small chair, part II.
Adventures of a small chair, part III.

In that case your CSS does not change and your html will be expanded like follows:

<figure class="split">
  <figure>
    <img src="/img/code/DSCF1384.webp">
	  <figcaption>
			Adventures of a small chair, part I.
	  </figcaption>
  </figure>
  <figure>
    <img src="/img/code/DSCF1390.webp">
	  <figcaption>
			Adventures of a small chair, part II.
	  </figcaption>
  </figure>
  <figure>
    <img src="/img/code/DSCF1402.webp">
	  <figcaption>
			Adventures of a small chair, part III.
	  </figcaption>
  </figure>
</figure>

Vertical positioning

You can push the content of each split column to the bottom, like:

Adventures of a small chair, part I.
Adventures of a small chair, part II.
Adventures of a small chair, part III.

For the bottom-push appearance you will again use the same HTML and assign the CSS classes split end . Like so:

<figure class="split end">
  <figure>
    <img src="/img/code/DSCF1384.webp">
	  <figcaption>
			Adventures of a small chair, part I.
	  </figcaption>
  </figure>
  <figure>
    <img src="/img/code/DSCF1390.webp">
	  <figcaption>
			Adventures of a small chair, part II.
	  </figcaption>
  </figure>
  <figure>
    <img src="/img/code/DSCF1402.webp">
	  <figcaption>
			Adventures of a small chair, part III.
	  </figcaption>
  </figure>
</figure>

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 */
}

Reverting order

When pushing figure tags with figcaption to the bottom, the alignment of the images inside the figure can differ because the captions might differ in size. There are two options to avoid that: 1) adjust your HTML to have the figcaption above the image, 2) revert the order of display using CSS. I use the second option, which looks like:

Adventures of a small chair, part I.
Adventures of a small chair, part II.
Adventures of a small chair, part III.

It can be achieved by assigning the CSS classes split end reverse:

<figure class="split end reverse">
  <figure>
    <img src="/img/code/DSCF1384.webp">
	  <figcaption>
			Adventures of a small chair, part I.
	  </figcaption>
  </figure>
  <figure>
    <img src="/img/code/DSCF1390.webp">
	  <figcaption>
			Adventures of a small chair, part II.
	  </figcaption>
  </figure>
  <figure>
    <img src="/img/code/DSCF1402.webp">
	  <figcaption>
			Adventures of a small chair, part III.
	  </figcaption>
  </figure>
</figure>

The reverse class is defined as:

.split.end.reverse > * {
  display: flex; /* display each direct child of the split container with flexbox layout */
  flex-direction: column-reverse; /* the main-axis of the flexbox will go bottom to top */
  justify-content: start; /* the items on the main-axis will be pushed to the bottom, because the flex direction is reversed, whe have to justify the content to the start to get it pushed to the bottom */
}

The complete CSS

Here is 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 */
}
.split.end.reverse > * {
  display: flex; /* display each direct child of the split container with flexbox layout */
  flex-direction: column-reverse; /* the main-axis of the flexbox will go bottom to top */
  justify-content: start; /* the items on the main-axis will be pushed to the bottom, because the flex direction is reversed, whe have justify the content to the start */
}

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;
}
.split.end.reverse > * {
  @apply flex flex-col-reverse justify-start;
}