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.

Have you published a response to this? :

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

My requests for Interop 2026 | Clagnut by Richard Rutter

Every one of these five proposals is worth a vote.

Mind you, Rich’s cynicism is understandable.

Tagged with

I’m more proud of these 128 kilobytes than anything I’ve built since | by Mike Hall | Jul, 2025 | Medium

I don’t normally link to articles on Medium—I respect you too much—and I do wish this were written on Mike Hall’s own site, but this is just too good not to share.

And don’t dismiss this as a nostalgiac case study from the past:

At no point did the constraints make the product feel compromised. Users on modern devices got a smooth experience and instant feedback, while those on older devices got fast, reliable functionality. Users on feature phones got the same core experience without the bells and whistles.

The constraints forced us to solve problems in ways we wouldn’t have considered otherwise. Without those constraints, we could have just thrown bytes at the problem, but with them every feature had to justify itself. Core functionality had to work everywhere, and without JavaScript crutches proper markup became essential.

This experience changed how I approach design problems. Constraints aren’t a straitjacket, keeping us from doing our best work; they are the foundation that makes innovation possible. When you have to work within severe limitations, you find elegant solutions that scale beyond those limitations.

Tagged with

CSS Intelligence: Speculating On The Future Of A Smarter Language — Smashing Magazine

This is a really thoughtful look at the evolution of CSS and the ever-present need to balance power with learnability.

Tagged with

Hiding elements that require JavaScript without JavaScript :: dade

This is clever: putting CSS inside a noscript element to hide anything that requires JavaScript.

Tagged with

Cascading Layouts | OddBird

A workshop on resilient CSS layouts

Oh, hell yes!

Do not hesitate—sign yourself up to this series of three online workshops by Miriam. This is the quickest to level up your working knowledge of the most powerful parts of CSS.

By the end of this you’re going to feel like Neo in that bit of The Matrix when he says “I know kung-fu!” …except kung-fu isn’t very useful for building resilient and maintainable websites, whereas modern CSS absolutely is.

Tagged with

Previously on this day

2 years ago I wrote Tragedy

Greek tragedies are time-travel stories.

6 years ago I wrote Timing out

A service worker strategy for dealing with lie-fi.

7 years ago I wrote Alternative analytics

Google Analytics is not the only option.

7 years ago I wrote Process and culture

Process is a four letter word.

10 years ago I wrote 100 words 047

Day forty seven.

12 years ago I wrote Inspiration calling

A phone call about the sincerest form of flattery.

14 years ago I wrote Bye, bye pride

Missing Grant McLennan.

14 years ago I wrote An Event Apart apart

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

14 years ago I wrote All Our Yesterdays: the links

Hyperlinks of digital preservation.

16 years ago I wrote The Medium is the Mess

Scribbling in the margins of the rule book.

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

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

17 years ago I wrote Data Portability For Whom?

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

17 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.

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

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

19 years ago I wrote The waste (memory wastes)

Grant McLennan RIP

21 years ago I wrote Brighton rock

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

22 years ago I wrote Malkovich, Malkovich

Malkovich this Malkovich.