Flexbox should be familiar to us all by now and has already given many developers a quiet night or two. But what if you could expand your Flexbox layout not only vertically, but also horizontally? This and more is possible since the integration of CSS Grid.
Imagine there was a way to freely design your website in a 2-dimensional grid. For example, allowing you to create text blocks that partially overlay images. Or even more complex image galleries without negative margins or positioning. Or using CSS to quickly design page templates that are also responsive. There is a solution for all of this: CSS Grid.
What is CSS Grid?
Similar to Flexbox, CSS Grid is also integrated with the help of a container element and CSS Grid Items. For example, we also find some properties for positioning the flexbox: for example align-items, justify items, justify self and align-self. These help you to position the contents of your grid accordingly.
Roughly speaking, CSS Grid is a flexbox that works 2-dimensionally:
While we can only build rows and corresponding columns horizontally with Flexbox, CSS Grid also gives us the option of arranging them vertically:
At first glance, CSS Grid may seem relatively unspectacular. After all, you can achieve the same result with Rows and Columns.
What makes CSS Grid so special?
With the new grid system, you can recreate every conceivable combination. The only condition is that they must be rectangular. Pure L-shapes, for example, cannot be constructed.
This allows you to plan and build your entire page layout based on CSS Grid. Nested grids are just as possible as the combination of CSS Grid and Flexbox.
Through clever planning, you can now also program your layouts in such a way that you can do without media queries as far as possible, but of course you don't have to. I will go into the various options in more detail later.
CSS Grid also comes with a number of other new CSS tricks that will make your life easier in the future. One of these is the new CSS unit: the so-called fraction (fr), which works in a similar way to the sizing of flexbox items.
A fraction (1fr) is a part of an entire row. So if you divide your grid into 3×4 as in the example below from CSS Tricks, then 1fr = ¼ or 25 %.
There is another special feature here: Not all boxes have to be filled with content. You can also assign empty content in the CSS grid:
W3Schools shows other possible layouts for which CSS grids are suitable. In this way, we can easily determine that certain elements should spread horizontally and vertically over a certain number of boxes. Boxes can have different widths (columns) and heights (rows).
In the example above, the first column is wider in percentage terms than the others. This is because the width was not predefined in the CSS and is therefore automatically based on the content. The same would happen if we create more content than we have predefined in the CSS. The grid would then automatically enlarge and append the new content.
Incidentally, Shopware's shopping worlds are based on a system similar to CSS Grid - at least in the backend view. In their WYSIWYG editor, content can be arranged in a grid that looks very similar to the CSS grid at first glance. In the final compiled page, however, no CSS Grid is used, at least by default.
CSS Grid has been supported by almost all common browsers since 2017. Only Internet Explorer versions from 10 onwards still require the -ms- prefix to be able to display the CSS Grid almost completely. Microsoft Edge, on the other hand, is already fully integrated. This means that nothing now stands in the way of using CSS Grid in your future projects:
What does CSS Grid look like in practice?
As already indicated, we use the basic function in a similar way to the flexbox. First, we define a container to which we assign the grid functions.
.container {
display: grid;}
There are a number of other values that you can assign to build the grid according to your wishes:
grid-template-columns, grid-template-rows and grid-template-areas (in summary, these can also all be set with grid-template ). These properties contain information on the number and size of the rows and columns. You can also define the distances between them with the properties column-gap and row-gap (or gap for short).
You also have the option - similar to the flexbox - to determine the overall positioning within the grid. There are the properties: justify-items, align-items (short: place-items), justify-content, align-content (short: place-content).
With the grid-auto-flow property, you can also determine the direction in which your grid should flow with the values row, column or dense. While row and column take care of the horizontal and vertical alignment respectively, dense determines that your grid is filled economically. This means that this value can be used to change the arrangement of your elements within the grid in order to fill otherwise empty space. This is a particularly interesting feature for image galleries. In this way, elements may move up in different screen sizes and there are no visual gaps.
While you define the columns and rows in the container, as well as the distances between them, you use the grid items to determine exactly where they should be located in the grid.
A finished grid could then look like this on the CSS side:
.container {
display: grid;
grid-template-columns: 40px 1fr 1fr 1fr 40px;
grid-template-rows: 25% 100px auto;
gap: .5rem .8rem
justify-items: stretch;}
Now that you have created your grid container, it's time to fill it with the grid items. The special thing about the CSS grid system is that the arrangement in the HTML can be secondary because you can give each item a start and end coordinate. This is done with grid-column-start, grid-column-end, grid-row-start, grid-row-end.
The coordinates point to the grid lines and count from left to right, or from top to bottom. These can also be abbreviated as grid-column and grid-row.
Advanced users can also use grid-area to give these fields all coordinates at once or assign a name to your grid item, the placement of which you can then determine yourself in the grid container. But you can name more than just the grid items. It is also possible to assign names to the grid lines so that you can tell the grid items their coordinates using these names. This saves you having to count them.
Also the use of negative values, or counting from left to right, bottom to top are possible. However, these are more interesting for advanced users of the CSS Grid and can be read in detail here:
Finally, you also have the option of individually determining the positioning of the content within the grid items. This is done with the properties: justify-self and align-self (short: place-self).
A grid item in CSS could look like this:
.item-a {
grid-column-start: 1;
grid-column-end: span 4;
grid-row-start: 2;
grid-row-end: span 2;
align-self: center;}
Grid row-end and grid-column-end can also be used with "span +n". This saves you tedious line counting. "Span 2" tells the item that it should extend over two grid fields. You can find detailed explanations of the individual properties in the CSS Tricks guide.
"*" indicates required fields
Examples from the web
If you're a visual guy like me, you need to see some real-world examples to fully understand CSS Grid. To do this, I did a bit of web browsing to find pages that were either created with CSS Grid or that could benefit from using it.
Levon Biss has used the CSS Grid as an implementation aid to create his portfolio. If you take a closer look at his page with the explorer tool, you will notice that the page was built with nested grid systems. First, the page was divided into three areas: Header, Main and Footer. The height for the header and the footer was predefined, while the main section with the value "auto" can grow flexibly with the content. The columns were set to the entire available width with 1fr.
.page-wrap {
height: 100%;
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 96px auto 72px;
}
The main of his page was again packed into a grid system. Notice how the CSS units px and fr were mixed here. This means that the border has a fixed width of 144px, while the middle section remains flexible.
.gallery-wrap{
display: grid;
grid-template-columns: 144px 1fr 144px;
grid-template-rows: 1fr;
height: 100%;
}
Finally, the gallery was also nested once again. Previously, no values were specified for the grid gaps. These are now set to 1em for the gallery. This saves adding margins between the images. So you can set the gaps once in the document.
.grid {
display: grid;
grid-template-columns: repeat(12,1fr);
grid-gap: 1em;
}
Another special feature of CSS Grid is the repeat() function. This is an abbreviated way of writing repeating values.
Repeat() takes the set of values to be created as the first value and the size as the second value. Written out, this would look like this:
.grid {
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
}
No CSS grid was used in this example. As in the previous example, we could have either nested the grid or added a margin to the grid container for the outer spacing.
The grid layout could look like this:
A possible approach to CSS could look like this:
.container {
margin: 0.5em 3em;
display: grid;
grid-template-columns: repeat(6, 1fr);
grid-template-rows: 100px 80px auto;
gap: .5rem;
}
.logo {
grid-area: 1 / 1 / 2 / span 3;
justify-self: start;
}
.nav {
grid-area: 1 / 4 / 2 / span 3;
justify-self: end;
}
.header {
grid-area: 2 / 1 / 3 / span 6;
justify-self: center;
}
.logo,
.nav,
.header {
align-self: center;
}
.img {
grid-column: span 2;
grid-row: span 2;
}
.img img {
width: 100%;
height: 100%;
object-fit: cover;
}
Although the entire Larq website could have benefited from the CSS grid, I have only selected a small area to illustrate this. The advantage of a 2-dimensional grid can be seen very clearly here.
This is how the grid items could be divided up:
A possible approach to CSS could look like this:
.container {
margin: 0.5em 5em;
display: grid;
grid-template-columns: repeat(3, 1fr) 50px repeat(3, 1fr);
grid-template-rows: 3rem 20px 100px 100px;
gap: 1rem;
}
.heading {
grid-column-start: 1;
grid-column-end: 8;
grid-row-start: 2;
grid-row-end: 1;
justify-self: center;
}
.img-a {
grid-area: 3 / 1 / span 2 / span 1;
}
.img-b {
grid-area: 3 / 2 / span 1 / span 1;
}
.img-c {
grid-area: 4 / 2 / span 1 / span 1;
}
.textblock {
grid-area: -3 / -4 / span 2 / span 2;
align-self: center;
}
Combining CSS Grid and WordPress
With the new WordPress editor, content can now also be displayed in rows and columns by default. However, the layout reminds me more of Bootstrap and co. and I miss the two-dimensionality. That's probably what others thought too, which is why they developed the Grids: Layout builder for WordPress plugin. The plugin is free and does exactly what it promises: it allows you to visually create CSS grids without the addition of a page builder.
The special thing about CSS Grid is the possibility of overlapping without the use of negative margin or absolute positioning. This is also easily possible with the plugin. Hierarchies can be displayed with the help of the z-index and also through the arrangement in the grid itself (the last element is at the top, the first at the bottom).
This is what the above example could look like as a website:
CSS Grid and @media query
CSS Grid can of course be used freely with Flexbox and Media Query. However, there is another new feature that CSS Grid brings with it: minmax()
As the name suggests, this is about minimum and maximum values. You can use this in conjunction with the columns. Unlike Media Query, it is not the screen size that is queried here, but the size of the element. If the box shrinks to such an extent that it falls below the minimum size, the elements are enlarged and moved so that they fit again.
Minmax() works in conjunction with auto-fit and can look like this:
.grid {
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}
Columns are created here that have a minimum size of 240px and a maximum size of 1fr. In this example, 1fr corresponds to the entire width of the grid. This means that several grid items can be placed next to each other if there is enough space, but use the entire width if there is not enough space.
But there are also advantages in connection with the Media Query. You can use the coordinates to place and arrange your grid items differently for each device. This can provide you with a pleasant user experience, especially on mobile devices, where the hierarchy can be different from that on the desktop.
"*" indicates required fields
All special features at a glance
- FR (fraction) as a new CSS unit
- Grid areas and lines can be given names
- Grid-column-end, can be used with "span n"
- Set grid alignment to "dense" to fill empty spaces with elements
- Declare identical columns or rows with repeat()
- Responsive display with the help of minmax() + auto-fit/auto-fill
- Grid items can be arranged arbitrarily (even overlapping) in the grid
Further sources of information on the topic
- A complete guide to CSS Grid from CSS Tricks
- A guide to learning CSS Grid from Learn CSS Grid
- Everything you need to learn CSS Grid, from Grid by Example
- Test your skills: Grid Layout from MDN Web Docs
- Learn all the functions of CSS Grid in a fun way with CSS Grid Garden
Do you have any other questions?
What questions do you have about CSS Grid? Feel free to use the comment function. Would you like to be informed about new articles on WordPress and web design? Then follow us on Twitter, Facebook, LinkedIn or via our newsletter.