CSS Grid is great for a modular design approach — each page section is done in a dedicated (grid) container. This makes it easy to move the sections around, reuse them in different pages, or incorporate a real design case (instead of an gif animation) in the middle of an article.
This is also how we are implementing the redesign of the CoffeeCup home page. Following idea generation and sketching, we are prototyping and polishing the design in CSS Grid Builder. The latest 'New Home prototype. can be found on new-home.coffeecup.com.
With sometimes some minor tweaks for IE11 support, this code is then ported to our code base. Steadily —on a section by section basis— 'Grid' will replace our current responsive layout framework.
We are documenting the process as we go, making short movies and write ups (including code examples) of our voyage to a new home. We are starting off the educational series with the article about the design of a new 'hero section'.
In the showcase below I created a responsive hero section using three text elements and three images. The 'stacked' image effect is done with CSS Grid.
Why 3 images instead of a single image stitched together in a graphics editor? I prefer the amount of control and flexibility it allows for — this way positioning and sizing tweaks can be made for different screen widths. Also, as you can see at the end of the video (and when the example below comes into view or is loaded), it allows for adding cool animations!
In the 'action section' that follows I am not using display: grid. Part of learning new techniques is also learning when not to use them... So yea, we will also be using other layout techniques like flexbox and positionings as we go.
Have a good look at the hero showcase below before we are going to set up the HTML structure and apply some styling.
To create the full-width gradient, I need a container that stretches the full page. The content within it is constrained and centered, this is done with another container — the 'inner-hero' so to speak. Since this container will have the actual content, this is where I am going to use the main grid for the hero section.
The three text elements are kept together in container, the 'hero-text-wrapper'. The three images are inserted below this container, leading to an element structure that looks something like the below.
We are here to marvel at the powers of CSS Grid, so let's jump right to the matter. How the other styles are set, the background gradient, font sizes and so on, can be seen in the short video towards the end pf this article.
The first thing we need to do is to create the grid context. This is done by setting the display property of the .hero-grid selector to grid. This will make the 4 elements inside of the grid parent container behave as grid-items — they will now automatically position themselves in the cells of the grid.
The cells are defined by the intersecting rows and columns — just like a spreadsheet. Starting with the mobile view, we need 4 cells stacked below eachother. Defining rows and columns can be done by writing out the grid-template-row and column properties, followed by the size values for each of the rows or columns, separated by a space.
The first 3 declarations, starting with the display property in the code block block below correspond to this grid setup. After making the container a grid, a single column with an auto width is defined.
The CSS Grid syntax is very flexible and versatile — there are various ways columns, rows and the entire grid can be created. To learn more about the syntax options I recommend using our CSS Grid Guide.
In this case I am creating the 4 rows by placing 4 height values behind the grid-template-rows property. This creates 4 rows with height values of auto 80px 80px auto respectively.
This structure is visualized in the screenshot of the Grid Editor dialog of CSS Grid Builder below.
The margin declarations (in the above code block still) are used to center the inner content container — the width restriction creates the space on the sides so the gradient is visible up to the bottom of the section.
Overall that tiny bit of layout code creates the following structure for screens below 1024px:
It is a great example of the power and flexibility of CSS Grid. With a spiffy looking mobile view it's time to start making adjustments for wider screens.
I am keeping the stacked structure until the viewport becomes wider than 1024px. At that point it is nice to take advantage of the horizontal space and place the images next to each other.
The plan is to place the app screenshot that sits in front in the mobile view BIG in the middle at larger viewport widths. The other 2 images will be on the left and right, partially disappearing behind the central image. Therefore we will need 4 columns: 2 big ones in the middle and 2 smaller ones on the left and right.
Here we only need 2 rows, one for the header text container and one for the images. The screenshot image can then be placed in the resulting 2 big cells in the second row. The other images will be placed in 1 small and 1 big cell. That should be enough to create the effect we see in the image below:
The first step here is to redefine the grid at the breakpoint. To do this we wrap the same .hero-grid selector in a media query and tell the browser what the grid should be like as of that point. Only a few lines of code are needed to pull this off — if you know what you're doing that is...
The repeat syntax and fr unit are two examples of the many cool things CSS Grid has made available to us. Using the repeat keyword a certain number of the same columns (or rows) can be created. In this case I am first creating a column that takes up 20% of the available width. Then, using repeat, I am specifying 2 columns — each of these 2 columns gets a width size of 1fr. Just as the first column, the last columns gets a width of 20%.
How the fr unit works: the fr value assigns a fraction of the remaining available space. In our case that means that the browser begins by assigning the 20% to the first and last column. From the space that is remaining, any width that has not been defined, each of the middle columns get 1 fraction (out of 2 fractions total). The resulting grid setup is visualized in the screenshot below:
As can be seen in the video below, initially this redefined layout will create a mess... Unless specifically told where to go, the elements will automatically rush to the first available grid cell and try to be comfortable there. This can be very handy, but not for our design.
In our case they will all try to cram into the 4 (too small) grid cells in the first row. So, let's just tell our content elements where to go! Here's the code that will do exactly that:
CSS Grid offers various techniques and gives a number of syntax options for placing elements. For those interested in details, our CSS Grid Guide dedicates a whole chapter to placing grid-items.
Because we are working with overlapping grid-items, I opted for the line-based placement method. There are a couple different ways of doing this but eventually they all come down to the same thing: instructing the elements to 'go sit' between horizontal and vertical grid lines.
Just to be clear, we are talking lines here, not columns or rows. These lines start with the first grid-track — columns and rows are grid-tracks — and end at the last one. Therefore, a (our) grid with 4 columns, has 5 grid lines. And a (our) grid with 2 rows, has 3 grid lines. The image below illustrates this concept for the columns. The column width settings have been added to the image as well.
Now we know that grid-items are placed in between those lines, the code in the previous block starts making total sense. The 3 images share the .hero-image selector, which places them between column grid line 2 and 4 and row grid line 2 and 3.
This position is then changed for 2 of the images. The .middle selector (which does make little semantical sense now since it is used to place the image on the right, I should have done a better job there...) overrides the column line placement of the shared .hero-image selector and positions the image between line 3 and 5. In a similar manner the third image is placed between line 1 and 3.
The text box, the container with the 3 heading elements and selector .hero-text-wrapper, is placed accross all columns in the first row.
Who sits on top when elements overlap? The app screenshot is placed above the other 2 images. In our case that automatically happened because of it's position in the DOM Tree — when elements have the same positioning rules, elements that are added later will overlap elements that were added earlier. This can be controlled with the z-index property, a higher z-index value will bring an element in front of an element with a lower value.
The text box, the container with the 3 heading elements and selector .hero-text-wrapper, is placed across all columns in the first row.
That wraps up the layout design and element placement using CSS Grid. Clearly there's a bit more to this design — it uses a background gradient, various font styles, and transition effects. The video below shows the entire design process, including the layout creation and responsifying, in under 15 minutes. Please sit back and listen to Suzanne explain how this was put together in CSS Grid Builder. If you would like to try this for yourself with the app, it is available for free right here.
There we have it, unfortunately browser support is still a 'thing'. However, with the recent (October 2017) release of Edge 16, all major browsers now offer full support for CSS Grid. So the way forward is looking bright for CSS Grid based layouts, but what to do in the meantime?
One of the options is to do nothing, here's why. Browsers that do not support certain CSS properties, will simply ignore them. That basically means all the content will still be displayed and be accessible. However, the elements won't be as neatly positioned as they will be for the great majority of people that are browsing the web with a modern browser.
Let's think about this a little, why are people using browsers that deliver a sub-optimal browsing experience in the first place? There are probably quite a few that don't realize they are held back by their browser. But the main reason here seems to be that they simply can't — system (hardware or OS) restrictions, company policies or a combination prevent people from taking the leap.
Then the next question is, is it worth the extra effort to improve their experience? Remember, they should be able to view and access the content anyway, in most cases it just won't look as good, in some cases it might actually look bad. I am going to take a bit of a controversial position here and say "looking at the current browser stats it is probably a wise decision to make sure it looks decent at the very minimum for most businesses, but for some this is debatable".
Looking at CoffeeCup, creator of modern web design tools, it might not make economical sense to do so. Would someone using IE11 want to buy our tools to create a modern responsive website? If they would take the jump and starting to create modern sites, this would require a lot of hand holding on our part....which we do a lot and is actually a fun part of it. But there is a limit to it, ultimately we are app creators and spending our time educating is time we can't spend on improving our web design tools.
Another example, somebody selling kids toys or electronics online. People that are not aware of using an old browser, are they likely to buy online? People restricted to using an old browser, are they likely to convert? I would say that the conversion ratios are probably lower, but it is likely worth the time and resources to create a good enough experience for them as well.
One more example, a (blog) site making money from ads by providing information for some niche? Most of the time the compensation is based upon the number of view or visits, so every browser counts. Here it makes economically most sense to make sure everybody gets a good experience and comes back to increase the count.
Conclusion: it makes sense to provide visitors without grid support with a decent to good, but not necessarily equal, browsing experience. And for CoffeeCup? A big part of the reasoning here would be that it makes me feel good.
The way to do this is using feature queries. What they are, how they work and what needs to happen to our design case is explained in Feature Queries for CSS Grid.
If you enjoyed this article, you should give that one a read too!