CSS snippets

I’ve been thinking about the kind of CSS I write by default when I start a new project.

Some of it is habitual. I now use logical properties automatically. It took me a while to rewire my brain, but now seeing left or top in a style sheet looks wrong to me.

When I mentioned this recently, I had some pushback from people wondering why you’d bother using logical properites if you never planned to translate the website into a language with a different writing system. I pointed out that even if you don’t plan to translate a web page, a user may still choose to. Using logical properties helps them. From that perspective, it’s kind of like using user preference queries.

That’s something else I use by default now. If I’ve got any animations or transitions in my CSS, I wrap them in prefers-reduced-motion: no-preference query.

For instance, I’m a huge fan of view transitions and I enable them by default on every new project, but I do it like this:

@media (prefers-reduced-motion: no-preference) {
  @view-transition {
    navigation: auto;
  }
}

I’ll usually have a prefers-color-scheme query for dark mode too. This is often quite straightforward if I’m using custom properties for colours, something else I’m doing habitually. And now I’m starting to use OKLCH for those colours, even if they start as hexadecimal values.

Custom properties are something else I reach for a lot, though I try to avoid premature optimisation. Generally I wait until I spot a value I’m using more than two or three times in a stylesheet; then I convert it to a custom property.

I make full use of clamp() for text sizing. Sometimes I’ll just set a fluid width on the html element and then size everything else with ems or rems. More often, I’ll use Utopia to flow between different type scales.

Okay, those are all features of CSS—logical properties, preference queries, view transitions, custom properties, fluid type—but what about actual snippets of CSS that I re-use from project to project?

I’m not talking about a CSS reset, which usually involves zeroing out the initial values provided by the browser. I’m talking about tiny little enhancements just one level up from those user-agent styles.

Here’s one I picked up from Eric that I apply to the figcaption element:

figcaption {
  max-inline-size: max-content;
  margin-inline: auto;
}

That will centre-align the text until it wraps onto more than one line, at which point it’s no longer centred. Neat!

Here’s another one I start with on every project:

a:focus-visible {
  outline-offset: 0.25em;
  outline-width: 0.25em;
  outline-color: currentColor;
}

That puts a nice chunky focus ring on links when they’re tabbed to. Personally, I like having the focus ring relative to the font size of the link but I know other people prefer to use a pixel size. You do you. Using the currentColor of the focused is usually a good starting point, thought I might end up over-riding this with a different hightlight colour.

Then there’s typography. Rich has a veritable cornucopia of starting styles you can use to improve typography in CSS.

Something I’m reaching for now is the text-wrap property with its new values of pretty and balance:

ul,ol,dl,dt,dd,p,figure,blockquote {
  hanging-punctuation: first last;
  text-wrap: pretty;
}

And maybe this for headings, if they’re being centred:

h1,h2,h3,h4,h5,h6 {
  text-align: center;
  text-wrap: balance;
}

All of these little snippets should be easily over-writable so I tend to wrap them in a :where() selector to reduce their specificity:

:where(figcaption) {
  max-inline-size: max-content;
  margin-inline: auto;
}
:where(a:focus-visible) {
  outline-offset: 0.25em;
  outline-width: 0.25em;
  outline-color: currentColor;
}
:where(ul,ol,dl,dt,dd,p,figure,blockquote) {
  hanging-punctuation: first last;
  text-wrap: pretty;
}

But if I really want them to be easily over-writable, then the galaxy-brain move would be to put them in their own cascade layer. That’s what Manu does with his CSS boilerplate:

@layer core, third-party, components, utility;

Then I could put those snippets in the core layer, making sure they could be overwritten by the CSS in any of the other layers:

@layer core {
  figcaption {
    max-inline-size: max-content;
    margin-inline: auto;
  }
  a:focus-visible {
    outline-offset: 0.25em;
    outline-width: 0.25em;
    outline-color: currentColor;
  }
  ul,ol,dl,dt,dd,p,figure,blockquote {
    hanging-punctuation: first last;
    text-wrap: pretty;
  }
}

For now I’m just using :where() but I think I should start using cascade layers.

I also want to start training myself to use the lh value (line-height) for block spacing.

And although I’m using the :has() selector, I don’t think I’ve yet trained my brain to reach for it by default.

