Are you sick and tired of the way you design user interfaces? Imagine what it would be like to arrange a website in a really simple way, like sketching, without nerves and irritation as usual. Sketching with the ability to redesign everything based on screen width.
I know what you’re thinking: “it’s not possible”. Well, I had the same opinion.
And then I’ve discovered CSS Grid Layout.
A brief history of arranging websites.
I suppose that not many of you remember the times before flexbox. First, we used tables, which was painful. Then we were using floats, positions, inline-blocks and many others weird hacks... But all of them had many cons.
Finally, in 2009 the CSS Flexible Box Layout, commonly known as Flexbox, was released. Although it is relatively easy to arrange a website using flexbox, it is helping only with one-dimensional layouts. It has been noticed, and a few years later, the CSS Grid Layout has been published.
Back to the table design… But in the modern and more simple way.
Grid is one of the first CSS modules created to solve the layout problems we’ve all been dealing with using different hacks for as long as we’ve been building websites. It’s a two-dimensional grid-system design layout, but much simpler and more intuitive than others. Responsive Web Design with CSS Grid? No worries – it’s simpler than ever. This web layout model changed the way we design user interfaces.
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
<div class="item">10</div>
<div class="item">11</div>
<div class="item">12</div>
</div>
.container {
display: grid;
grid-gap: 10px;
grid-auto-rows: 100px;
grid-template-columns: repeat(4, 1fr);
}
Looks like magic? I hope not. Let me explain what happened.
Our class container has set ‘grid’ as a display value. Now every 1st level child inside this block will depend on properties set on the container.
Grid-gap is nothing else than space between container childs. It’ll be automatically updated on different screens (RWD). Do you remember how hard it was doing this before? Never again.
The last two properties used in the example are to specify how tracks should look like. There are two ways of setting it:
grid-template-rows/columns
grid-auto-rows/columns
In the template-way, we need to specify the exact number of vertical/horizontal tracks and their size. For example we can set:
grid-template-rows: 100px 200px 100px;
grid-template-columns: 100px 100px;
First 3 rows will have a specified height, and the rest will be set automatically. Every row will have 2 columns - 100px width each.
If in our stylesheet, the word ‘template’ will be replaced with ‘auto’, then we’re not specifying the number of tracks - only their size (like in the example on the screen above).
You have probably noticed that I used some terminology, like 'tracks'... You will encounter various new phrases around the CSS grid more than once, so let me introduce you to the basic concepts.
CSS Grid: Basic terminology
Grid container – the element on which display: grid; is applied; direct parent of all the grid items.
Grid items – the children of the grid container.
Grid line – the dividing lines that make up the structure of the grid; can be vertical or horizontal.
Grid track – the space between two grid lines; can be horizontal or vertical; the highlighted grid track is between row lines 2 and 3.
Grid cell – the smallest unit on our grid; the space between four grid lines; like a table cell; highlighted grid cell is between row lines 2 and 3 and column lines 2 and 3.
Grid area – any area of the grid, bounded by four grid lines; it can contain many grid cells. A highlighted grid area is between row lines 2 and 4 and column lines 2 and 5.
CSS Grid functions
OK, I know what you’re thinking. Everything seems excellent, but defining tracks took a lot of time and space. Let’s see what happens if you’ll have ten columns.
grid-template-columns: 100px 200px 100px 200px 100px 200px 100px 200px 100px 200px;
It looks really bad, isn’t it? The cool thing is grid functions. Now consider it this way:
grid-template-columns: repeat(5, 100px 200px);
So by using the repeat function, we can “generate” our code instead of writing it. That util needs two parameters – the first one is the number of tracks we’d like to have, and the second one – it’s a pattern.
There are also a few more functions – minmax, min, max. I believe that it’s not necessary to explain every one.
Free space units
If you already used CSS Grid, probably you met the situation when you’ve declared a few columns, which sum took 100% of site width, then defined a grid gap and you saw that horizontal scroll appeared.
I know the feeling. And to solve this problem, I found the solution – replacing fixed width by the “fr” units. For example:
Let’s replace
grid-template-columns: repeat(4, 25%);
with
grid-template-columns: repeat(4, 1fr);
It looks like it’s working fine… but how? Developers were using these weird units, but a lot of them couldn’t explain what it really is. Then I realised it’s a magic unit. Magic unit which looks at how much width has been taken by existing content, by fixed-size tracks, by grid-gap. Then, the remaining space will be divided up in proportion – based on how many tracks use ‘fr’ units. That’s why front-end developers used to call it ‘free space units’.
First responsive layout using grid and grid areas.
Take a look at the code below.
<div class="container">
<div class="item item5">P5</div>
<div class="item footer">FOOTER</div>
<div class="item item1">P1</div>
<div class="item item2">P2</div>
<div class="item item3">P3</div>
<div class="item header">HEADER</div>
<div class="item item4">P4</div>
</div>
Does it look awful? Yeah, I agree, but it does give a broader perspective on the mightiness of CSS Grid. This time check the result.
I know what you’re thinking: “it needs a really lot of CSS”. Think about how many lines were written to layout it, without colours, only the size and positions of the blocks. More than 100? 200? Let me shock you – only about ten.
.container {
display: grid;
grid-template-columns: repeat(6, 1fr);
grid-auto-rows: 100px;
grid-gap: 10px;
grid-template-areas:
"header header header header header header"
". i1 i2 i2 i3 ."
". i1 i2 i2 i3 ."
". i4 i5 i5 i3 ."
"footer footer footer footer footer footer";
}
“Whaaaat? How?” These thoughts accompanied me when I was discovering it. I’ve already explained the first properties, so let’s focus on the grid-template-areas. This is a mapping of the grid layout. Using that property, we can create the whole layout on the grid container.
So, in this example, we specified that the entire first row would be occupied by a header, in next rows, first and last columns will be empty (the dot sign means it’ll be empty). It’s so simple, isn’t it?
Ouch, I’ve forgotten about names. It’s not any kind of magic.
.header { grid-area: header; }
.item1 { grid-area: i1; }
So using that, we can also simply redefine the whole page layout depending on the screen width.
@media (max-width: 1024px) {
.container {
grid-template-columns: repeat(4, 1fr);
grid-template-areas:
"header i1 i1 i1"
"header i2 i3 i4"
"header i5 i5 i4"
"header footer footer footer";
}
}
Conclusion
CSS Grid is a modern way to position items. It works similar to a table – we can define the number of columns, rows and "merge" individual cells. However, CSS Grid has many other, more advanced features that I haven't covered in this article, and which are very helpful in positioning elements.