The above example is very simple, and we can get away without needing to write code that would be a problem to browsers that do not support grid, and legacy code is not an issue to our grid supporting browsers. However, things are not always so simple.
A more complex example
In this next example, I have a set of floated cards. I have given the cards a width
, in order to float
them. To create gaps between the cards, I use a margin
on the items, and then a negative margin on the container:
.wrapper ul {
overflow: hidden;
margin: 0 -10px;
padding: 0;
list-style: none;
}
.wrapper li {
float: left;
width: calc(33.333333% - 20px);
margin: 0 10px 20px 10px;
}
<div class="wrapper">
<ul>
<li class="card">
<h2>One</h2>
<p>We can use CSS Grid to overwrite older methods.</p>
</li>
<li class="card">
<h2>Two</h2>
<p>We can use CSS Grid to overwrite older methods.</p>
</li>
<li class="card">
<h2>Three</h2>
<p>We can use CSS Grid to overwrite older methods.</p>
</li>
<li class="card">
<h2>Four</h2>
<p>We can use CSS Grid to overwrite older methods.</p>
</li>
<li class="card">
<h2>Five</h2>
<p>We can use CSS Grid to overwrite older methods.</p>
</li>
<li class="card">
<h2>Six</h2>
<p>We can use CSS Grid to overwrite older methods.</p>
</li>
</ul>
</div>
The example demonstrates the typical problem that we have with floated layouts: if additional content is added to any one card, the layout breaks.
As a concession for older browsers, I have set a min-height
on the items, and hope that my content editors won't add too much content and make a mess of the layout!
I then enhance the layout using grid. I can turn my <ul>
into a grid container with three column tracks. However, the width I have assigned to the list items themselves still applies, and it now makes those items a third of the width of the track:
If I reset the width to auto
, then this will stop the float behavior happening for older browsers. I need to be able to define the width for older browsers, and remove the width for grid supporting browsers. Thanks to CSS Feature Queries I can do this, right in my CSS.
A solution using feature queries
Feature queries will look very familiar if you have ever used a media query to create a responsive layout. Rather than checking a viewport width, or some feature of the browser or device, we check for support of a CSS property and value pair using an @supports
rule. Inside the feature query, we can then write any CSS we need to apply our modern layout, and remove anything required for the older layout.
@supports (display: grid) {
.wrapper {
}
}
Feature queries have excellent browser support, and all of the browsers that support the updated grid specification support feature queries too. You can use them to deal with the issue we have with our enhanced: floated layout.
I use an @supports
rule to check for support of display: grid
. I then do my grid code on the <ul>
, set my width and min-height
on the <li>
to auto
. I also remove the margins and negative margins, and replace the spacing with the gap
property. This means I don't get a final margin on the last row of boxes. The layout now works, even if there is more content in one of the cards, than the others:
.wrapper ul {
overflow: hidden;
margin: 0 -10px;
padding: 0;
list-style: none;
}
.wrapper li {
float: left;
width: calc(33.333333% - 20px);
margin: 0 10px 20px 10px;
}
@supports (display: grid) {
.wrapper ul {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
margin: 0;
}
.wrapper li {
width: auto;
min-height: auto;
margin: 0;
}
}
<div class="wrapper">
<ul>
<li class="card">
<h2>One</h2>
<p>We can use CSS Grid to overwrite older methods.</p>
</li>
<li class="card">
<h2>Two</h2>
<p>We can use CSS Grid to overwrite older methods.</p>
<p>We can use CSS Grid to overwrite older methods.</p>
</li>
<li class="card">
<h2>Three</h2>
<p>We can use CSS Grid to overwrite older methods.</p>
</li>
<li class="card">
<h2>Four</h2>
<p>We can use CSS Grid to overwrite older methods.</p>
</li>
<li class="card">
<h2>Five</h2>
<p>We can use CSS Grid to overwrite older methods.</p>
</li>
<li class="card">
<h2>Six</h2>
<p>We can use CSS Grid to overwrite older methods.</p>
</li>
</ul>
</div>