Page layout with CSS Grid

We haven’t talked about CSS much around here, but it has come up so much in my work at Yale that I thought I would write up a really short intro to something that is incredibly useful: CSS grid. Here goes.

What is CSS?

CSS (for “cascading style sheets”) is a standard that lets you change the default display of elements in an HTML document. You can do a million things with CSS — change typography, color, spacing, even animate stuff.

But the thing I want to tell you about here is layout.

Here’s the thing we will build:

image

Hilariously enough, in the olden tymes (like, in 2010) this layout was so freaking hard to make with CSS that it because known as “the holy grail”. I kid thee not, there is a Wikipedia article about it. I mean, do a million websites not have this layout? Yes, yes they do. Is it somewhat bonkers that it was so hard for so long to make this layout? Yes, yes it was.

I mean, like, even in language documentation a site with this general shape or something similar is going to be useful sooner or later. (Poke around the sites listed in the #web-documentation category and see for yourself.)

Klingon

For instance, let’s design a little faux-text browser for Klingon documentation:

This is a holy-grail-style layout. Amirite?

klingon-right

Well, that settles it.

Let’s see how to do this using CSS grid.

Let’s make a Holy Grail Layout with CSS Grid

Our Klingon site’s HTML might look like this:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Klingon Documentation</title>
  <style>
@import url(klingon-text.css); /* don’t worry about this, it’s for formatting the interlinears */
  </style>
</head>


<body>

  <header>
    <h1>Documentation of Klingon</h1>
  </header>

  <nav>
    <ul>
      <li><a href="#text-1">Text 1</a></li>
      <li><a href="#text-2"><mark>Text 2</mark></a></li>
      <li><a href="#text-3">Text 3</a></li>
    </ul>
  </nav>

  <main>
    <h2>Text 2</h2>

    <section id="text">
      <!-- klingon interlinear goes here-->
    </section>

  </main>

  <aside>
    <h3>Other stuff</h3>
  </aside>

  <footer>
    <p>Other stuff</p>
  </footer>


  <script src="clone-interlinear.js"></script> /* again, ignore this */
</body>

</html>

The <script> tag and the @import in the <style> are just putting that silly sample Klingon “text” in (with the same repeated sentence). We’re just interested in the high-level content here.

Without CSS

So, if we look at that page without doing any layout CSS, it just looks like this (check it out here):

Not a bad layout, but not a holy grail. We need to “lay out” the tags in this page into a holy grail. Okay, deep breath, here comes some Holy Grail CSS:

body {
   display: grid;
   gap: 1em;
   grid-template: 
     "banner     banner      banner    " auto
     "sidebar-1  content     sidebar-2 " 1fr
     "fine-print fine-print  fine-print" auto
 /    1fr       5fr     1fr; 
}

body header {  grid-area: banner; }
body nav {  grid-area: sidebar-1; }
body main {  grid-area: content; }
body aside {grid-area: sidebar-2; }
body footer {  grid-area: fine-print; }

And that gives us this (you’ll probably want to follow that link because the embed is going to get a little tweaked when it’s squeezed into this forum page):

Okay, line by line.

The first line display: grid; means “we’re going to set up a grid on the <body> tag.”

The second line gap: 1em means “put a gutter between the panels in the grid.”

We’ll come back to grid-template in a sec, but look at the five lines at the bottom. In that part, we’re saying, “go find the selected tags, and ‘move them’ in to the grid declared on their parent.” So for instance, the line

body header {  grid-area: banner; }

Means “go look inside the <body> tag, and find its <header> child. Then, put it inside the <body>’s grid cell which has been named banner.”

The other lines are doing the same thing: “place such and such a tag in such and such a ‘named area’ in the <body>’s grid”.

So it’s that complicated grid-template property that’s actually actually defining the <body> tag’s grid. The syntax takes some getting used to, so what I’m going to do here is just show you why you should care first, then we can talk a bit more about how it works.

Firefox has a nifty tool that helps a lot when you’re working on CSS grid layouts (more info here), and it will actually overlay area names onto the rendered page. Hopefully this will help you see how that complicated grid-template rule maps onto the actual document:

So here is a very different presentation of the document:

A few of the changes have nothing to do with CSS grid per se (I put a flex on the nav links and turned the <h1> vertical, for funsies). The key point here is that the HTML has not changed at all. This turns out to be a very powerful thing, because you can create a simple HTML document and change its display only in CSS.

The great thing grid-template is that it’s easy to drastically change the layout of document without changing the HTML at all. Here’s the Firefox tool again (I renamed one of the areas from sidebar-1 to nav, btw):

I’m going to wrap this up here, but there’s a lot more to say about layout with CSS grid. (I didn’t explain how the widths and heights of the columns and rows are set, for example.)

But I hope that the key benefit of grid-areas is apparent.

And grid isn’t limited to page-level layout — it could easily be adapted to render a complicated dictionary entry, for instance, something like this:

The fact that that’s even possible with CSS is amazing.

See also:

4 Likes

Ayyyyy, love me some CSS grid. The site I work for is one that, for its size, traffic and modernity, has a shockingly low number of instances of grid on it - less than ten, I think. (There’s a tooooon of flexbox, though. Normally I’d be a bit more CYA about company secrets or whatever, but all my work is meant to be seen by the public, so.)

I’ve been wondering for a while - for docling purposes, what browsers / devices is it good practice to support? The lazy developer in me wants to use features that make your code easier, but the accessibility-minded linguist in me wants to ask, who in the community is still using, like, Internet Explorer 6, or other browsers that don’t support certain modern features?

I realize that this of course depends on who the community actually is, and I figure that evergreen browsers help you a lot here. (CSS grid itself seems to be supported for 96% of global users, fwiw, but who cares about global percentages when you have a target community in mind?)

Anecdotally, I’ve seen some community members using Internet Explorer (11, I think), but this was before the push to get everyone on Edge, so now I truly have no idea.

2 Likes

Hi Adam!

An excellent question. The short answer is, I’m not sure.

Right. I think it depends a lot on what exactly is being delivered. As you point out, CSS Grid looks good, but something like Container Queries is still coming. The good news is, though, things seem to spread much faster these days. I can remember waiting for ages for Flexbox to spread everywhere.

The Date Relative view on caniuse is quite interesting in this regard:

Indexeddb took years to spread, with browsers only slowly coming to support it:

But the brand new Container Queries is already available almost universally — and it came about really quick:

The emergence of evergreen browsers has really changed everything from where I sit. I feel like Internet Explorer is pretty much out of the picture. But it is true that upgrading requires connectivity, and in many places that is limited. Still, are many machines from circa 2008 when the first evergreen browsers came out still running? Maybe, I guess, but I feel like most systems running browsers now are going to have been bought with a browser that automatically upgrades.

Honestly, I feel like the upgrade story with browsers in general is way better than most software. We’re still upgrading ELAN, Flex, Praat, etc, by hand, while that has ceased to be necessary with browsers for years.

Yikes, I’m rambling on. OH WELL :grimacing: (interesting topic :D)

So as for which CSS / JS / HTML technologies I personally use, my rule of thumb is that it has to be available in two standard browsers on Windows/Mac/Linux. Chrome usually takes care of one of those two, and between Safari and Firefox you can usually get to the point where people at least have a choice of browser. I would never put something out there that requires, say, a nightly build.

One final thought is that there’s quite a difference between building a static document like an interlinear text that requires a few inline-grids and an application interface that records audio and stores a corpus in indexeddb. Basic static documents are universally reliable, app-style stuff is becoming more and more reliable as well.

Thanks for your comment! Please feel free to share your CSS and other expertise with the other local heros!

1 Like

abut the 96% support question - maybe the way to think about it is who are the 4% and are they likely to be docling/grid users?

1 Like

One tricky thing is that even within a library like docling there will be varying degrees of “newness” in terms of what’s required — one component may require something quite new, another may be all old APIs.

That said, I’ve tried to find a common ground between being conservative and taking advantage of things that are useful. My rule of thumb has been “it has to be available on at least two browsers on Mac/Linux/Windows”. That way people at least have a choice.

There could very well be communities where browsers are in use but connectivity is such that automatic upgrades (now standard) can’t really happen. That would definitely require adjustment. But even there the definition of “user” can be variable. Maybe for a project in a community with extremely limited connectivity or even no electricity, print would be the only viable target medium. In such a case, a documentation team might focus on the print capabilities of CSS (which while considerable are themselves not completely implemented) to create materials.

I feel like it’s hard to generalize about this long tail of users. The people who know best about particular situations are community members and their collaborators.

It can be frustrating that adding support for that last slice of potential users imposes increasing demands on the development process, and given that in documentation we don’t have the power, widespread expertise, or staff of a big corporation, sometimes the resources just aren’t there.

2 Likes