Like the flexbox example, I still need to set an absolute value for the width of the label to align the
elements as they stack.
Another approach with grid
CSS Grid also allows elements to respond based on their content using flexible grid tracks. In addition to other length values like percentages, relative units, or pixels, CSS Grid accepts a Fractional Unit (fr
) , where 1fr
will take up one part of the available space, 2fr
will take up two parts of the available space, and so on. Let’s set up two equal columns here:
.wrapper--accessibility-tools {
display: grid;
grid-template-columns: 1fr 1fr;
grid-gap: 10px;
}
CodePen Embed Fallback
There’s also a minmax()
function which creates grid tracks that flex to the available space, but also don’t shrink narrower than a specified size.
.wrapper--accessibility-tools {
display: grid;
grid-template-columns: minmax(auto, max-content) minmax(auto, max-content);
grid-gap: 10px;
}
CodePen Embed Fallback
Both of these demos work, and are free from any absolute values or device specific CSS. The results are far from ideal though, each grid now responds at different points. Maybe not a huge problem, but certainly not great.
This happens because when adding display: grid
to a container, only the direct children of that container become grid items. This means the intrinsic sizing units we used only relate to elements in the same grid.
Using subgrid
To really achieve my goal, I need the buttons and labels to react to elements in sibling grid containers. CSS Grid Level 2 includes the subgrid feature. Although we have always been able to nest grids, the elements within each grid container have been independent. With subgrid, we get to set up nested (child) grids that use parent grids tracks.
This makes a number patterns that were previously difficult much easier, in particular the “card” pattern which seems to be the most popular example to show the benefits of subgrid. Without subgrid, each card is defined as an independent grid, meaning track sizing in the first card cannot respond to a change of height in the second. Pulling from an example Rachel Andrew used, here’s a simple group of cards:
Credit: Rachel Andrew
Subgrid allows the cards to use the rows defined in the parent grid, meaning they can react to content in surrounding cards.
Credit: Rachel Andrew
Each card in this example still spans three row tracks, but those rows are now defined on the parent grid, allowing each card to occupy the same amount of vertical space.
For the example we’ve been working with, we do not need to use rows. Instead, we need to size columns based on content from sibling grids. First, let’s set the parent grid to contain the two
elements. This is similar to the code we previously look at in the auto-fit
demo.
.wrapper--accessibility-tools {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
grid-gap: 10px;
}
Then we position each subgrid onto the parent grid.
.sub-grid {
display: grid;
grid-column: span 3;
grid-template-columns: subgrid;
align-items: center;
}
All of the labels and buttons are now aligned to the tracks of their parent grid, keeping them consistent. They will each have an equal width based on the space that is available. If there is not enough space for each nested grid on one line, the second will wrap onto a new line.
This time, the two nested grid items align perfectly. The grid is also flexible if we introduce a longer title on a one of the buttons, the other elements will respond accordingly.
CodePen Embed Fallback
Browser compatibility
Support for subgrid is not great at the time of writing. It is only supported in Firefox 71+, although there are positive signals from other browsers. CSS feature queries can be used to provide alternative styling to Chrome and Edge.
This browser support data is from Caniuse , which has more detail. A number indicates that browser supports the feature at that version and up.
Desktop
Chrome
Firefox
IE
Edge
Safari
No
71
No
No
No
Mobile / Tablet
Android Chrome
Android Firefox
Android
iOS Safari
No
79
No
No
Note that I am using an extra wrapper around the fieldsets in these demos. This is to combat a bug with form elements and grid and flexbox .
<fieldset class="accessibility-tools__colour-theme">
<div class="wrapper"></div>
</fieldset>
The layout CSS is applied to the wrapper with the fieldset being set to display: contents
.
.accessibility-tools fieldset {
display: contents;
border: 0;
}
Other writing on the subject
The post Achieving Vertical Alignment (Thanks, Subgrid!) appeared first on CSS-Tricks .
You can support CSS-Tricks by being an MVP Supporter .