Fully Responsive CSS Grid Layout

Maggie Serino
4 min readAug 4, 2017

--

CSS Grid is a new system, not yet officially supported by all browsers, that allows to divide the page into regions and to define their relationships in terms of size, position, and layer. (Source: MDN)

The module presented to the W3C defines a two-dimensional grid-based layout system, optimized for user interface design. The children can be positioned into arbitrary slots in a predefined flexible or fixed-size layout grid. (Source: W3C)

In this example I’m going to show how I’ve set up the CSS Grid to recreate the layout of a Medium post (see what I’m doing here?😅), with Header, Footer, Post Author, full-size Post Image and Post Body with different levels of heading.

I’ve set up the project using a React application, which was absolutely not required given that the content is all static (I just wanted to get some practice with React).

Here is the Github repo for the project.

A live demo of the application can be found following this link.

Let’s start digging into the code.

The Grid

Main container divided in 12 sections

The main grid is divided into 12 columns and it’s using these attributes:

display: grid;
grid-template-columns: repeat(12, 1fr);

The container divides its columns in 12 sections of equal sizes (using the CSSGrid-specific features, the fr or fraction).
This means that is always dynamic and resizes depending on the viewport.

The header tag (in red in the picture) spans for 12 columns ( grid-column: span 12), but the actual content (in green) is set into a container that starts at the 3rd column and finishes at -3:

grid-column-start: 3;
grid-column-end: -3;

This means that the content will always be centered in the grid.

It works the same for all the elements of the page. The Post Author and Post Content (in pink) start at 4 and end at -4.

On the other hand, the Post Header (the one with the full-width image) behaves a bit like the Header and the Footer: it spans for 12 columns, and the Post Title (in pink), inside, is again in a 4/-4 container.

An advantage of the start/end approach is that there’s no need to set attributes like max-width or margin: 0 auto for any of the containers to make them centered: it will look like they’ll be floating in the center of the page, but actually they’re set within the grid, therefore fully manageable.

Responsive

How to make the CSS Grid responsive?
With some media queries, of course💃🏻!

Let’s take the Post Author div (in pink in the main image above) as an example.
On small viewports the author image is on top of the text, and from tablet on is on the left (screenshot below).

The HTML structure of this component is the following:

<div class="post-author">
<div class="post-author__image">
<!-- image tag here (we don't care about this) -->
</div>
<div class="post-author__info">
<!-- text tags here (we don't care about them) -->
</div>
</div>
Mobile view

The CSS for the mobile is:

.post-author {
&__image {
background-color: palegreen; // just for reference
grid-column: span 12;
}
&__info {
background-color: powderblue; // just for reference
grid-column: span 12;
}
}
Tablet/Desktop view

And the media query:

@media only screen and (min-width : 768px) {
.post-author {
&__image {
grid-column: span 1;
}
&__info {
grid-column: span 11;
}
}
}

The concept is a bit like Bootstrap (which we’re already used to): on mobile both image (palegreen) and text block (powderblue) occupy 12 columns: they’re stacking on top of each other.
From tablet the image occupies 1 column, positioning itself on the left, and the text block occupies 11, and it goes on the right.

The advantage of this approach is that it’s built 100% using CSS Grid. There are no floats, no clearfix, no percentages or calculations. The columns adjust themselves depending on how much space they have available.

Conclusions

I believe CSS Grid is a great tool to build solid layouts. I haven’t yet explored other features like the grid template areas, and so far I’ve made massive use of the grid-column and pretty much ignored grid-row , but it’s because I didn’t want to set a particular height to the elements, I’ve left the heights match the content, and used some padding for the white space.

In this example I haven’t touched the — very important — topic of compatibility. Of course, you can’t expect the example to work on all browser, simply because CSS Grid is not in the W3C standard at the time I’m writing this blog post.
There are fallback techniques (like the @support feature query) that can be used, but I haven’t explored them in this article, simply because I wanted to have a try on the actual layout. They will probably be the topic of a future post.

If you liked this article and you want to share your thoughts, or you think there’s something I missed, please leave a comment.

If you really liked it, why not share it with your social circle?

Again, you can view a demo of the example on the Demo Page (hosted on Heroku) and the project source on the Github Page.

See you at the next post.
Thank you!

P.S. I really love Web Colour names. I mean, lawngreen and mediumslateblue are just masterpieces, aren’t they? 😬

--

--