CSS Grid Layout – A Powerful Tool for Designing UI
Tags: css, ui, frontend
Published: 2021-02-23 13:27:11

<!-- wp:paragraph -->
<p>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. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>I know what you’re thinking: “it’s not possible”. Well, I had the same opinion.&nbsp;</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>And then I’ve discovered <strong>CSS Grid Layout</strong>.&nbsp;</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2><br>A brief history of arranging websites.</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>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.&nbsp;</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>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.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2><br>Back to the table design… But in the modern and more simple way.</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>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 <a href="https://pagepro.co/frontend-development.html" target="_blank" rel="noreferrer noopener">building websites</a>. 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.</p>
<!-- /wp:paragraph -->

<!-- wp:code-mind/code {"code":"\u003cdiv class=\u0022container\u0022\u003e\n  \u003cdiv class=\u0022item\u0022\u003e1\u003c/div\u003e\n  \u003cdiv class=\u0022item\u0022\u003e2\u003c/div\u003e\n  \u003cdiv class=\u0022item\u0022\u003e3\u003c/div\u003e\n  \u003cdiv class=\u0022item\u0022\u003e4\u003c/div\u003e\n  \u003cdiv class=\u0022item\u0022\u003e5\u003c/div\u003e\n  \u003cdiv class=\u0022item\u0022\u003e6\u003c/div\u003e\n  \u003cdiv class=\u0022item\u0022\u003e7\u003c/div\u003e\n  \u003cdiv class=\u0022item\u0022\u003e8\u003c/div\u003e\n  \u003cdiv class=\u0022item\u0022\u003e9\u003c/div\u003e\n  \u003cdiv class=\u0022item\u0022\u003e10\u003c/div\u003e\n  \u003cdiv class=\u0022item\u0022\u003e11\u003c/div\u003e\n  \u003cdiv class=\u0022item\u0022\u003e12\u003c/div\u003e\n\u003c/div\u003e","lang":"HTML"} -->
<pre class="wp-block-code-mind-code c-code"><code class="html">&lt;div class="container">
  &lt;div class="item">1&lt;/div>
  &lt;div class="item">2&lt;/div>
  &lt;div class="item">3&lt;/div>
  &lt;div class="item">4&lt;/div>
  &lt;div class="item">5&lt;/div>
  &lt;div class="item">6&lt;/div>
  &lt;div class="item">7&lt;/div>
  &lt;div class="item">8&lt;/div>
  &lt;div class="item">9&lt;/div>
  &lt;div class="item">10&lt;/div>
  &lt;div class="item">11&lt;/div>
  &lt;div class="item">12&lt;/div>
&lt;/div></code></pre>
<!-- /wp:code-mind/code -->

<!-- wp:code-mind/code {"code":".container {\n  display: grid;\n  grid-gap: 10px;\n  grid-auto-rows: 100px;\n  grid-template-columns: repeat(4, 1fr);\n}\n","lang":"CSS, SCSS"} -->
<pre class="wp-block-code-mind-code c-code"><code class="css, scss">.container {
  display: grid;
  grid-gap: 10px;
  grid-auto-rows: 100px;
  grid-template-columns: repeat(4, 1fr);
}
</code></pre>
<!-- /wp:code-mind/code -->

<!-- wp:image -->
<figure class="wp-block-image"><img src="https://lh3.googleusercontent.com/uzySmTExef2mhd0hZA595FJ6GSbC5sXF5W2He_5noSnuK1-8NL5Qw-j4A4SfgvkMI0ys43hHMwnHTXYch5E2sAPLW3OFu-f4uYk4ltqW2vT3VORS2MbqYEwkQlW3Ab-ZDgmf5PkO" alt="CSS Grid: simple example"/></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>Looks like magic? I hope not. Let me explain what happened.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Our class container has set ‘<strong>grid’</strong> as a <strong>display</strong> value. Now every 1st level child inside this block will depend on properties set on the container.&nbsp;</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><strong>Grid-gap</strong> 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.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The last two properties used in the example are to specify how tracks should look like. There are two ways of setting it:</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><strong>grid-template-rows/columns</strong></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><strong>grid-auto-rows/columns</strong></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>In the template-way, we need to specify the exact number of vertical/horizontal tracks and their size. For example we can set:</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><strong>grid-template-rows: 100px 200px 100px;</strong></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><strong>grid-template-columns: 100px 100px;&nbsp;</strong></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>First 3 rows will have a specified height, and the rest will be set automatically. Every row will have 2 columns - 100px width each.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>If in our stylesheet, the word <strong>‘template’</strong> will be replaced with <strong>‘auto’</strong>, then we’re not specifying the number of tracks - only their size (like in the example on the screen above).</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>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.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2><br>CSS Grid: Basic terminology</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p><strong>Grid container</strong> – the element on which display: grid; is applied; direct parent of all the grid items.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><strong>Grid items</strong> – the children of the grid container.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><strong>Grid line</strong> – the dividing lines that make up the structure of the grid; can be vertical or horizontal.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><strong>Grid track </strong>– the space between two <strong>grid lines</strong>; can be horizontal or vertical; the highlighted grid track is between row lines 2 and 3.</p>
<!-- /wp:paragraph -->

