Home >Web Front-end >CSS Tutorial >Redesigning a Site to Use CSS Grid Layout
In this article, we’re going to see CSS Grid in action by creating a responsive multi-column website layout.
CSS Grid is a new, hot trend in web development these days. Forget about table layouts and floats: a new way to design websites is already here! This technology introduces two-dimensional grids which define multiple areas of layout with a handful of CSS rules.
Grid can make third-party frameworks such as 960gs or Bootstrap grid redundant, as you may easily do everything yourself! This feature is supported by all major browsers, though Internet Explorer implements an older version of the specification.
If you’re new to Grid layout, check out our beginner’s guide to CSS Grid.
So, we were asked to create a typical website layout with a header, main content area, sidebar to the right, a list of sponsors, and a footer:
Another developer has already tried to solve this task and came up with a solution that involves floats, display: table, and some clearfix hacks. We’re going to refer to this existing layout as “initial”:
See the Pen SP: Multi-Column Layout With Floats by SitePoint (@SitePoint) on CodePen.
Until recently, floats were considered to be the best option to create such layouts. Prior to that, we had to utilize HTML tables, but they had a number of downsides. Specifically, such table layout is very rigid, requiring lots of tags (table, tr, td, th etc), and semantically these tags are used to present table data, not to design layouts.
But CSS continues to evolve, and now we have CSS Grid. Conceptually, it’s similar to an old table layout but can use semantic HTML elements with a more flexible layout.
First things first: we need to define a basic HTML structure for our document. Before that, let’s briefly talk about how the initial example works. It has the following main blocks:
Our new layout will be very similar to the initial one, but with one exception: we won’t add the .main-header and .content-area-wrapper wrappers because the clearfixes won’t be required anymore. Here is the new version of the HTML:
<span><span><span><div</span> class<span>="container"</span>></span> </span> <span><span><span><header</span> class<span>="logo"</span>></span> </span> <span><span><span><h1</span>></span><span><span><a</span> href<span>="#"</span>></span>DemoSite<span><span></a</span>></span><span><span></h1</span>></span> </span> <span><span><span></header</span>></span> </span> <span><span><span><nav</span> class<span>="main-menu"</span>></span> </span> <span><span><span><ul</span>></span> </span> <span><span><span><li</span> class<span>="main-menu__item"</span>></span><span><span><a</span> href<span>="#"</span>></span>Our clients<span><span></a</span>></span><span><span></li</span>></span> </span> <span><span><span><li</span> class<span>="main-menu__item"</span>></span><span><span><a</span> href<span>="#"</span>></span>Products<span><span></a</span>></span><span><span></li</span>></span> </span> <span><span><span><li</span> class<span>="main-menu__item"</span>></span><span><span><a</span> href<span>="#"</span>></span>Contact<span><span></a</span>></span><span><span></li</span>></span> </span> <span><span><span></ul</span>></span> </span> <span><span><span></nav</span>></span> </span> <span><span><span><main</span> class<span>="content-area"</span>></span> </span> <span><span><span><h2</span>></span>Welcome!<span><span></h2</span>></span> </span> <span><span><span><p</span>></span> </span> Content <span><span><span></p</span>></span> </span> <span><span><span></main</span>></span> </span> <span><span><span><aside</span> class<span>="sidebar"</span>></span> </span> <span><span><span><h3</span>></span>Additional stuff<span><span></h3</span>></span> </span> <span><span><span><ul</span>></span> </span> <span><span><span><li</span>></span>Items<span><span></li</span>></span> </span> <span><span><span><li</span>></span>Are<span><span></li</span>></span> </span> <span><span><span><li</span>></span>Listed<span><span></li</span>></span> </span> <span><span><span><li</span>></span>Here<span><span></li</span>></span> </span> <span><span><span><li</span>></span>Wow!<span><span></li</span>></span> </span> <span><span><span></ul</span>></span> </span> <span><span><span></aside</span>></span> </span> <span><span><span><section</span> class<span>="sponsors-wrapper"</span>></span> </span> <span><span><span><h2</span>></span>Our sponsors<span><span></h2</span>></span> </span> <span><span><span><section</span> class<span>="sponsors"</span>></span> </span> <span><span><span><figure</span> class<span>="sponsor"</span>></span> </span> <span><span><span><img</span> src<span>="https://via.placeholder.com/150x150"</span>></span> </span> <span><span><span></figure</span>></span> </span> <span><span><span><figure</span> class<span>="sponsor"</span>></span> </span> <span><span><span><img</span> src<span>="https://via.placeholder.com/200x150"</span>></span> </span> <span><span><span></figure</span>></span> </span> <span><span><span><figure</span> class<span>="sponsor"</span>></span> </span> <span><span><span><img</span> src<span>="https://via.placeholder.com/100x200"</span>></span> </span> <span><span><span></figure</span>></span> </span> <span><span><span><figure</span> class<span>="sponsor"</span>></span> </span> <span><span><span><img</span> src<span>="https://via.placeholder.com/100x100"</span>></span> </span> <span><span><span></figure</span>></span> </span> <span><span><span><figure</span> class<span>="sponsor"</span>></span> </span> <span><span><span><img</span> src<span>="https://via.placeholder.com/200x200"</span>></span> </span> <span><span><span></figure</span>></span> </span> <span><span><span></section</span>></span> </span> <span><span><span></section</span>></span> </span> <span><span><span><footer</span> class<span>="footer"</span>></span> </span> <span><span><span><p</span>></span> </span> <span title="©">© 2018 DemoSite. White&Sons LLC. All rights (perhaps) reserved. </span> <span><span><span></p</span>></span> </span> <span><span><span></footer</span>></span> </span><span><span><span></div</span>></span> </span>
Note that you may utilize the body as the global .container; that’s just a matter of preference in this case. All in all, we have six main areas:
Usually it’s recommended that you implement a mobile-first approach. That is, you start from the mobile layout and then add styles for larger screens. This isn’t necessary in this case, since we’re adapting an initial layout that already falls back to a linearized view on small-screen devices. Therefore, let’s start by focusing on the grid’s implementation, and after that talk about responsiveness and fallback rules. So, return to our scheme and see how the grid columns can be arranged:
So, I propose having three columns (highlighted in red) and four rows (highlighted in blue). Some areas, like the logo, are going to occupy only one column, whereas others, like main content, are going to span multiple columns. Later we can easily modify the layout, move the areas around, or add new ones.
Following the scheme, give each area a unique name. These will be used in the layout defined below:
<span><span>.logo</span> { </span> <span>grid-area: logo; </span><span>} </span> <span><span>.main-menu</span> { </span> <span>grid-area: menu; </span><span>} </span> <span><span>.content-area</span> { </span> <span>grid-area: content; </span><span>} </span> <span><span>.sidebar</span> { </span> <span>grid-area: sidebar; </span><span>} </span> <span><span>.sponsors-wrapper</span> { </span> <span>grid-area: sponsors; </span><span>} </span> <span><span>.footer</span> { </span> <span>grid-area: footer; </span><span>} </span>
Now set the display property to grid, define three columns and add small margins to the left and right of the main container:
<span><span><span><div</span> class<span>="container"</span>></span> </span> <span><span><span><header</span> class<span>="logo"</span>></span> </span> <span><span><span><h1</span>></span><span><span><a</span> href<span>="#"</span>></span>DemoSite<span><span></a</span>></span><span><span></h1</span>></span> </span> <span><span><span></header</span>></span> </span> <span><span><span><nav</span> class<span>="main-menu"</span>></span> </span> <span><span><span><ul</span>></span> </span> <span><span><span><li</span> class<span>="main-menu__item"</span>></span><span><span><a</span> href<span>="#"</span>></span>Our clients<span><span></a</span>></span><span><span></li</span>></span> </span> <span><span><span><li</span> class<span>="main-menu__item"</span>></span><span><span><a</span> href<span>="#"</span>></span>Products<span><span></a</span>></span><span><span></li</span>></span> </span> <span><span><span><li</span> class<span>="main-menu__item"</span>></span><span><span><a</span> href<span>="#"</span>></span>Contact<span><span></a</span>></span><span><span></li</span>></span> </span> <span><span><span></ul</span>></span> </span> <span><span><span></nav</span>></span> </span> <span><span><span><main</span> class<span>="content-area"</span>></span> </span> <span><span><span><h2</span>></span>Welcome!<span><span></h2</span>></span> </span> <span><span><span><p</span>></span> </span> Content <span><span><span></p</span>></span> </span> <span><span><span></main</span>></span> </span> <span><span><span><aside</span> class<span>="sidebar"</span>></span> </span> <span><span><span><h3</span>></span>Additional stuff<span><span></h3</span>></span> </span> <span><span><span><ul</span>></span> </span> <span><span><span><li</span>></span>Items<span><span></li</span>></span> </span> <span><span><span><li</span>></span>Are<span><span></li</span>></span> </span> <span><span><span><li</span>></span>Listed<span><span></li</span>></span> </span> <span><span><span><li</span>></span>Here<span><span></li</span>></span> </span> <span><span><span><li</span>></span>Wow!<span><span></li</span>></span> </span> <span><span><span></ul</span>></span> </span> <span><span><span></aside</span>></span> </span> <span><span><span><section</span> class<span>="sponsors-wrapper"</span>></span> </span> <span><span><span><h2</span>></span>Our sponsors<span><span></h2</span>></span> </span> <span><span><span><section</span> class<span>="sponsors"</span>></span> </span> <span><span><span><figure</span> class<span>="sponsor"</span>></span> </span> <span><span><span><img</span> src<span>="https://via.placeholder.com/150x150"</span>></span> </span> <span><span><span></figure</span>></span> </span> <span><span><span><figure</span> class<span>="sponsor"</span>></span> </span> <span><span><span><img</span> src<span>="https://via.placeholder.com/200x150"</span>></span> </span> <span><span><span></figure</span>></span> </span> <span><span><span><figure</span> class<span>="sponsor"</span>></span> </span> <span><span><span><img</span> src<span>="https://via.placeholder.com/100x200"</span>></span> </span> <span><span><span></figure</span>></span> </span> <span><span><span><figure</span> class<span>="sponsor"</span>></span> </span> <span><span><span><img</span> src<span>="https://via.placeholder.com/100x100"</span>></span> </span> <span><span><span></figure</span>></span> </span> <span><span><span><figure</span> class<span>="sponsor"</span>></span> </span> <span><span><span><img</span> src<span>="https://via.placeholder.com/200x200"</span>></span> </span> <span><span><span></figure</span>></span> </span> <span><span><span></section</span>></span> </span> <span><span><span></section</span>></span> </span> <span><span><span><footer</span> class<span>="footer"</span>></span> </span> <span><span><span><p</span>></span> </span> <span title="©">© 2018 DemoSite. White&Sons LLC. All rights (perhaps) reserved. </span> <span><span><span></p</span>></span> </span> <span><span><span></footer</span>></span> </span><span><span><span></div</span>></span> </span>
display: grid defines a grid container and sets a special formatting context for its children. fr is a special unit that means “fraction of the free space of the grid container”. 2 6 4 gives us 12, and 6 / 12 = 0.5. It means that the middle column is going to occupy 50% of the free space.
I would also like to add some spacing between the rows and columns:
<span><span>.logo</span> { </span> <span>grid-area: logo; </span><span>} </span> <span><span>.main-menu</span> { </span> <span>grid-area: menu; </span><span>} </span> <span><span>.content-area</span> { </span> <span>grid-area: content; </span><span>} </span> <span><span>.sidebar</span> { </span> <span>grid-area: sidebar; </span><span>} </span> <span><span>.sponsors-wrapper</span> { </span> <span>grid-area: sponsors; </span><span>} </span> <span><span>.footer</span> { </span> <span>grid-area: footer; </span><span>} </span>
Having done this, we can work with individual areas. But before wrapping up this section, let’s quickly add some common styles:
<span><span>.container</span> { </span> <span>display: grid; </span> <span>margin: 0 2rem; </span> <span>grid-template-columns: 2fr 6fr 4fr; </span><span>} </span>
Good! Now we can proceed to the first target, which is going to be the header.
Our header occupies the first row that should have a specific height set to 3rem. In the initial layout this is solved by assigning the height property for the header wrapper:
<span><span>.container</span> { </span> // ... <span>grid-gap: 2rem 1rem; </span><span>} </span>
Also note that the logo and the menu are vertically aligned to the middle, which is achieved using the line-height trick:
<span>* { </span> <span>box-sizing: border-box; </span><span>} </span> <span>html { </span> <span>font-size: 16px; </span> <span>font-family: Georgia, serif; </span><span>} </span> <span>body { </span> <span>background-color: #fbfbfb; </span><span>} </span> <span>h1<span>, h2, h3</span> { </span> <span>margin-top: 0; </span><span>} </span> <span>header h1 { </span> <span>margin: 0; </span><span>} </span> <span>main p { </span> <span>margin-bottom: 0; </span><span>} </span>
With CSS Grid, however, things are going to be simpler: we won’t require any CSS hacks.
Start by defining the first row:
<span><span>.main-header</span> { </span> <span>height: 3rem; </span><span>} </span>
Our logo should occupy only one column, whereas the menu should span two columns. We can express our intent with the help of the grid-template-areas property, which references the grid-area names assigned above:
<span><span>.logo</span> { </span> // ... <span>height: 100%; </span> <span>line-height: 3rem; </span><span>} </span>
What’s going on here? Well, by saying logo only once, we’re making sure that it occupies only one — the left-most column. menu menu means that the menu occupies two columns: the middle and the right-most one. See how straightforward this rule is!
Now align the logo on the Y axis:
<span><span>.container</span> { </span> // ... <span>grid-template-rows: 3rem; </span><span>} </span>
The menu should be centered vertically and pulled to the right:
<span><span>.container</span> { </span> // ... <span>grid-template-areas: </span> <span>"logo menu menu"; </span><span>} </span>
Our menu is built with the ul and li tags, so let’s also style them a bit by removing markers, nullifying margins/paddings, and setting the menu to a flex container:
<span><span>.logo</span> { </span> <span>grid-area: logo; </span> <span>align-self: center; </span><span>} </span>
That’s pretty much it. To observe the result, I’m going to use Firefox with a handy CSS Grid highlighter tool enabled. (There are similar tools for other browsers available: for instance, Gridman for Chrome.) To gain access to this tool, press F12 and select the .container element, which should have a grid label:
After that, proceed to the CSS rules tab, and find the display: grid property. By pressing on the small icon next to the grid value, you can enable or disable the highlighter:
Here is the result:
The highlighter displays all your rows and columns, as well as the margins between them and the areas’ names. You can customize the output inside the Layout section, which also lists all the grids on the page:
So, we’ve dealt with the header, so let’s proceed to the main content area and the sidebar.
Our main content area should span two columns, whereas the sidebar should occupy only one. As for the row, I’d like its height to be set automatically. We can update the .container grid accordingly:
<span><span><span><div</span> class<span>="container"</span>></span> </span> <span><span><span><header</span> class<span>="logo"</span>></span> </span> <span><span><span><h1</span>></span><span><span><a</span> href<span>="#"</span>></span>DemoSite<span><span></a</span>></span><span><span></h1</span>></span> </span> <span><span><span></header</span>></span> </span> <span><span><span><nav</span> class<span>="main-menu"</span>></span> </span> <span><span><span><ul</span>></span> </span> <span><span><span><li</span> class<span>="main-menu__item"</span>></span><span><span><a</span> href<span>="#"</span>></span>Our clients<span><span></a</span>></span><span><span></li</span>></span> </span> <span><span><span><li</span> class<span>="main-menu__item"</span>></span><span><span><a</span> href<span>="#"</span>></span>Products<span><span></a</span>></span><span><span></li</span>></span> </span> <span><span><span><li</span> class<span>="main-menu__item"</span>></span><span><span><a</span> href<span>="#"</span>></span>Contact<span><span></a</span>></span><span><span></li</span>></span> </span> <span><span><span></ul</span>></span> </span> <span><span><span></nav</span>></span> </span> <span><span><span><main</span> class<span>="content-area"</span>></span> </span> <span><span><span><h2</span>></span>Welcome!<span><span></h2</span>></span> </span> <span><span><span><p</span>></span> </span> Content <span><span><span></p</span>></span> </span> <span><span><span></main</span>></span> </span> <span><span><span><aside</span> class<span>="sidebar"</span>></span> </span> <span><span><span><h3</span>></span>Additional stuff<span><span></h3</span>></span> </span> <span><span><span><ul</span>></span> </span> <span><span><span><li</span>></span>Items<span><span></li</span>></span> </span> <span><span><span><li</span>></span>Are<span><span></li</span>></span> </span> <span><span><span><li</span>></span>Listed<span><span></li</span>></span> </span> <span><span><span><li</span>></span>Here<span><span></li</span>></span> </span> <span><span><span><li</span>></span>Wow!<span><span></li</span>></span> </span> <span><span><span></ul</span>></span> </span> <span><span><span></aside</span>></span> </span> <span><span><span><section</span> class<span>="sponsors-wrapper"</span>></span> </span> <span><span><span><h2</span>></span>Our sponsors<span><span></h2</span>></span> </span> <span><span><span><section</span> class<span>="sponsors"</span>></span> </span> <span><span><span><figure</span> class<span>="sponsor"</span>></span> </span> <span><span><span><img</span> src<span>="https://via.placeholder.com/150x150"</span>></span> </span> <span><span><span></figure</span>></span> </span> <span><span><span><figure</span> class<span>="sponsor"</span>></span> </span> <span><span><span><img</span> src<span>="https://via.placeholder.com/200x150"</span>></span> </span> <span><span><span></figure</span>></span> </span> <span><span><span><figure</span> class<span>="sponsor"</span>></span> </span> <span><span><span><img</span> src<span>="https://via.placeholder.com/100x200"</span>></span> </span> <span><span><span></figure</span>></span> </span> <span><span><span><figure</span> class<span>="sponsor"</span>></span> </span> <span><span><span><img</span> src<span>="https://via.placeholder.com/100x100"</span>></span> </span> <span><span><span></figure</span>></span> </span> <span><span><span><figure</span> class<span>="sponsor"</span>></span> </span> <span><span><span><img</span> src<span>="https://via.placeholder.com/200x200"</span>></span> </span> <span><span><span></figure</span>></span> </span> <span><span><span></section</span>></span> </span> <span><span><span></section</span>></span> </span> <span><span><span><footer</span> class<span>="footer"</span>></span> </span> <span><span><span><p</span>></span> </span> <span title="©">© 2018 DemoSite. White&Sons LLC. All rights (perhaps) reserved. </span> <span><span><span></p</span>></span> </span> <span><span><span></footer</span>></span> </span><span><span><span></div</span>></span> </span>
I’d like to add some padding for the sidebar to give it some more visual space:
<span><span>.logo</span> { </span> <span>grid-area: logo; </span><span>} </span> <span><span>.main-menu</span> { </span> <span>grid-area: menu; </span><span>} </span> <span><span>.content-area</span> { </span> <span>grid-area: content; </span><span>} </span> <span><span>.sidebar</span> { </span> <span>grid-area: sidebar; </span><span>} </span> <span><span>.sponsors-wrapper</span> { </span> <span>grid-area: sponsors; </span><span>} </span> <span><span>.footer</span> { </span> <span>grid-area: footer; </span><span>} </span>
Here’s the result, as viewed in Firefox’s Grid tool:
The sponsors section should contain five items with equal widths and heights. Each item, in turn, will have one image.
In the initial layout, this block is styled with display: table, but we won’t rely on it. Actually, the sponsors section may be a great candidate for applying CSS grid as well!
First of all, tweak the grid-template-areas to include the sponsors area:
<span><span>.container</span> { </span> <span>display: grid; </span> <span>margin: 0 2rem; </span> <span>grid-template-columns: 2fr 6fr 4fr; </span><span>} </span>
Now turn the .sponsors section into a grid as well:
<span><span>.container</span> { </span> // ... <span>grid-gap: 2rem 1rem; </span><span>} </span>
As long as we need five items with equal widths, the repeat() function can be utilized to define the columns:
<span>* { </span> <span>box-sizing: border-box; </span><span>} </span> <span>html { </span> <span>font-size: 16px; </span> <span>font-family: Georgia, serif; </span><span>} </span> <span>body { </span> <span>background-color: #fbfbfb; </span><span>} </span> <span>h1<span>, h2, h3</span> { </span> <span>margin-top: 0; </span><span>} </span> <span>header h1 { </span> <span>margin: 0; </span><span>} </span> <span>main p { </span> <span>margin-bottom: 0; </span><span>} </span>
As for the row, its height should be set automatically. The gap between the columns should be equal to 1rem:
<span><span>.main-header</span> { </span> <span>height: 3rem; </span><span>} </span>
Style each item:
<span><span>.logo</span> { </span> // ... <span>height: 100%; </span> <span>line-height: 3rem; </span><span>} </span>
Here’s the intermediate result:
This example illustrates that you can nest grids without any problems. Another solution might be using Flexbox, but in this case the sponsors may wrap if there’s not enough width for them.
Now I would like to center the images both vertically and horizontally. We might try doing the following:
<span><span>.container</span> { </span> // ... <span>grid-template-rows: 3rem; </span><span>} </span>
place-self aligns the element on the X and Y axes. It’s a shorthand property to align-self and justify-self.
The images will indeed be aligned, but unfortunately the white background is gone. This is because each .sponsor now has width and height equal to the image’s dimensions:
It means that we need a different approach here, and one of the possible solutions is to employ Flexbox:
<span><span>.container</span> { </span> // ... <span>grid-template-areas: </span> <span>"logo menu menu"; </span><span>} </span>
Now everything is displayed properly, and now we know that Grid plays nicely with Flexbox:
Our last section is the footer, and it’s actually the simplest section. All we have to do is span it to all three columns:
<span><span><span><div</span> class<span>="container"</span>></span> </span> <span><span><span><header</span> class<span>="logo"</span>></span> </span> <span><span><span><h1</span>></span><span><span><a</span> href<span>="#"</span>></span>DemoSite<span><span></a</span>></span><span><span></h1</span>></span> </span> <span><span><span></header</span>></span> </span> <span><span><span><nav</span> class<span>="main-menu"</span>></span> </span> <span><span><span><ul</span>></span> </span> <span><span><span><li</span> class<span>="main-menu__item"</span>></span><span><span><a</span> href<span>="#"</span>></span>Our clients<span><span></a</span>></span><span><span></li</span>></span> </span> <span><span><span><li</span> class<span>="main-menu__item"</span>></span><span><span><a</span> href<span>="#"</span>></span>Products<span><span></a</span>></span><span><span></li</span>></span> </span> <span><span><span><li</span> class<span>="main-menu__item"</span>></span><span><span><a</span> href<span>="#"</span>></span>Contact<span><span></a</span>></span><span><span></li</span>></span> </span> <span><span><span></ul</span>></span> </span> <span><span><span></nav</span>></span> </span> <span><span><span><main</span> class<span>="content-area"</span>></span> </span> <span><span><span><h2</span>></span>Welcome!<span><span></h2</span>></span> </span> <span><span><span><p</span>></span> </span> Content <span><span><span></p</span>></span> </span> <span><span><span></main</span>></span> </span> <span><span><span><aside</span> class<span>="sidebar"</span>></span> </span> <span><span><span><h3</span>></span>Additional stuff<span><span></h3</span>></span> </span> <span><span><span><ul</span>></span> </span> <span><span><span><li</span>></span>Items<span><span></li</span>></span> </span> <span><span><span><li</span>></span>Are<span><span></li</span>></span> </span> <span><span><span><li</span>></span>Listed<span><span></li</span>></span> </span> <span><span><span><li</span>></span>Here<span><span></li</span>></span> </span> <span><span><span><li</span>></span>Wow!<span><span></li</span>></span> </span> <span><span><span></ul</span>></span> </span> <span><span><span></aside</span>></span> </span> <span><span><span><section</span> class<span>="sponsors-wrapper"</span>></span> </span> <span><span><span><h2</span>></span>Our sponsors<span><span></h2</span>></span> </span> <span><span><span><section</span> class<span>="sponsors"</span>></span> </span> <span><span><span><figure</span> class<span>="sponsor"</span>></span> </span> <span><span><span><img</span> src<span>="https://via.placeholder.com/150x150"</span>></span> </span> <span><span><span></figure</span>></span> </span> <span><span><span><figure</span> class<span>="sponsor"</span>></span> </span> <span><span><span><img</span> src<span>="https://via.placeholder.com/200x150"</span>></span> </span> <span><span><span></figure</span>></span> </span> <span><span><span><figure</span> class<span>="sponsor"</span>></span> </span> <span><span><span><img</span> src<span>="https://via.placeholder.com/100x200"</span>></span> </span> <span><span><span></figure</span>></span> </span> <span><span><span><figure</span> class<span>="sponsor"</span>></span> </span> <span><span><span><img</span> src<span>="https://via.placeholder.com/100x100"</span>></span> </span> <span><span><span></figure</span>></span> </span> <span><span><span><figure</span> class<span>="sponsor"</span>></span> </span> <span><span><span><img</span> src<span>="https://via.placeholder.com/200x200"</span>></span> </span> <span><span><span></figure</span>></span> </span> <span><span><span></section</span>></span> </span> <span><span><span></section</span>></span> </span> <span><span><span><footer</span> class<span>="footer"</span>></span> </span> <span><span><span><p</span>></span> </span> <span title="©">© 2018 DemoSite. White&Sons LLC. All rights (perhaps) reserved. </span> <span><span><span></p</span>></span> </span> <span><span><span></footer</span>></span> </span><span><span><span></div</span>></span> </span>
Basically, the layout is finished! However, we’re not done yet: the site also has to be responsive. So, let’s take care of this task in the next section.
Having CSS Grid in place, it’s actually very easy to introduce responsiveness, because we can quickly reposition the areas.
Let’s start with large screens (in this article I’ll be sticking to the same breakpoints as defined in Bootstrap 4). I’d like to decrease the horizontal margin of the main container and the gap between individual sponsors:
<span><span>.logo</span> { </span> <span>grid-area: logo; </span><span>} </span> <span><span>.main-menu</span> { </span> <span>grid-area: menu; </span><span>} </span> <span><span>.content-area</span> { </span> <span>grid-area: content; </span><span>} </span> <span><span>.sidebar</span> { </span> <span>grid-area: sidebar; </span><span>} </span> <span><span>.sponsors-wrapper</span> { </span> <span>grid-area: sponsors; </span><span>} </span> <span><span>.footer</span> { </span> <span>grid-area: footer; </span><span>} </span>
On the medium screens, I’d like the main content area and the sidebar to occupy all three columns:
<span><span>.container</span> { </span> <span>display: grid; </span> <span>margin: 0 2rem; </span> <span>grid-template-columns: 2fr 6fr 4fr; </span><span>} </span>
Let’s also decrease font size and stack the sponsors so they’re displayed one beneath another. The gap between the columns should be zero (because actually there will be only one column). Instead, I’ll set a gap between the rows:
<span><span>.container</span> { </span> // ... <span>grid-gap: 2rem 1rem; </span><span>} </span>
This is how the layout looks on medium screens now:
On small screens, we’re going to display each area on a separate row, which means that there will be only one column now:
<span>* { </span> <span>box-sizing: border-box; </span><span>} </span> <span>html { </span> <span>font-size: 16px; </span> <span>font-family: Georgia, serif; </span><span>} </span> <span>body { </span> <span>background-color: #fbfbfb; </span><span>} </span> <span>h1<span>, h2, h3</span> { </span> <span>margin-top: 0; </span><span>} </span> <span>header h1 { </span> <span>margin: 0; </span><span>} </span> <span>main p { </span> <span>margin-bottom: 0; </span><span>} </span>
The menu should not be pulled to the right in this case, and we also don’t need the gap between the columns:
<span><span>.main-header</span> { </span> <span>height: 3rem; </span><span>} </span>
The job is done:
Note that you may even rearrange the grid items easily for various screens. Suppose we’d like to put the menu at the bottom on small screens (so that the visitors don’t have to scroll up after they’ve finished reading material on the page). To do that, simply tweak the grid-template-areas:
<span><span>.logo</span> { </span> // ... <span>height: 100%; </span> <span>line-height: 3rem; </span><span>} </span>
It’s worth mentioning that we can make the sponsors block responsive without any media queries at all. This is possible with the help of auto-fit property and minmax function. To see them in action, tweak the styles for the .sponsors like this:
<span><span>.container</span> { </span> // ... <span>grid-template-rows: 3rem; </span><span>} </span>
The repeat function, as you already know, repeats the columns as many times as necessary.
auto-fill means “fill the row with as many columns as possible”. If there’s not enough space for the column, it will be placed to the next line.
minmax allows us to specify the minimum and maximum value for the columns’ widths. In this case, each column should span 1 fraction of free space, but no less than 200 pixels.
All this means that on smaller screens the columns may be shrunk down to at most 200px each. If there’s still not enough space, one or multiple columns will be moved to a separate line. Here’s the result of applying the above CSS rules:
Unfortunately, CSS Grid is not yet fully supported by all browsers, and you may guess which one is still implementing an older version of the specification. Yeah, it’s Internet Explorer 10 and 11. If you open the demo in those browsers, you’ll see that the grid doesn’t work at all, and the areas are simply stacked:
Of course, this isn’t the end of the world, as the site is still usable, but let’s add at least some fallback rules. The good news is that if the element is floated and also has grid assigned, the grid takes precedence. Also, the display, vertical-align, and some other properties also have no effect on grid items, so let’s take advantage of that fact.
The stacked menu looks nice as is, but the sidebar should probably be placed next to the main content, not below it. We can achieve this by using display: inline-block:
<span><span><span><div</span> class<span>="container"</span>></span> </span> <span><span><span><header</span> class<span>="logo"</span>></span> </span> <span><span><span><h1</span>></span><span><span><a</span> href<span>="#"</span>></span>DemoSite<span><span></a</span>></span><span><span></h1</span>></span> </span> <span><span><span></header</span>></span> </span> <span><span><span><nav</span> class<span>="main-menu"</span>></span> </span> <span><span><span><ul</span>></span> </span> <span><span><span><li</span> class<span>="main-menu__item"</span>></span><span><span><a</span> href<span>="#"</span>></span>Our clients<span><span></a</span>></span><span><span></li</span>></span> </span> <span><span><span><li</span> class<span>="main-menu__item"</span>></span><span><span><a</span> href<span>="#"</span>></span>Products<span><span></a</span>></span><span><span></li</span>></span> </span> <span><span><span><li</span> class<span>="main-menu__item"</span>></span><span><span><a</span> href<span>="#"</span>></span>Contact<span><span></a</span>></span><span><span></li</span>></span> </span> <span><span><span></ul</span>></span> </span> <span><span><span></nav</span>></span> </span> <span><span><span><main</span> class<span>="content-area"</span>></span> </span> <span><span><span><h2</span>></span>Welcome!<span><span></h2</span>></span> </span> <span><span><span><p</span>></span> </span> Content <span><span><span></p</span>></span> </span> <span><span><span></main</span>></span> </span> <span><span><span><aside</span> class<span>="sidebar"</span>></span> </span> <span><span><span><h3</span>></span>Additional stuff<span><span></h3</span>></span> </span> <span><span><span><ul</span>></span> </span> <span><span><span><li</span>></span>Items<span><span></li</span>></span> </span> <span><span><span><li</span>></span>Are<span><span></li</span>></span> </span> <span><span><span><li</span>></span>Listed<span><span></li</span>></span> </span> <span><span><span><li</span>></span>Here<span><span></li</span>></span> </span> <span><span><span><li</span>></span>Wow!<span><span></li</span>></span> </span> <span><span><span></ul</span>></span> </span> <span><span><span></aside</span>></span> </span> <span><span><span><section</span> class<span>="sponsors-wrapper"</span>></span> </span> <span><span><span><h2</span>></span>Our sponsors<span><span></h2</span>></span> </span> <span><span><span><section</span> class<span>="sponsors"</span>></span> </span> <span><span><span><figure</span> class<span>="sponsor"</span>></span> </span> <span><span><span><img</span> src<span>="https://via.placeholder.com/150x150"</span>></span> </span> <span><span><span></figure</span>></span> </span> <span><span><span><figure</span> class<span>="sponsor"</span>></span> </span> <span><span><span><img</span> src<span>="https://via.placeholder.com/200x150"</span>></span> </span> <span><span><span></figure</span>></span> </span> <span><span><span><figure</span> class<span>="sponsor"</span>></span> </span> <span><span><span><img</span> src<span>="https://via.placeholder.com/100x200"</span>></span> </span> <span><span><span></figure</span>></span> </span> <span><span><span><figure</span> class<span>="sponsor"</span>></span> </span> <span><span><span><img</span> src<span>="https://via.placeholder.com/100x100"</span>></span> </span> <span><span><span></figure</span>></span> </span> <span><span><span><figure</span> class<span>="sponsor"</span>></span> </span> <span><span><span><img</span> src<span>="https://via.placeholder.com/200x200"</span>></span> </span> <span><span><span></figure</span>></span> </span> <span><span><span></section</span>></span> </span> <span><span><span></section</span>></span> </span> <span><span><span><footer</span> class<span>="footer"</span>></span> </span> <span><span><span><p</span>></span> </span> <span title="©">© 2018 DemoSite. White&Sons LLC. All rights (perhaps) reserved. </span> <span><span><span></p</span>></span> </span> <span><span><span></footer</span>></span> </span><span><span><span></div</span>></span> </span>
In all browsers that support grid, these properties will have no effect, but in IE they’ll be applied as expected. One more property we need to tweak is the width:
<span><span>.logo</span> { </span> <span>grid-area: logo; </span><span>} </span> <span><span>.main-menu</span> { </span> <span>grid-area: menu; </span><span>} </span> <span><span>.content-area</span> { </span> <span>grid-area: content; </span><span>} </span> <span><span>.sidebar</span> { </span> <span>grid-area: sidebar; </span><span>} </span> <span><span>.sponsors-wrapper</span> { </span> <span>grid-area: sponsors; </span><span>} </span> <span><span>.footer</span> { </span> <span>grid-area: footer; </span><span>} </span>
But having added these styles, our grid layout will now look much worse, because the width property isn’t ignored by grid items. This can be fixed with the help of the @supports CSS query. IE doesn’t understand these queries, but it doesn’t need to: we’ll use it to fix the grid!
<span><span>.container</span> { </span> <span>display: grid; </span> <span>margin: 0 2rem; </span> <span>grid-template-columns: 2fr 6fr 4fr; </span><span>} </span>
Now let’s take care of the sponsor items and add some top margin for each block:
<span><span>.container</span> { </span> // ... <span>grid-gap: 2rem 1rem; </span><span>} </span>
We don’t need any top margin when the grid is supported, so nullify it inside the @supports query:
<span>* { </span> <span>box-sizing: border-box; </span><span>} </span> <span>html { </span> <span>font-size: 16px; </span> <span>font-family: Georgia, serif; </span><span>} </span> <span>body { </span> <span>background-color: #fbfbfb; </span><span>} </span> <span>h1<span>, h2, h3</span> { </span> <span>margin-top: 0; </span><span>} </span> <span>header h1 { </span> <span>margin: 0; </span><span>} </span> <span>main p { </span> <span>margin-bottom: 0; </span><span>} </span>
Lastly, let’s add some responsiveness for IE. We’ll simply stretch the main content, sidebar, and each sponsor to full width on smaller screens:
<span><span>.main-header</span> { </span> <span>height: 3rem; </span><span>} </span>
Don’t forget to fix the sponsor’s width for the browsers that support grid:
<span><span>.logo</span> { </span> // ... <span>height: 100%; </span> <span>line-height: 3rem; </span><span>} </span>
Here’s how the layout looks in Internet Explorer now:
You can view the final result on CodePen:
See the Pen SP: Multi-Column Layout With Grid by SitePoint (@SitePoint) on CodePen.
In this article, we’ve seen CSS Grid in action and utilized it to redesign an existing float-based layout. Comparing these two solutions, we can see that the HTML and CSS code of the “grid” solution is smaller (not counting the fallbacks, of course), simpler, and more expressive. With the help of the grid-template-areas property, it’s easy to understand how individual areas are laid out, and we can quickly reposition them or adjust their sizes. On top of that, we don’t need to rely on various hacky tricks like clearfix.
So, as you see, CSS Grid is a great alternative to floats, and it’s very much production-ready. You may need to provide some fallback rules for Internet Explorer (that implements an older version of the specification), but as you’ve seen, they’re not very complex, and in general the site is still usable even without any backwards compatibility at all.
Have you already tried creating websites with CSS Grid? What are your impressions? Share your thoughts in the comments!
CSS Grid Retrofit is a powerful tool in web design that allows developers to create complex layouts with ease. It is a two-dimensional system, meaning it can handle both columns and rows, unlike flexbox which is largely a one-dimensional system. This makes it a versatile tool for creating responsive designs that adapt to different screen sizes and resolutions. It also simplifies the process of aligning and distributing space among items in a container, even when their size is unknown or dynamic.
CSS Grid Retrofit stands out from other grid systems due to its flexibility and ease of use. Unlike other systems that require extensive coding and calculations, CSS Grid Retrofit allows developers to create complex layouts with minimal code. It also offers more control over the placement and alignment of elements, making it a preferred choice for many developers.
Yes, CSS Grid Retrofit is an excellent tool for creating mobile responsive designs. It allows developers to define different grid layouts for different screen sizes using media queries. This means you can create a complex layout for a desktop view, and a simpler, more streamlined layout for mobile view, all within the same CSS document.
CSS Grid Retrofit is compatible with most modern browsers, including Chrome, Firefox, Safari, and Edge. However, it may not work as expected in older browsers or versions. It’s always a good practice to test your design in multiple browsers to ensure it works as intended.
To start using CSS Grid Retrofit, you need to define a container element as a grid with display: grid. Then, you can define the column and row sizes with grid-template-columns and grid-template-rows, and place its child elements into the grid with grid-column and grid-row.
Yes, CSS Grid Retrofit can be combined with other layout methods like Flexbox for more complex designs. This can be particularly useful when you want to create a layout that is partially flexible and partially fixed.
Some best practices for using CSS Grid Retrofit include using named grid areas for easier layout management, using the fr unit for flexible grid tracks, and using Grid Inspector in your browser’s developer tools to visualize and debug your grid layouts.
CSS Grid Retrofit allows elements to overlap, which can be a powerful tool for creating unique layouts. You can control the stacking order of overlapping elements with the z-index property.
Yes, CSS Grid Retrofit is a two-dimensional system, meaning it can handle both columns and rows. This makes it a versatile tool for creating both horizontal and vertical layouts.
Some common challenges when working with CSS Grid Retrofit include dealing with browser compatibility issues, handling overlapping elements, and managing complex layouts with many grid areas. However, with practice and a good understanding of the grid properties, these challenges can be overcome.
The above is the detailed content of Redesigning a Site to Use CSS Grid Layout. For more information, please follow other related articles on the PHP Chinese website!