Tags: styles

122

sparkline

Tuesday, January 20th, 2026

Lowering the specificity of multiple rules at once - Manuel Matuzovic

This is clever, and seems obvious in hindsight: use an anonymous @layer for your CSS reset rules!

Thursday, September 25th, 2025

Thursday, August 14th, 2025

Underlines and line height

I was thinking about something I wrote yesterday when I was talking about styling underlines on links:

For a start, you can adjust the distance of the underline from the text using text-underline-offset. If you’re using a generous line-height, use a generous distance here too.

For some reason, I completely forgot that we’ve got a line-height unit in CSS now: lh. So if you want to make the distance of your underline proportional to the line height of the text that the link is part of, it’s easy-peasy:

text-underline-offset: 0.15lh; 

The greater the line height, the greater the distance between the link text and its underline.

I think this one is going into my collection of CSS snippets I use on almost every project.

Wednesday, August 13th, 2025

Style your underlines

We shouldn’t rely on colour alone to indicate that something is interactive.

Take links, for example. Sure, you can give them a different colour to the surrounding text, but you shouldn’t stop there. Make sure there’s something else that distinguishes them. You could make them bold. Or you could stick with the well-understood convention of underlying links.

This is where some designers bristle. If there are a lot of links on a page, it could look awfully cluttered with underlines. That’s why some designers would rather remove the underline completely.

As Manu observed:

I’ve done a lot of audits in the first half of this year and at this point a believe that designing links without underlines is a kink. The idea that users don’t understand that links are clickable arouses some designers. I can’t explain it any other way.

But underlining links isn’t the binary decision it once was. You can use CSS to style those underlines just as you’d style any other part of your design language.

Here’s a regular underlined link.

For a start, you can adjust the distance of the underline from the text using text-underline-offset. If you’re using a generous line-height, use a generous distance here too.

Here’s a link with an offset underline.

If you’d rather have a thinner or thicker underline, use text-decoration-thickness.

Here’s a link with a thin underline.

The colour of the underline and the colour of the link don’t need to be the same. Use text-decoration-color to make them completely different colours or make the underline a lighter shade of the link colour.

Here’s a link with a translucent underline.

That’s quite a difference with just a few CSS declarations:

text-underline-offset: 0.2em; text-decoration-thickness: 1px; text-decoration-color: oklch(from currentColor l c h / 50%); 

If that still isn’t subtle enough for you, you could even use text-decoration-style to make the underline dotted or dashed, but that might be a step too far.

Here’s a link with a dotted underline.

Whatever you decide, I hope you’ll see that underlines aren’t the enemy of good design. They’re an opportunity.

You should use underlines to keep your links accessible. But you should also use CSS to make those underlines beautiful.

Wednesday, July 23rd, 2025

A Friendly Introduction to SVG • Josh W. Comeau

A fantastic explanation of the building blocks of SVG, illustrated—as always—with Josh’s interactive examples.

Sunday, June 22nd, 2025

Kelp

A UI library for people who love HTML, powered by modern CSS and Web Components.

Wednesday, May 21st, 2025

Matthias Ott – Painting With the Web – beyond tellerrand Düsseldorf 20025 - YouTube

A great talk by Matthias on what you can do with web standards today!

Matthias Ott – Painting With the Web – beyond tellerrand Düsseldorf 20025

Thursday, May 8th, 2025

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.

Thursday, April 17th, 2025

Hiding elements that require JavaScript without JavaScript :: dade

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

Wednesday, March 19th, 2025

Style legend

There’s a new proposal for giving developers more control over styling form controls. I like it.

It’s clearly based on the fantastic work being done by the Open UI group on the select element. The proposal suggests that authors can opt-in to the new styling possibilities by declaring:

appearance: base; 

So basically the developer is saying “I know what I’m doing—I’m taking the controls.” But browsers can continue to ship their default form styles. No existing content will break.

The idea is that once the developer has opted in, they can then style a number of pseudo-elements.

This proposal would apply to pretty much all the form controls you can think of: all the input types, along with select, progress, meter, buttons and more.

But there’s one element more that I wish were on the list:

legend

I know, technically it’s not a form control but legend and fieldset are only ever used within forms.

The legend element is notoriously annoying to style. So a lot of people just don’t bother using it, which is a real shame. It’s like we’re punishing people for doing the right thing.

Wouldn’t it be great if you, as a developer, had the option of saying “I know what I’m doing—I’m taking the controls”:

legend { appearance: base; } 

Imagine if that nuked the browser’s weird default styles, effectively turning the element into a span or div as far as styling is concerned. Then you could style it however you wanted. But crucially, if browsers shipped this, no existing content would break.

The shitty styling situation for legend (and its parent fieldset) is one of those long-standing annoyances that seems to have fallen down the back of the sofa of browser vendors. No one’s going to spend time working on it when there are more important newer features to ship. That’s why I’d love to see it sneak in to this new proposal for styling form controls.

I was in Amsterdam last week. Just like last year I was there to help out Vasilis’s students with a form-based assignment:

They’re given a PDF inheritance-tax form and told to convert it for the web.

Yes, all the excitement of taxes combined with the thrilling world of web forms.

(Side note: this time they were told to style it using the design system from the Dutch railway because the tax office was getting worried that they were making phishing sites.)

I saw a lot of the same challenges again. I saw how students wished they could specify a past date or a future date in a date picker without using JavaScript. And I saw them lamenting the time they spent styling legends that worked across all browsers.

Right now, Mason Freed has an open issue on the new proposal with his suggestion to add some more elements to consider. Both legend and fieldset are included. That gets a thumbs-up from me.

Wednesday, January 29th, 2025

