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.
This is a clever technique for a CSS/HTML only way of just-in-time loading of iframes using details and summary.
Think you know about styling lists with CSS? Think again!
This is just a taste of the kind of in-depth knowledge that Rich will be beaming directly into our brains at Web Day Out…
There have been so many advances in HTML, CSS and browser support over the past few years. These are enabling phenomenal creativity and refinement in web typography, and I’ve got a mere 28 minutes to tell you all about it.
I’ve been talking to Rich about his Web Day Out talk, and let me tell you, you don’t want to miss it!
It’s gonna be a wild ride! Join me at Web Day Out in Brighton on 12 March 2026. Use JOIN_RICH to get 10% off and you’ll also get a free online ticket for State of the Browser.
Some neat CSS from Tess that’s a great example of progressive enhancement; these book covers look good in all browsers, but they look even better in some.
This is clever, and seems obvious in hindsight: use an anonymous @layer for your CSS reset rules!
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.
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.
An excellent example of an HTML web component from Eric:
Extend HTML to do things automatically!
He layers on the functionality and styling, considering potential gotchas at every stage. This is resilient web design in action.
I’m not the only one who’s amazed by how much you can do with just a little CSS these days.
I’ve added this handy little bit of CSS to my starting styles.
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.
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.
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.
A fantastic explanation of the building blocks of SVG, illustrated—as always—with Josh’s interactive examples.
This is a really thoughtful look at the evolution of CSS and the ever-present need to balance power with learnability.
A UI library for people who love HTML, powered by modern CSS and Web Components.
A great talk by Matthias on what you can do with web standards today!
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.
I should be using the lh and rlh units more enough—they’re supported across the board!
Everything you ever wanted to know about text-wrap: pretty in CSS.
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.