I mentioned that there were a couple of hacks we had to do to make it work, because of the way flexbox works. It is unidirectional in nature, which means, at any time you can only affect the layout in one direction, row or column. If you wish to make a complex layout with sections spanning across multiple rows and columns in a random fashion, then the best option (and somewhat of the only option) is CSS grids.
The last time I checked the compatibility for CSS grid layout in CanIUse.com, it is hovering around 95%. It is a very good coverage, you can confidently use CSS grids for your layout needs and this number will only become better going forward.
So, why don't we go ahead and implement the same layout in CSS grids?
Just like the previous one, we achieve the same UI, no difference at all. But internally, it is a lot cleaner and easy to understand.
Here is the codepen.
This is it, that is what we get. Not so much different from the previous flexbox example, much simpler internally.
Addressing the double
We have done some structural changes to the HTML. It no longer has two
h1s, which is good for our SEO stuff and semantics.
Now the structure looks like this:
This is so much simpler than the one in
We use the beauty of CSS grids and specifically
grid-template-areas property to achieve our desired layouts, both in desktop and mobile views.
To make grids work, we apply
display: grid to the root level
Unlike flexbox which might require multiple parent divs to achieve complex layouts, the grid system does require only one parent div and all the sections can be immediate children of that parent.
Lets see the magic of
The content wrapper div looks like this:
We firstly provide
grid-area label to each of the siblings and use those names in
grid-template-areas rule of the parent to decide the layout.
There are two strings in the value of
grid-template-areas, they represent two rows. And the contents of each string represent the columns. Each string has two tokens, so two columns each.
So, the first row has nothing in the first column (because
. represents nothing) and has the
header in the second column.
The second row has the
leftnav in the first column space and the
reading section in the second column space.
This is what we want.
Now lets look at the
grid-template-areas value in case of mobile view:
Here there are three strings, so three rows. And each string has only one token, so only one column. As simple as that.
Notice this line:
There is a function we are using here called
minmax. What this does is it fixes the minimum and maximum width values for each column (since it is
grid-template-columns). In this particular case, we want the first column of the
.content-wrapper to have a minimum of
250px and a maximum of
1fr means one fraction.
The second column has 3fr always (no
minmax applied), so as long as the total width of
.content-wrapper is such that the total fractions (1fr + 3fr = 4fr) is more than 4 times 250px, the width of the leftnav column will be that much (total width / 4). But as soon as that becomes 250px or less, the leftnav takes up 250px and the rest is divided to three fractions (3fr).
So, when the overall width is 1200px, the left column width is 1fr (out of 4fr) which is 1/4 of 1200px which is 300px.
Whereas when the overall width is just 900px, the leftnav takes up 250px and the reading section width is 650px (900 - 250).
Summing up, you can notice that the size of the leftnav increases slightly as you keep increasing the window width.
In the mobile view, there is only one column and all the rows have
1fr width, so they occupy complete width.
.reading-column__sections within the reading column and thanks to the below rules, the maximum width of these sections does not exceed
60ch even though the column itself is spanning till the right side edge.
If you are new to flexbox and grids in CSS, it is high time you learn them. There are many good resources for you to understand them. The browser support is getting better and better.
Please do suggest if you want me to achieve any other feature in this particular example. Or if you like it, please let me know what you learned.
Subscribe to my YouTube channel for many such developer tips.