An odd page layout (using CSS first-of-kind, last-of-kind, and nth-of-kind selectors)

Consider the following layout for a page with a collection of articles:

article layout idea idea

It’s a fairly common structure and really good for emphorsizing the lead story. I set about trying to create that layout as a theme for a FactMint infographic. As it was a theme, I couldn’t add any additional classes to the HTML (and would rather not anyway). I started from this criteria:

The first article must be full width and all others half width.

That can be accomplished using the CSS selector

section article:first-of-kind

or similarly using the :first-child pseudo class.

Although the criteria is fulfilled, there is problem. Take the case where there are two articles:

article layout problem 1

Looks a little unbalanced, at best. So, what’s the solution? Well, one could make the last article full width, too. That is accomplished using a selector like:

section article:list-of-kind.

The issue with that approach is fairly clear, it just moves the problem onto the cases where there are an odd number of articles; the penultimate article will, then, be solitary and half-width:

article layout problem 2

Logically, the general solution is easy to describe: make the last article full width only in the cases where there are an even number of blocks. The question is, how would one accompish that?

I’ve seen this problem resolved in the past by adding conditionally adding a class (say, .full-width) to the last article, subject to there being an even number of articles. That could be implemented using a templating engine or just code. The solution has its merits – it’s pretty easy to understand, for one thing, which is a big pro. It is, however, not a semantic class; even if you were to call the class last-component, while it would be semantic, the fact that it is conditional would nullify its sentiment.

Here’s the solution I came up with. It is dependent upon the precedence of four CSS rules, implemented by their order in the stylesheet. Namely:

  1. All articles are half width
  2. The last article is full width
  3. All odd articles are half width
  4. The first article is full width

So, the first article is always full width, as it’s the last (highest precedence) rule and the last article is full width unless it is odd (as the odd rule overrides the last rule).

Here’s a jsfiddle to illustrate. Play around with the number of articles in the section.

Leave a Reply

Your email address will not be published. Required fields are marked *