Skip to content
Daniel Shaw · WordPress & WooCommerce Developer Wellington, New Zealand

👋 Not available for new client work right now!

Every Layout is a salve

There are a few people I return to often for their clarity of intent and empathy for the long-suffering end user. Each of these people have influenced how I prepare content for a web browser: Rob Weychert for amazing design-led code exploration; Zach Leatherman for font research; Heydon Pickering for his thinking on accessibility and general sensibility.

That last guy1 has easily had the most enduring impact on how I manage presentation with CSS, via a stupidly simple—the best kind of stupid—but powerful idea: the lobotomized owl. He's recently launched Every Layout, a resource to help “relearn CSS layout”. There's only a few topics available to read right now, but what I've seen so far serves as a timely antidote to discussions around CSS that have been painful to follow in recent years.

CSS is not “broken”

Or, at least, it's only as broken as every single system in existence when viewed through a frame of either original sin or a future utopia. CSS's global state does not need to be an issue when structured with an appreciation for the big C. When the majority of the URLs on the web still resolve as websites that embrace the static-document-as-a-web-page model, it seems wise to understand and work with the available tool instead of developing all new tools with all new problems. Very few people are actually building rockets and rocket science does not need to be applied to this situation.

The Stack” discusses the * + * selector, or, how to manage elements' relationships with each other in a document's vertical flow. This really hits on one of the main tasks when developing for the front-end: taking a set of components and describing rules to govern those components, irrespective of their ultimate relationships not being known. It's no Skynet, but there is a level of faux self-awareness being created here. What really delights and amazes is how cleanly this approach solves two quite different use-cases: developer-controlled templates and user-generated content managed via CMS.

Back to the Stack: “the trick is to style the context, not the individual element(s). The Stack layout primitive injects margin between elements via their common parent”:

.stack > * + * { margin-top: 1.5rem; }

This is a best friend of intentionality! Gain confidence and influence as you exert uniform control on the vertical flow of content!

Managing nested variants

It's rare all elements can be managed with a single margin value. The Stack approach addresses this with the suggestion to “set up alternative non-recursive Stacks with different margin values, and nest them where suitable.” The suggested approach looks like this:

[class^='stack'] > * { margin: 0; } .stack--small > * + * { margin-top: 1.5rem; } .stack--large > * + * { margin-top: 3rem; }

My experience has been it's not too helpful to use alternative wrapper classes to manage variations, and I choose to assign more explicit over-rides:

/* No wrapper class available. */ .stack h2, .stack h3 { margin-top: 3rem; } /* Wrapper class inserted by a 3rd-party. */ .stack .wp-block-quote { margin-top: 3rem; }

This ignores the context and targets the element, which—OMG—goes against the entire concept of the Stack. In practice, I've found this to be a happy trade-off for elements where a wrapper class cannot be controlled (user-generated content via a CMS) or a known wrapper class will be injected by a 3rd-party (say, the “block” divs WordPress now wraps around some elements).

Hmmm, Firefox…

The following markup displays oddly in Firefox when the * + * selector is used recursively:

<style> .stack * + * { margin-top: 1.5rem; } </style> <div class="stack"> <p>c/o Cecil & Minerva<br> Owhiro Bay<br> Wellington 6023<br> New Zealand</p> </div>

In Firefox this results in a margin being applied to the <br> element: see a demonstration of this issue on Codepen (must be viewed in Firefox).

When first using this selector, I noticed random paragraphs with forced line-breaks were being spaced oddly in Firefox: some lines were displaying with an upper margin applied, generating unintentional white-space. Eventually I realised the <br> element was also inheriting the margin.

The solution is simple:

/* Prevent margin being added to <br> in Firefox. */ .stack br { margin-top: 0; }
  1. Yup, I acknowledge this list is Dude Fest 2019.