Padding-based float grid with gutters via padding
This float-based grid uses inline-padding to create gutters between columns. Each column is floated tot the left and positioned immediately after the previous column. In some cases, the last column wraps to the next line due to rounding errors.
Because the background color also extends into the padding-area, background-clip:content-box is required to limit the background color rendering
the content-box area. To add inner spacing without making content touch the edges of the column, each
column uses a nested child element that applies its own padding.
Each column has padding equal to half the gutter width to create the gutters. The parent row compensates for this by using negative inline-margins, that are equal to half the gutter width.
.row {
--number-of-columns: 12;
--gutter-size: 1rem;
--size-of-column: calc(100% / var(--number-of-columns));
display: flow-root;
margin-inline: calc(var(--gutter-size) / -2);
}
.column {
inline-size: var(--size-of-column);
padding-inline: calc(var(--gutter-size) / 2);
float: inline-start;
background-clip: content-box;
}
Margin-based float grid with gutters (single direction margins)
This float-based grid uses inline-margins to create gutters between columns. Each column is floated to the left and positioned immediately after the previous column. In some cases, the last column wraps to the next line due to rounding errors.
Each column except the first one, has an inline-start margin equal to the gutter width. This creates consistent spacing between columns but also keeps the first column flush with the container edge.
.row {
--number-of-columns: 12;
--gutter-size: 1rem;
--gutter-size-total: calc((var(--number-of-columns) - 1) * var(--gutter-size));
--size-of-column: calc((100% - var(--gutter-size-total)) / var(--number-of-columns));
display: flow-root;
}
.column {
inline-size: var(--size-of-column);
margin-inline-start: var(--gutter-size);
float: inline-start;
&:first-child {
margin-inline-start: 0;
}
}
Isolated floats
This float-based grid uses inline-margins to position components relative to the container. Each column is positioned independently from other columns to avoid rounding errors that could cause wrapping.
Each column is floated to the left, taking it out of normal flow. A margin-inline-end value of -100% pulls each column back to the left edge of the container and
overrides the default float behaviour where each float follows the previous one. The actual
positon of a column is then set via margin-inline-start.
.row {
--number-of-columns: 12;
--gutter-size: 1rem;
--gutter-size-total: calc((var(--number-of-columns) - 1) * var(--gutter-size));
--size-of-column: calc((100% - var(--gutter-size-total)) / var(--number-of-columns));
display: flow-root;
}
.column {
inline-size: var(--size-of-column);
margin-inline-start: calc((var(--size-of-column) + var(--gutter-size)) * (sibling-index() - 1));
margin-inline-end: -100%; /* move every column to the left edge of container */
float: inline-start;
}
Inline block grids
This inline-block-based grid uses inline margins to create gutters between
columns. There are multiple approaches to remove the whitespace between inline-block columns.
One approach is to set letter-spacing: -1em on the parent row and
reset it to normal in each column. Another is to set font-size: 0 on the parent row and reset it in each column. A third
option is to strip the whitespace from the markup using HTML comments. Finally, setting the
parent row to display: table causes some browsers to ignore whitespace entirely.
Each column except the first has an inline-start margin equal to the gutter width. This creates consistent spacing between columns while keeping the first column flush with the container edge.
.row {
--number-of-columns: 12;
--gutter-size: 1rem;
--gutter-size-total: calc((var(--number-of-columns) - 1) * var(--gutter-size));
--size-of-column: calc((100% - var(--gutter-size-total)) / var(--number-of-columns));
display: table;
table-layout: fixed;
inline-size: 100%;
letter-spacing: -1em;
}
.column {
display: inline-block;
inline-size: var(--size-of-column);
margin-inline-start: var(--gutter-size);
letter-spacing: normal;
&:first-child {
margin-inline-start: 0;
}
}
Justified inline block grid
This inline-block-based grid uses text-align: justify to
create gutters between columns. To remove the whitespace between inline-block columns, the
parent row is set to font-size: 0 and reset in each column.
text-align: justify distributes inline content evenly across the full
width of the row, creating equal gutters between columns. Since the last line of a justified
block is never justified, a spacer element is appended to the row so it wraps to the next
line, forcing the columns into a fully justified row. The block-size of the spacer must be compensated
for by applying a negative margin on the columns.
.row {
--number-of-columns: 12;
--gutter-size: 1rem;
--gutter-size-total: calc((var(--number-of-columns) - 1) * var(--gutter-size));
--size-of-column: calc((100% - var(--gutter-size-total)) / var(--number-of-columns));
text-align: justify;
line-height: 0;
}
.column {
display: inline-block;
inline-size: var(--size-of-column);
margin-block-end: -7px; /* compensate for spacer element */
line-height: normal;
text-align: start;
}
/* neccessary as "&::after" on row container doesn't work; it needs to be a real element */
.spacer {
display: inline-block;
inline-size: 100%;
block-size: 0;
}
Justified inline block grid with text-align-last
This inline-block-based grid uses text-align: justify and text-align-last: justify to create gutters between columns. The latter
avoids having to use a spacer element to make the former work as text-align: justify isn't applied to the last line of a justified block.
.row {
--number-of-columns: 12;
--gutter-size: 1rem;
--gutter-size-total: calc((var(--number-of-columns) - 1) * var(--gutter-size));
--size-of-column: calc((100% - var(--gutter-size-total)) / var(--number-of-columns));
text-align: justify;
text-align-last: justify;
}
.column {
display: inline-block;
inline-size: var(--size-of-column);
text-align: center;
text-align-last: center;
}
Border spacing grid
This table-based grid uses border-spacing to create gutters between columns
when border-collapse: separate is set. border-spacing also
creates gutters between the first and last cell and the edge of the table. The gutters at the
start and end must be compensated for via negative margins. Negative margin-inline on a table
element are ignored in some browsers, so an additional wrapper is needed to apply the negative inline
margins.
/* required as negative margin-inline-end is ignored on table elements */
.wrapper {
--gutter-size: 1rem;
margin-inline: calc(var(--gutter-size) * -1);
}
.row {
display: table;
border-collapse: separate;
table-layout: fixed;
inline-size: 100%;
border-spacing: var(--gutter-size) 0; /* order of values is reversed: horizontal vertical */
}
.column {
display: table-cell;
}