<!-- wp:image -->
<figure class="wp-block-image"><img src="https://lh5.googleusercontent.com/mHGAZxs9SxDTPzyQBcRZYZDQEyWcOS-QEOHbWMws8jW1NDoGmhOa8YulFM6hJopFJ396O5zIZrWPwviXELnjwR58zneYZKkqEQSGI-fylfpNRgBjLZs6v32nJJ048TQooPPO-tLi" alt="CSS Grid: grid track"/></figure>
<!-- /wp:image -->

<!-- wp:image -->
<figure class="wp-block-image"><img src="https://lh6.googleusercontent.com/Q_njGjUXJxv_lY5dx94KMqkxVt1IveLjZSCGon3XBDpGIfPqWGGgNjsxx8_1PumEJ7Zr6EB8ZwCSpwhMF-zBecFznkIe0xqo-FP6SdCHvs1Yu_XSi45zfAU91MRNGPWDeNCowVzw" alt="CSS Grid: grid track"/></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p><strong>Grid cell</strong> – the smallest unit on our grid; the space between four&nbsp;grid lines; like a table cell; highlighted grid cell is between row lines 2 and 3 and column lines 2 and 3.</p>
<!-- /wp:paragraph -->

<!-- wp:image -->
<figure class="wp-block-image"><img src="https://lh3.googleusercontent.com/lLYXgNni16hPFwb7iiEsQRsL50HM2q7YeOqpRMTCA7ixbiU91AUjYB2ZFm2oNOyRD9leXwK3q7Tkk_5TGIR0Ct0Na_EMqNwrMy0frj9oTUvi9dNGtTEGugZPvvH94ZZI1sA6_Mrh" alt="CSS Grid: grid cell"/></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p><strong>Grid area</strong> – 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.</p>
<!-- /wp:paragraph -->

<!-- wp:image -->
<figure class="wp-block-image"><img src="https://lh6.googleusercontent.com/yAXrSwxoopWJOH5dJ9UVmY8-rQ1d8RjGJVWNzROvJ77n_QnA4sG9ttDzydBW4xHGosYHT8C4PWhNGqvkEj5j1JIwBpq_Pnz-liRTwdtHuUtstHRaOS-qoO_6GZBCZPaeNTmEJIwg" alt="CSS Grid: grid area"/></figure>
<!-- /wp:image -->

<!-- wp:spacer {"height":50} -->
<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2><br>CSS Grid functions</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>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.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><strong>grid-template-columns: 100px 200px 100px 200px 100px 200px 100px 200px 100px 200px;</strong></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>It looks really bad, isn’t it? The cool thing is grid functions. Now consider it this way:</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><strong>grid-template-columns: repeat(5, 100px 200px);</strong></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>So by using the<strong> repeat </strong>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.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>There are also a few more functions – <strong>minmax</strong>, <strong>min</strong>, <strong>max</strong>. I believe that it’s not necessary to explain every one.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2><br>Free space units</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>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.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>I know the feeling. And to solve this problem, I found the solution – replacing fixed width by the “fr” units. For example:</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Let’s replace</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><strong>grid-template-columns: repeat(4, 25%);</strong></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>with</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><strong>grid-template-columns: repeat(4, 1fr);</strong></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>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’.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2><br>First responsive layout using grid and grid areas.</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Take a look at the code below.</p>
<!-- /wp:paragraph -->

