CSS sidebar proposal

This post suggests we change the sidebars we have for our CSS documentation. Our CSS sidebar system is complex, fragile, has a fairly big maintenance burden, and generally produces poor sidebars.

How our CSS sidebars work

(First it’s worth saying that our system leans heavily on the idea that we can usefully split CSS language items into groups of related functionality. Usually, but not always, these correspond to CSS Modules, which also correspond (I believe) to CSS specifications. For example, CSS Fonts.)

Our CSS sidebars are built using the CSSRef macro.

First, this macro does some work to try to figure out what sort of page it’s looking at, one of:

  • a property,
  • an at-rule,
  • a type,
  • a selector,
  • an “overview page” (this is a page giving an overview of a particular CSS module, like CSS Fonts)

It does this by applying some heuristics to the page slug or, in the case of selectors, by looking at the page tag. For example:

function isType(foo) {
  return foo.indexOf('<') !== -1 && foo.indexOf('>') !== -1;

var isOverviewPage = slug.indexOf("_") !== -1 && !isType(title);

Next, it looks for the “groups” that this item belongs to. If the page looked like an overview page, then the slug is used as a group name (converted, so “CSS_Fonts” -> “CSS Fonts”). Otherwise, it loads up the content of the mdn/data repo, and looks up all the groups associated with this item. For almost all properties, there’s only one group, which corresponds to the CSS module it’s defined in. So for instance, if our page was font-family, then the group would be CSS Fonts.

Next, for each group found, it gets all the CSS properties, at-rules, etc in that group. So in our example it would find all the other font properties. It fetches links to all these things, and adds them to the sidebar.

It also constructs a slug from each group name (so “CSS Fonts” -> “CSS_Fonts”), and adds that link to the sidebar, and finds any subpages of that page, and adds them to the sidebar, expecting them to be guide pages relevant to that group.

Finally, it always adds links to the top-level CSS and CSS Reference pages.

So the result of all this is that, in a happy case, a CSS page gets a sidebar showing guides and reference material specifically related to the group(s) that an item belongs to. So for example, that font-family page has links to a couple of font-related guides, and some at-rules and properties related to fonts.

(n.b. all the above does not apply to selector pages. It does something completely different for selectors, I won’t go into that though.)


The first problem is that this is a complex system with lots of moving parts. It includes:

  • a fair chunk of quite complex KumaScript code
  • several JSON files in a separate Git repo (mdn/data)
  • document slugs
  • document tags

All these things have to work together properly for the system to work. It makes various assumptions which are not well-understood and often fail in practice: for example, that a page whose slug contains underscores, that doesn’t start with < and end with >, must be a group overview page (cf Compositing and Blending, which isn’t).

It’s an effort to maintain: writers have to keep mdn/data updated for sidebars to work properly. The rules are very subtle and when they are not exactly followed, weird things happen.

But I think a bigger problem is that the results are often poor. Even in a happy case like font-family, the design assumes that someone looking at a property is most likely to want to navigate to another property in the same group. But it seems quite likely that they will want to navigate to a different group. For example, it seems equally likely that a user looking at font-family wants to see the page for color next - well, how do they get there? The quickest way, I think, is to click the CSS Reference link, then find color in the huge list half-way down that page. This is not a usable answer.

But that’s a good case. The split of items among CSS modules often isn’t one that will make much sense to users, and many sidebars are very small and don’t include clear links to items that would seem to be quite closely related.

In many cases, where a page doesn’t match a group at all, the sidebar is totally vestigial (e.g. Specificity, Shorthand properties, or even the main CSS page). All that work, and (essentially) no sidebar at all!

Also, the sidebar doesn’t acknowledge the existence of the Learn area at all.

I’d also like us to consider a general principle, which is that sidebars should contain the same content for all pages in a given area of the site. With CSS, the sidebar usually completely changes its contents whenever you navigate from one property to another, and I think this makes it very hard to users to learn how to use the sidebar to find things, or even to see these docs as a coherent body at all.

So what should we do?

I think we should design a single sidebar for our CSS docs. I think it should have an outline something like this:

* Learn CSS      // one item under here, for each LA module
    * CSS first steps
    * ...
* Guides         // one item under here for each "overview page"
    * CSS Fonts  // under here, guide pages under /docs/Web/CSS/CSS_Fonts
    * ...
* Reference
    * Properties // under here, all CSS properties in an alpha list
    * Selectors  // under here, all CSS selectors and pseudo-classes, etc, in an alpha list
    * At-rules   // under here, all CSS at-rules in an alpha list
    * Types      // under here, all CSS types in an alpha list

I think we should use tags only as a way to build this. So we should break the dependency on mdn/data entirely.


So… I’m torn on this. I like the idea of simplifying things, very much. However, I also really like the idea of having links to potentially relevant content given the context of the page you’re on.

Perhaps in addition to the standard outline you propose we could have at the bottom a “These might interest you…” type of list constructed based on the page you’re looking at? This could be generated automatically and could even potentially be appended to the sidebar after the rest of the page is loaded, to allow it to be constructed out of band from the rest of the page load, to speed things up.

1 Like

The thing is, mdn‑data is also being used by other projects.

Unfortunately, the API portion of it is woefully out of date from the API data in the KumaScript repository.

And the remaining *Data.json files haven’t yet been migrated over.

By completing the migration outlined in mdn/sprints#1695, it’d be possible to use mdn‑data in StumpTown as well.

It is, but I’m not sure how that affects any of these points.

One of the issues with CSS sidebars has been the fact that CSS has become very modular so there are a few specs which contain properties that a web developer would assume actually belong to another spec, Box Alignment is the source of many of these. For example, if I’m reading CSS Grid docs, I would assume that gap, row-gap and column-gap would be grid properties. However they are Box Align properties, and so “live” under the Box Align spec.

It makes sense our structure mirrors the spec structure, however from a developer point of view, when they look at grid, they want to find all of the properties they can use when creating a grid, aligning items and content, and so on.

However we can’t just stick all the alignment properties (for example) into every spec that uses them, as not all properties apply to every spec. For example in flexbox you can use all of the alignment properties except justify-self as items on the main axis are dealt with as a group.

Maybe this isn’t a sidebar thing, but I think it shows how the way we (and specs) structure things is adrift from how a web developer might be thinking about these things. So I wanted to bring these scenarios up.

Otherwise I’d be very happy to simplify sidebars!

1 Like

+1 for a reader-centered design of sidebars. Short of that, @wbamberg’s proposal at least makes it easier than the current design, for readers to find what they’re looking for.

1 Like

Yes, I agree that the division of properties among the specs doesn’t always match the division a web developer might make, which is reasonable since they are different audiences.

We might try to invent a different organizing system for MDN (maybe with bigger groupings, so Grid and Flex and Box-Align properties could all be grouped together). I think this would be harder than I just made it sound.

Also, fundamentally we’d run into the same problem: that we are assuming that a developer looking at page X will want to look at pages Y and Z next, and not pages A or B. And sometimes that assumption will be wrong.

It’s also OK for the assumption to be wrong as long as we don’t fail too badly in that case: that is, as long as there’s a reasonable route for the user to get to pages A or B. But at the moment, in our sidebar, there isn’t.

So for now I’d like us to try something much simpler to implement and maintain, which is better than what we have now, without waiting for the perfect solution.

Thanks for your feedback @rachelandrew, it’s much appreciated. Since you’ve been mostly looking after the CSS docs recently, I wanted to be sure you weren’t horrified by the suggestion :).

1 Like