CSS has sooooo much to offer today—I want to make sure I’m taking full advantage of it.

Responses

Carlos Espada

The :has() selector is a very powerful and elegant tool, once you start using it, it opens up a ton of possibilities. A very simple way to use it, for example: body:has(dialog[open]) { overflow: clip; } What about container queries? Are you using them?

Marc Görtz

Nicht abgesprochen, aber wie bei Markus gibt es auch hier ein kleines Facelift:

Ich bin jetzt auf die Farbdefinition via oklch() umgestiegen. Das stand schon länger auf meiner Liste – in anderen Projekten hatte ich es sogar schon umgesetzt – aber Jeremy Keiths Beitrag hat mich dann doch dazu gebracht, auch hier endlich Hand anzulegen. Parallel dazu habe ich ein wenig am Kontrast geschraubt, wobei da aber noch Luft nach oben ist.

Apropos frische Ideen: Bei WebKit wurde kürzlich über Line Height Units geschrieben, und da konnte ich auch nicht widerstehen. Jetzt sind lh und rlh an vielen Stellen im Einsatz. Ein bisschen Feintuning steht hier noch an, aber der Grundstein ist gelegt.

Auch die Schrift habe ich ausgetauscht. Vorher war’s Inter – solide, aber auf Dauer doch etwas beliebig. Jetzt läuft hier Rubik, ebenfalls eine variable Schrift, aber deutlich kompakter mit fast 50% weniger Dateigröße. Nicht schlecht, oder?

Und dann wäre da noch ein kleiner Fünfzeiler, den ich ebenfalls bei Jeremy aufgeschnappt habe:

@media (prefers-reduced-motion: no-preference) { @view-transition { navigation: auto; } } 

Mein Einstieg in die View Transition API – mal sehen, wie sich das in den nächsten Wochen so anfühlt.

4 Shares

# Shared by Ghazal on Thursday, May 8th, 2025 at 11:01am

# Shared by Bernard Nijenhuis on Thursday, May 8th, 2025 at 11:31am

# Shared by gw on Thursday, May 8th, 2025 at 9:56pm

# Shared by Henry Bley-Vroman on Friday, May 9th, 2025 at 7:40pm

34 Likes

# Liked by Alexei Accio on Thursday, May 8th, 2025 at 11:01am

# Liked by Emily Rapport on Thursday, May 8th, 2025 at 11:01am

# Liked by David Bushell 🏖️ on Thursday, May 8th, 2025 at 11:01am

# Liked by Jonathan Stephens on Thursday, May 8th, 2025 at 11:01am

# Liked by Elaina on Thursday, May 8th, 2025 at 11:01am

# Liked by Matthias Ott on Thursday, May 8th, 2025 at 11:01am

# Liked by Sérgio Nunes on Thursday, May 8th, 2025 at 11:02am

# Liked by David Bushell 🏖️ on Thursday, May 8th, 2025 at 11:02am

# Liked by Bernard Nijenhuis on Thursday, May 8th, 2025 at 11:31am

# Liked by felix on Thursday, May 8th, 2025 at 11:31am

# Liked by Fernando Mateus on Thursday, May 8th, 2025 at 11:34am

# Liked by Psylok on Thursday, May 8th, 2025 at 11:56am

# Liked by Chris Smith on Thursday, May 8th, 2025 at 12:07pm

# Liked by Brian Hart on Thursday, May 8th, 2025 at 12:27pm

# Liked by Paul Burgess on Thursday, May 8th, 2025 at 12:27pm

# Liked by Marc Amos on Thursday, May 8th, 2025 at 12:34pm

# Liked by Mason Conkright on Thursday, May 8th, 2025 at 12:59pm

# Liked by Carlos Espada on Thursday, May 8th, 2025 at 12:59pm

# Liked by Flo Kosiol on Thursday, May 8th, 2025 at 1:05pm

# Liked by Jordi Sánchez on Thursday, May 8th, 2025 at 1:23pm

# Liked by Jason on Thursday, May 8th, 2025 at 1:41pm

# Liked by Luke Dorny on Thursday, May 8th, 2025 at 1:41pm

# Liked by Ferhat Aslan on Thursday, May 8th, 2025 at 1:54pm

# Liked by Dan Connolly on Thursday, May 8th, 2025 at 2:06pm