<!-- wp:code-mind/code {"code":"\u003cdiv class=\u0022container\u0022\u003e\n  \u003cdiv class=\u0022item item5\u0022\u003eP5\u003c/div\u003e\n  \u003cdiv class=\u0022item footer\u0022\u003eFOOTER\u003c/div\u003e\n  \u003cdiv class=\u0022item item1\u0022\u003eP1\u003c/div\u003e\n  \u003cdiv class=\u0022item item2\u0022\u003eP2\u003c/div\u003e\n  \u003cdiv class=\u0022item item3\u0022\u003eP3\u003c/div\u003e\n  \u003cdiv class=\u0022item header\u0022\u003eHEADER\u003c/div\u003e\n  \u003cdiv class=\u0022item item4\u0022\u003eP4\u003c/div\u003e\n\u003c/div\u003e\n","lang":"HTML"} -->
<pre class="wp-block-code-mind-code c-code"><code class="html">&lt;div class="container">
  &lt;div class="item item5">P5&lt;/div>
  &lt;div class="item footer">FOOTER&lt;/div>
  &lt;div class="item item1">P1&lt;/div>
  &lt;div class="item item2">P2&lt;/div>
  &lt;div class="item item3">P3&lt;/div>
  &lt;div class="item header">HEADER&lt;/div>
  &lt;div class="item item4">P4&lt;/div>
&lt;/div>
</code></pre>
<!-- /wp:code-mind/code -->

<!-- wp:paragraph -->
<p>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.&nbsp;</p>
<!-- /wp:paragraph -->

<!-- wp:image -->
<figure class="wp-block-image"><img src="https://lh6.googleusercontent.com/LWpH7bpG1H8xs1xV2wNOBLoFxybxV8n35PPuhkpAGWqWHAYv1WSsRAnh0WNeORAwGpwXJgTUnSZl7zKqwPp1R9yrVwms0jXkYDVHre7HoUKrPeImHncatNX-z57ZAsdQekuCDcn9" alt=""/></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>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.</p>
<!-- /wp:paragraph -->

<!-- wp:code-mind/code {"code":".container {\n  display: grid;\n  grid-template-columns: repeat(6, 1fr);\n  grid-auto-rows: 100px;\n  grid-gap: 10px;\n \n  grid-template-areas:\n    \u0022header header header header header header\u0022\n    \u0022. i1 i2 i2 i3 .\u0022\n    \u0022. i1 i2 i2 i3 .\u0022\n    \u0022. i4 i5 i5 i3 .\u0022\n    \u0022footer footer footer footer footer footer\u0022;\n}\n","lang":"CSS, SCSS"} -->
<pre class="wp-block-code-mind-code c-code"><code class="css, scss">.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";
}
</code></pre>
<!-- /wp:code-mind/code -->

<!-- wp:paragraph -->
<p>“Whaaaat? How?” These thoughts accompanied me when I was discovering it. I’ve already explained the first properties, so let’s focus on the <strong>grid-template-areas</strong>. This is a mapping of the grid layout. Using that property, we can create the whole layout on the grid container. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>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?&nbsp;</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Ouch, I’ve forgotten about names. It’s not any kind of magic.</p>
<!-- /wp:paragraph -->

<!-- wp:code-mind/code {"code":".header { grid-area: header; }\n.item1 { grid-area: i1; }","lang":"CSS, SCSS"} -->
<pre class="wp-block-code-mind-code c-code"><code class="css, scss">.header { grid-area: header; }
.item1 { grid-area: i1; }</code></pre>
<!-- /wp:code-mind/code -->

<!-- wp:paragraph -->
<p>So using that, we can also simply redefine the whole page layout depending on the screen width.</p>
<!-- /wp:paragraph -->

<!-- wp:code-mind/code {"code":"@media (max-width: 1024px) {\n  .container {\n    grid-template-columns: repeat(4, 1fr);\n    grid-template-areas:\n      \u0022header i1 i1 i1\u0022\n      \u0022header i2 i3 i4\u0022\n      \u0022header i5 i5 i4\u0022\n      \u0022header footer footer footer\u0022;\n  }\n}\n","lang":"CSS, SCSS"} -->
<pre class="wp-block-code-mind-code c-code"><code class="css, scss">@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";
  }
}
</code></pre>
<!-- /wp:code-mind/code -->

<!-- wp:image -->
<figure class="wp-block-image"><img src="https://lh4.googleusercontent.com/sHjeMm-FFNd_KtajKF8hGxiMGn7qCtkieGBwAatqveNll52PNZrIRTlTWxXXEjbB2oQcuWzoajFxbxAqi_r7ED7fOkwIe831zlNlgZIJf7w2IiOvy5S8euCDPbJielCkeFz1aYRZ" alt=""/></figure>
<!-- /wp:image -->

<!-- wp:heading -->
<h2><br>Conclusion</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>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.</p>
<!-- /wp:paragraph -->