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.)
Problems
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.