# Liked by strongest on Thursday, May 8th, 2025 at 2:41pm

# Liked by John Warne on Thursday, May 8th, 2025 at 2:41pm

# Thursday, May 8th, 2025 at 3:20pm

# Liked by Mia (web luddite) on Thursday, May 8th, 2025 at 3:47pm

# Liked by Nick F on Thursday, May 8th, 2025 at 4:19pm

# Thursday, May 8th, 2025 at 6:44pm

# Liked by gw on Thursday, May 8th, 2025 at 9:56pm

# Liked by zeu on Friday, May 9th, 2025 at 10:12am

# Liked by Ade Oshineye on Sunday, May 11th, 2025 at 5:37pm

# Liked by Aaron Davis on Thursday, May 15th, 2025 at 11:56am

Related posts

Making the website for Research By The Sea

Having fun with view transitions and scroll-driven animations.

Hanging punctuation in CSS

A little fix for Safari.

Schooltijd

Going back to school in Amsterdam.

Assumption

Separate your concerns.

Control

Trying to understand a different mindset to mine.

Related links

Performance-Optimized Video Embeds with Zero JavaScript – Frontend Masters Blog

This is a clever technique for a CSS/HTML only way of just-in-time loading of iframes using details and summary.

Tagged with

NoLoJS: Reducing the JS Workload with HTML and CSS - Web Performance Calendar

You might not need (much) JavaScript for these common interface patterns.

While we all love the power and flexibility JS provides, we should also respect it, and our users, by limiting its use to only what it needs to do.

Yes! Client-side JavaScript should do what only client-side JavaScript can do.

Tagged with

Web development tip: disable pointer events on link images

Here’s a little snippet of CSS that solves a problem I’ve never considered:

The problem is that Live Text, “Select text in images to copy or take action,” is enabled by default on iOS devices (Settings → General → Language & Region), which can interfere with the contextual menu in Safari. Pressing down on the above link may select the text inside the image instead of selecting the link URL.

Tagged with

CSS-in-JS: The Great Betrayal of Frontend Sanity - The New Stack

This is a spot-on analysis of how CSS-in-JS failed to deliver on any of its promises:

CSS-in-JS was born out of good intentions — modularity, predictability and componentization. But what we got was complexity disguised as progress.

Tagged with

Write Code That Runs in the Browser, or Write Code the Browser Runs - Jim Nielsen’s Blog

So instead of asking yourself, “How can I write code that does what I want?” Consider asking yourself, “Can I write code that ties together things the browser already does to accomplish what I want (or close enough to it)?”

Tagged with

Previously on this day

3 years ago I wrote Tragedy

Greek tragedies are time-travel stories.

7 years ago I wrote Timing out

A service worker strategy for dealing with lie-fi.

8 years ago I wrote Alternative analytics

Google Analytics is not the only option.

8 years ago I wrote Process and culture

Process is a four letter word.

11 years ago I wrote 100 words 047

Day forty seven.

13 years ago I wrote Inspiration calling

A phone call about the sincerest form of flattery.

15 years ago I wrote Bye, bye pride

Missing Grant McLennan.

15 years ago I wrote An Event Apart apart

Failing to explain what made An Event Apart in Boston so special to me.

15 years ago I wrote All Our Yesterdays: the links

Hyperlinks of digital preservation.

17 years ago I wrote The Medium is the Mess

Scribbling in the margins of the rule book.

18 years ago I wrote Why You Should Have a Web Site

Liveblogging a presentation by Steven Pemberton at XTech 2008 in Dublin.

18 years ago I wrote Data Portability For Whom?

Liveblogging a talk by Gavin Bell at XTech 2008 in Dublin.

18 years ago I wrote Ni Hao, Monde: Connecting Communities Across Cultural and Linguistic Boundaries

Liveblogging a presentation by Simon Batistoni at XTech 2008 in Dublin.

18 years ago I wrote AMEE — The World’s Energy Meter

Liveblogging a talk by Gavin Starks at XTech 2008 in Dublin.

20 years ago I wrote The waste (memory wastes)

Grant McLennan RIP

22 years ago I wrote Brighton rock

The Brighton Festival is in full swing. Everywhere you look, there’s theatre, music, dance and art.

23 years ago I wrote Malkovich, Malkovich

Malkovich this Malkovich.