Back to top

Grid-like Definition list layout using Flexbox

Definition list laid out in a grid/table

Modern web design often features “vanity metrics”; KPIs indicating company's successes or listing distinguishable features. The most appropriate HTML element to mark up such content is the definition list <dl>.

Designs often call for a grid-like layout for such content. This article shows how to build the CSS for the scalable vertical grid-like definition list layout using Flexbox CSS.

Definition lists aren't interchangeable with tables

There is a rule to follow when deciding whether to use <dl> or <table> in your HTML. Here is a great answer with examples: Two-column table or dl?.

TL;DR Tables have meaningful headers while definition terms aren't the same property (height vs weight), are usually defined with different units, and grouping them under the same property name doesn't make sense.

Using the correct markup increases the usability and accessibility of your site so you should always choose the appropriate meaningful HTML element to markup your content, regardless of styling requirements.

This article shows how to arrange definition lists items in grids. It doesn't imply it's acceptable to convert tabular data into such a list if you style it to look like a table.

All terms must have the same number of descriptions

The grouping of descriptions with their terms in a definition list is implied through the order of HTML elements, there is nothing else to indicate which description belongs to which term.

All descriptions directly following the term in HTML “belong” to it. Terms and descriptions are siblings in HTML.

Laying out these items in a grid while keeping the correct grouping and order of descriptions after their terms can only work if the number of descriptions is the same for all terms. Otherwise, the grid/table would have “empty“ cells that need to be skipped which isn't easy to control.

Size Flexbox elements to grid them

Flexbox can be used to build responsive layouts without much code, leaving the calculations to the browser and context, for optimal calculation of the elements' sizes and arrangement of their positions.

Flexbox can also be used for layouts where more control is desired. Setting the display to flex on the container arranges the items horizontally next to each other in content-size columns in a single row. The gaps between columns are from the default margin-left on description elements:

The simplest Flexbox layout

Setting the direction to row and wrapping arranges them in more rows but still there is no grid:

  1. dl {
  2.  display: flex;
  3.  flex-flow: row wrap;
  4. }

Flexbox layout wrapping rows

Horizontal definition list grids don't need order

Since the definition list elements are already sorted correctly in HTML and Flexbox tiles them in rows the only thing we need to display them in a meaningful grid is uniform sizes.

We can do that with the width or the flex-basis properties and resetting the margin. With 5 columns in this example, we need each column to take up 20% of the total width. It's good practise to use the flex shorthand instead of only the flex-basis:

  1. dl {
  2.  display: flex;
  3.  flex-flow: row wrap;
  4. }
  6. dt, 
  7. dd {
  8.   flex: 0 0 20%;
  9.  margin: 0;
  10. }

Flexbox horizontal definition list

Vertical definition list grids with reorder-ed items

Display a definition list as a table/grid with #Flexbox #CSS @prkosTweet this

To group the descriptions with their terms vertically we need to control the order in which they are taken by the flexbox into a grid.

Since we're aiming for 3 columns in this example because there are 3 list terms, we need to change the items width to 33.33%, which won't make sense vertically:

  1. dl {
  2.  display: flex;
  3.  flex-flow: row wrap;
  4. }
  6. dt, 
  7. dd {
  8.   flex: 0 0 33.33%;
  9.   margin: 0;
  10. }

Flexbox jumbled up vertically

To put them in the right place vertically we rely on their HTML order and the fact that all terms have an equal number of descriptions describing them.

We can aim at elements that we want to display in one row with CSS :nth-of-type pseudo-class. Placing them into specific rows is done with the Flexbox order property.

Definition terms usually go on the top or in the bottom row, mimicking a table header. In this example, we'll put them at the bottom so we'll use the order value that is the number of rows we want to end up with in our grid.

  1. dt {
  2.  order: 5;
  3. }

Flexbox definition term at the bottom

Need more help? Schedule a free 15 minutes evaluation callContact me

We also want to control each respective definition description so each displays on their own rows, in the order in which they are written in HTML.

In this example there are 4 definition descriptions in each set so we need to address each in order, to put them in separate rows (every first dd out of the set of 4 goes into the 1st row, every second dd out of the set of 4 goes into the 2nd row):

  1. dd:nth-of-type(4n+1) {
  2.    order: 1;
  3. }
  5. dd:nth-of-type(4n+2) {
  6.     order: 2;
  7. }
  9. dd:nth-of-type(4n+3) {
  10.     order: 3;
  11. }
  13. dd:nth-of-type(4n+4) {
  14.     order: 4;
  15. }

This is what you end up with:

Definition list laid out in a grid/table

Flexbox definition list table/grid in Sass

This CodePen takes advantage of Sass to build the vertical order automatically for any number of definition terms and descriptions:

See the Pen Definition list as a vertical table/grid with Flexbox by Mihaela Jurković (@prkos) on CodePen.

What did you think of this article?