It turns out that CSS Grid is pretty good at laying out online comics, especially if you want your comics to be flexible. In this tutorial we’ll use Barry the cat to demonstrate how to build a responsive comic.
Barry the Cat
For this tutorial I’ve borrowed some artwork from GraphicRiver; Sleepy Fat Cat is actually a display typeface, but comes packed with some lovely cat vectors–perfect for this comic demo!
Get Your Browser up to Speed
Don’t forget, you’ll need cutting edge browser features to see CSS Grid in action, so read through CSS Grid Layout: A Quick Start Guide if you’re using a non-supporting browser. Here’s what we’re working towards:
Check out the full demo on CodePen to see it respond to different screen sizes.
1. Markup
Let’s begin by laying out some HTML:
<section class="grid-1"><div class="panel panel-title"><h1>Barry’s Cushion</h2><p>A tale of lethargy and soft furnishings</p></div><div class="panel panel-1"></div><div class="panel panel-2"></div><div class="panel panel-3"><p>“I should probably get up–things to do.”</p></div><div class="panel panel-4"></div><div class="panel panel-5"></div><div class="panel panel-6"></div><div class="panel panel-7"><p>“Naaah.”</p></div><div class="panel panel-8"></div><div class="panel panel-9"></div><div class="panel panel-copyright"><p>Sleepy Fat Cat by messenj4h<br>© Copyright happily ever after <a href="https://webdesign.tutsplus.com">Envato Tuts+</a></div></section>
Here we have a <section>
to act as our grid, with a load of <div class="panel">
elements to be our grid items.
A couple of panels have text in them, but the rest will be for our comic images. We have two options here: we can either place our images inline within the panels, or add images through CSS. I’m doing the latter because it affords easier control over the placement and sizing of the graphics, but you could argue that inline images would be more accessible. Your choice.
2. Basic Styles
To get the (fur) ball rolling, let’s add some styles to cover our typography and colors:
/* basics */ body { background: #f8f7f2; padding: 0 10%; font: 100%/1.5 'Kalam', cursive; } h1 { margin: 0; line-height: 1; padding: 10px; color: #251b19; } p { margin: 0; padding: 10px; color: #251b19; font-size: 1.2em; a { color: #e56633; } a:hover { text-decoration: none; }
I’ve chosen Kalam as the Google web font for our text–its handwritten style is perfect for comics I reckon. You’ll need to hook it up in your CSS or via a link in your document head:
<link href="https://fonts.googleapis.com/css?family=Kalam" rel="stylesheet">

3. Our Grid
Starting mobile first, we’ll lay things out in one column with a single panel on each row:
.grid-1 { display: grid; width: 100%; max-width: 770px; margin: 10% auto; grid-template-columns: 1fr; grid-template-rows: auto 200px 200px auto 200px 200px 200px auto 200px 200px auto; grid-gap: 25px; }
Looking back to our earlier Grid tutorials you’ll recall that grid-template-columns
assigns how many columns we’ll have, and how wide they’ll be. grid-template-rows
does the same for rows; here we’re defining eleven of them. The ones containing images will be 200px high, the ones with text will size automatically according to the content. Finally, grid-gap
defines our gutter size.
Let’s now add some general styles to our panels:
.panel { color: white; background-repeat: no-repeat; background-position: center center; background-size: cover; box-shadow: 0px 0px 0px 5px #251b19; }
The background
properties don’t have any visual impact just yet, but they will just as soon as we add some background images. And the box-shadow
acts as a border. You can also use traditional border
properties here if you prefer, but box-shadow sometimes gives more flexibility.
Let’s see what we have so far!
4. Cat Pictures
What the internet was made for, right? I’ve prepared a few SVG images to add to the panels, which I do one by one:
.panel-1 { background-image: url(cat-1.svg); }
Looking good!
But I don’t want borders around all the panels. I’ll remove them (using box-shadow: none;
) from those containing text, along with the first image, and the final image.
5. Media Queries
These images aren’t working perfectly yet; poor old Barry’s getting some serious cropping. It’s time to look beyond mobile and alter our grid for larger viewports. Let’s add some media queries; one at 400px and one at 600px (arbitrary figures, use whatever you want):
/* media query 1 */ @media only screen and (min-width: 400px) { } /* media query 2 */ @media only screen and (min-width: 600px) { }
We’ll use them to alter the grid layout in each case.
/* media query 1 */ @media only screen and (min-width: 400px) { .grid-1 { grid-template-columns: repeat(2, 1fr); grid-template-rows: auto 200px auto 200px 200px auto 200px auto; } } /* media query 2 */ @media only screen and (min-width: 600px) { .grid-1 { grid-template-columns: repeat(3, 1fr); grid-template-rows: auto 200px 200px 200px auto; } }
We’re going for two columns and eight rows for slightly larger screens, then three columns and five rows for even larger.
Spanning
Now we’ve burst out from our single column constraints we can be a bit more creative. We need, for example, our title to run along the width of the whole comic. The same is true of the panels containing text, and the copyright statement. Even some of the images would be better served in full-width panels. So we’ll add those details to the first of our media queries:
.panel-title, .panel-3, .panel-6, .panel-7, .panel-copyright { grid-column: span 2; }
I’ve changed the typography in a couple of cases too, in the end giving us:

Our two column layout looks great! However, our three column comic needs fixing.

6. Fixing Our Three Column Layout
As we’re working mobile first, the rules we applied to our first media query are still taking effect on the largest of screens. We need to work our way through the panels and reset some styles.
Begin by making the .panel-title
span three columns, instead of just two. Then .panel-3
(with the text) can be set back to grid-column: span 1;
or grid-column: auto;
The same applies to .panel-6
. With a couple more changes you should end up with something like this:
A Wee Bit of Flexbox
I’d like the first bit of dialogue to be vertically centered, so let’s use flexbox to do that. Add the following to the second media query:
.panel-3 { display: flex; align-items: center; }

7. Overlaying Panels
Grid doesn’t restrict us to equidistant blocks running along and down a page, we can happily layer our panels too. We’re going to make our final bit of text a bit more interesting by assigning it to the same grid location as the next panel:
.panel-7 { grid-column: 1; grid-row: 4; z-index: 1; } .panel-8 { grid-column: 1 / span 2; grid-row: 4; }
Here, we’ve positioned both .panel-7
and.panel-8
to grid-column: 1;
and grid-row: 4;
. That means that they’re both in exactly the same place, with whichever appears second in the DOM being stacked on top of the first.
We can use z-index to alter the stacking order, so giving .panel-7
a z-index: 1;
brings it to the top:

Note: now that we’ve effectively removed a row, you’ll need to check your grid-template-rows
are ok.
Let’s add a bit more style to our “Naaah”. Again, grid items aren’t restricted as much as you might think–we can shift them with negative margins and even transform them without any problem. I’ve added some styles to the panel and the paragraph within it to give this:

Conclusion
Well done–here’s what we’ve built!
This was a fun exercise in using CSS Grid, whilst introducing you to some new Grid concepts along the way. I hope you enjoyed it–now if you don’t mind I’m off for a nap.
Further Reading
- Understanding CSS Grid Layout beginner’s series
- Sleepy Fat Cat Typeface on GraphicRiver
- The Mechanics of Comics
- Understanding Comics by Scott McCloud