6 CSS Snippets Every Front-End Developer Should Know In 2025 · 19 January 2025

  • Springy easing with linear()
  • Typed custom properties
  • View transitions for page navigation
  • Transition animation for dialog and popover
  • Transition animation for details
  • Animated adaptive gradient text

Thursday, October 31st, 2024

My Modern CSS Reset | jakelazaroff.com

I like the approach here: logical properties and sensible default type and spacing.

Tuesday, October 1st, 2024

I wasted a day on CSS selector performance to make a website load 2ms faster | Trys Mudford

Picture me holding Trys back and telling him, “Leave it alone, mate, it’s not worth it!”

Wednesday, September 25th, 2024

Introducing TODS – a typographic and OpenType default stylesheet | Clagnut by Richard Rutter

This is a very handy piece of work by Rich:

The idea is to set sensible typographic defaults for use on prose (a column of text), making particular use of the font features provided by OpenType. The main principle is that it can be used as starting point for all projects, so doesn’t include design-specific aspects such as font choice, type scale or layout (including how you might like to set the line-length).

Tuesday, May 28th, 2024

Building on the idea of an IndieWeb zine - Benjamin Parry

Speaking of zines, I really like Benjamin’s ideas about a web-first indie web zine: using print stylesheets with personal websites to make something tangible but webby.

Tuesday, October 10th, 2023

Making the Patterns Day website

I had a lot of fun making the website for Patterns Day.

If you’re interested in the tech stack, here’s what I used:

  1. HTML
  2. CSS

Actually, technically it’s all HTML because the styles are inside a style element rather than a separate style sheet, but you know what I mean. Also, there is technically some JavaScript but all it does is register a service worker that takes care of caching and going offline.

I didn’t use any build tools. There was no pipeline. There is no node_modules folder filling up my hard drive. Nothing was automated. The website was hand-crafted the long hard stupid way.

I started with the content. I wrote out the words and marked them up with the most appropriate HTML elements.

A screenshot of an unstyled web page for Patterns Day.

Time to layer on the presentation.

For the design, I turned to Michelle for help. I gave her a brief, describing the vibe of the conference, and asked her to come up with an appropriate visual language.

Crucially, I asked her not to design a website. Instead I asked her to think about other places where this design language might be used: a poster, social media, anything but a website.

Partly I was doing this for my own benefit. If you give me a pixel-perfect design for a web page and tell me to code it up, either I won’t do it or I won’t enjoy it. I just don’t get any motivation out of that kind of direct one-to-one translation.

But give me guardrails, give me constraints, give me boundary conditions, and off I go!

Michelle was very gracious in dealing with such a finicky client as myself (“Can you try this other direction?”, “Hmm… I think I preferred the first one after all!”) She delivered a colour palette, a type scale, typeface choices, and some wonderful tiling patterns …it is Patterns Day after all!

With just a few extra lines of CSS, the basic typography was in place.

A screenshot of the web page for Patterns Day with web fonts applied.

I started layering on the colours. Even though this was a one-page site, I still made liberal use of custom properties in the CSS. It just feels good to be able to update one value and see the results, well …cascade.

A screenshot of the web page for Patterns Day with colours added.

I had a lot of fun with the tiling background images. SVG was the perfect format for these. And because the tiles were so small in file size, I just inlined them straight into the CSS.

By this point, I felt like I was truly designing in the browser. Adjusting spacing, playing around with layout, and all that squishy stuff. Some of the best results came from happy accidents—the way that certain elements behaved at certain screen sizes would lead me into little experiments that yielded interesting results.

I’m not sure it’s possible to engineer that kind of serendipity in Figma. Figma was the perfect tool for exploring ideas around the visual vocabulary, and for handing over design decisions around colour, typography, and texture. But when it comes to how the content is going to behave on the World Wide Web, nothing beats a browser for fidelity.

A screenshot of the web page for Patterns Day with some changes applied.

By this point I was really sweating the details, like getting the logo just right and adjusting the type scale for different screen sizes. Needless to say, Utopia was a godsend for that.

I was also checking back in with Michelle to get her take on design decisions I was making.

I could’ve kept tinkering but the diminishing returns were a sign that it was time to put this out into the world.

A screenshot of the web page for Patterns Day with the logo in place.

It felt really good to work on a web page like this. It felt like I was getting my hands into the soil of the web. I don’t think it’s an accident that the result turned out to be very performant.

Getting hands-on like this stops me from getting rusty. And honestly, working with CSS these days is a joy. There’s such power to be had from using var() in combination with functions like calc() and clamp(). Layout is a breeze with flexbox and grid. Browser differences are practically non-existent. We’ve never had it so good.

Here’s something I noticed about my relationship to CSS; my brain has finally made the switch to logical properties. Now if I’m looking at some CSS and I see left, right, top, or bottom, it looks like a bug to me. Those directional properties feel loaded with assumptions whereas logical properties feel much more like working with the grain of the web.

Wednesday, October 4th, 2023

Clamp calculator | Utopia

Oh, this is a nice addition to the Utopia set of tools: when you don’t need a full-on type scale but you still want to figure out fluid clamp() values, the clamp calculator has you covered.

It’s got permalinks too!

Tuesday, September 19th, 2023

A (more) Modern CSS Reset - Andy Bell

A solid update to Andy’s four-years old CSS reset. Best of all, every single line comes with an explanation. So if you don’t like the reasoning, don’t use that line.

Tuesday, March 21st, 2023

Thursday, March 16th, 2023

Modern Font Stacks

This is handy—a collection of font stacks using system fonts. You can see which ones are currently installed on your machine too.

The most performant web font is no web font.