Skip to Content

Changelog: Links

Conjuring a Web 1.0 staple

The thing I miss most about the web before social media was everyone having their own blog or personal site. It was decentralized and punk.

The URL made it all work. One inbound link and you were in. And every outbound link made it stronger. So we all linked to our friends and favorites to include, inform, and pay respect. We called them blogrolls.

Let’s unpack some teachable moments that I encountered while implementing my links page.

DRY and accessible labels

A constant goal of mine is writing less code without sacrificing core principles like clarity or accessibility.

The blogroll component is semantically a list of lists. Each list has a label, but that’s not important enough to warrant a heading. It turns out that we don’t need complicated markup to express this:

Figure 1: Abridged HTML of the blogroll component
<div class="io-c-blogroll">
  <ul aria-label="Worst Presidents">
    <li><a href="#">Donald Trump</a><li>

When the link is focused, a screen reader might announce: Donald Trump, Link, List Item, Worst Presidents. But the aria-label attribute isn’t visually accessible on its own.

With a ::before pseudo-element we can dynamically insert content as the first child of an element. So we leverage the attr() CSS function to display our aria-label for sighted users:

Figure 2: Abridged CSS of the blogroll component
.io-c-blogroll ul::before {
  content: attr(aria-label);

The best part: pseudo-elements aren’t included within the accessibility tree, so the labels aren’t announced twice!

Negative margins to the rescue

Lately I’ve become more trusting of negative margins to solve complex layout problems. They don’t always make intuitive sense. So I like to frame it as undoing another element’s positive margins; using them purposefully reduces their cognitive load.

Typically they’re helpful when implementing layouts with evenly-spaced items. Our first instinct may be to add margins around each item:

Figure 3: Initial solution

That’s great! But what if we want the children to align to the edges of their container? By setting negative margins on the container, we can undo the outermost margins of its children:

Figure 4: Revised solution with negative margins

Putting it all together, here are the rules that define the list gutters:

Figure 5: Abridged CSS of the blogroll component
.io-c-blogroll {
  margin: -1em -2em;
.io-c-blogroll ul {
  margin: 1em 2em;

Eventually I’d like to expand my links page to include a microblog where I can share links more extemporaneously. Like an article that resonated with me but doesn’t warrant a full post. That’s a change for another day.