Tags: styling



Saturday, October 6th, 2018

An nth-letter selector in CSS

Variable fonts are a very exciting and powerful new addition to the toolbox of web design. They was very much at the centre of discussion at this year’s Ampersand conference.

A lot of the demonstrations of the power of variable fonts are showing how it can be used to make letter-by-letter adjustments. The Ampersand website itself does this with the logo. See also: the brilliant demos by Mandy. It’s getting to the point where logotypes can be sculpted and adjusted just-so using CSS and raw text—no images required.

I find this to be thrilling, but there’s a fly in the ointment. In order to style something in CSS, you need a selector to target it. If you’re going to style individual letters, you need to wrap each one in an HTML element so that you can then select it in CSS.

For the Ampersand logo, we had to wrap each letter in a span (and then, becuase that might cause each letter to be read out individually instead of all of them as a single word, we applied some ARIA shenanigans to the containing element). There’s even a JavaScript library—Splitting.js—that will do this for you.

But if the whole point of using HTML is that the content is accessible, copyable, and pastable, isn’t a bit of a shame that we then compromise the markup—and the accessibility—by wrapping individual letters in presentational tags?

What if there were an ::nth-letter selector in CSS?

There’s some prior art here. We’ve already got ::first-letter (and now the initial-letter property or whatever it ends up being called). If we can target the first letter in a piece of text, why not the second, or third, or nth?

It raises some questions. What constitutes a letter? Would it be better if we talked about ::first-character, ::initial-character, ::nth-character, and so on?

Even then, there are some tricksy things to figure out. What’s the third character in this piece of markup?


Is it “C”, becuase that’s the third character regardless of nesting? Or is it “E”, becuase techically that’s the third character token that’s a direct child of the parent element?

I imagine that implementing ::nth-letter (or ::nth-character) would be quite complex so there would probably be very little appetite for it from browser makers. But it doesn’t seem as problematic as some selectors we’ve already got.

Take ::first-line, for example. That violates one of the biggest issues in adding new CSS selectors: it’s a selector that depends on layout.

Think about it. The browser has to first calculate how many characters are in the first line of an element (like, say, a paragraph). Having figured that out, the browser can then apply the styles declared in the ::first-line selector. But those styles may involve font sizing updates that changes the number of characters in the first line. Paradox!

(Technically, only a subset of CSS of properties can be applied to ::first-line, but that subset includes font-size so the paradox remains.)

I checked to see if ::first-line was included in one of my favourite documents: Incomplete List of Mistakes in the Design of CSS. It isn’t.

So compared to the logic-bending paradoxes of ::first-line, an ::nth-letter selector would be relatively straightforward. But that in itself isn’t a good enough reason for it to exist. As the CSS Working Group FAQs say:

The fact that we’ve made one mistake isn’t an argument for repeating the mistake.

A new selector needs to solve specific use cases. I would argue that all the letter-by-letter uses of variable fonts that we’re seeing demonstrate the use cases, and the number of these examples is only going to increase. The very fact that JavaScript libraries exist to solve this problem shows that there’s a need here (and we’ve seen the pattern of common JavaScript use-cases ending up in CSS before—rollovers, animation, etc.).

Now, I know that browser makers would like us to figure out how proposed CSS features should work by polyfilling a solution with Houdini. But would that work for a selector? I don’t know much about Houdini so I asked Una. She pointed me to a proposal by Greg and Tab for a full-on parser in Houdini. But that’s a loooong way off. Until then, we must petition our case to the browser gods.

This is not a new suggestion.

Anne Van Kesteren proposed ::nth-letter way back in 2003:

While I’m talking about CSS, I would also like to have ::nth-line(n), ::nth-letter(n) and ::nth-word(n), any thoughts?

Trent called for ::nth-letter in January 2011:

I think this would be the ideal solution from a web designer’s perspective. No javascript would be required, and 100% of the styling would be handled right where it should be—in the CSS.

Chris repeated the call in October of 2011:

Of all of these “new” selectors, ::nth-letter is likely the most useful.

In 2012, Bram linked to a blog post (now unavailable) from Adobe indicating that they were working on ::nth-letter for Webkit. That was the last anyone’s seen of this elusive pseudo-element.

In 2013, Chris (again) included ::nth-letter in his wishlist for CSS. So say we all.

Thursday, October 4th, 2018

Tuesday, September 25th, 2018

The State of Fieldset Interoperability - Bocoup

The long-standing difficulties of styling fieldset and legend are finally getting addressed …although I’m a little shocked that the solution involves extending -webkit-appearance. I think that, at this point, we should be trying to get rid of vendor prefixes from the web once and for all, not adding to them. Still, needs must, I suppose.

Friday, July 13th, 2018

CSS: A New Kind Of JavaScript | HeydonWorks

A bold proposal by Heydon to make the process of styling on the web less painful and more scalable. I think it’s got legs, but do we really need another three-letter initialism?

We waste far too much time writing and maintaining styles with JavaScript, and I think it’s time for a change. Which is why it’s my pleasure to announce an emerging web standard called CSS.

Tuesday, June 12th, 2018

Resilient, Declarative, Contextual

This is really good breakdown of what’s different about CSS (compared to other languages).

These differences may feel foreign, but it’s these differences that make CSS so powerful. And it’s my suspicion that developers who embrace these things, and have fully internalized them, tend to be far more proficient in CSS.

Tuesday, April 3rd, 2018

How display: contents; Works

A really deep dive into display: contents from Ire.

Friday, March 30th, 2018

Focusing on Focus Styles | CSS-Tricks

A deep dive into the :focus pseudo-class and why it’s important.

Wednesday, March 28th, 2018

Nobody Said CSS Is Easy

One thing I gained a stronger awareness of (simply from working with checkboxes) is that it’s important to progressively enhance UI components, so that a fancy custom one is able to fall back to the default browser styles and functionality. This way, a user can still access the UI if JavaScript or CSS fail.

Wednesday, March 7th, 2018

Frequently Asked Questions [CSS Working Group Wiki]

Rebuttals to the most oft-asked requests for browsers to change the way they handle CSS.

Monday, February 12th, 2018

How I design with CSS grid

Always mark-up first. Regardless of what the kids are doing these days, I stick by my guns and start with mark-up first. A fun experiment (maybe not for you, but definitely for me) is to see how your site reads on Lynx. It does serve as a good gauge of whether the content on the site is structured properly or not.

Saturday, January 6th, 2018

A Sliding Nightmare: Understanding the Range Input | CSS-Tricks

Ana goes into exhaustive detail on all the differences in the shadow DOM and styling of input type="range" across browsers.

I’m totally fine with browsers providing different styling for complex UI elements like this, but I wish they’d at least provide a consistent internal structure and therefore a consistent way of over-riding the default styles. Maybe then people wouldn’t be so quick to abandon native elements like this in favour building their own UI components from scratch—the kind of over-engineering that inevitably ends up being under-engineered.

Thursday, December 7th, 2017

Silly hover effects and the future of web typography – Pixelambacht

These experiments with transitioning variable font styles on hover might be silly, but I can see the potential for some beautiful interaction design.

Accessible Links Re:visited | Filament Group, Inc., Boston, MA

Great advice on keeping your hyperlinks accessible.

Wednesday, November 29th, 2017

Accessible custom styled form elements - Rian Rietveld

An excellent level-headed evaluation of styling and scripting form controls, weighing up the benefits and trade-offs. The more tightly you control the appearance, the less you get to benefit from the functionality (and accessibility) that the browser gives you for free …meaning you’ve now to got to work harder to replace it.

HTML elements like check buttons, radio buttons or select options can be hard to style with CSS in a custom design. There are many workarounds for this, but are they accessible?

Thursday, November 16th, 2017

Saturday, September 23rd, 2017

[selectors] Functional pseudo-class like :matches() with 0 specificity · Issue #1170 · w3c/csswg-drafts

A really interesting proposal from Lea that would allow CSS authors to make full use of selectors but without increasing specificity. Great thoughts in the comments too.

Tuesday, August 22nd, 2017

Inside a super fast CSS engine: Quantum CSS (aka Stylo) ★ Mozilla Hacks – the Web developer blog

Lin gives a deep dive into Firefox’s new CSS engine specifically, but this is also an excellent primer on how browsers handle CSS in general: parsing, styling, layout, painting, compositing, and rendering.

Saturday, August 12th, 2017

Shadow DOM: fast and encapsulated styles – Monica Dinculescu

Monica explains how Shadow DOM could be the perfect answer for scoping CSS:

We didn’t have style encapsulation, so we started naming things “the right way” with BEM, so that we didn’t accidentally stomp over each other’s styles. We wanted to be able to author CSS from inside a JavaScript component, so we started using CSS-in-JS. We needed all these tools, because “the platform” (read: the browsers that be) wasn’t there, and building these tools showed that there was a need to move forward. For style encapsulation, Shadow DOM is the platform moving forward.

Although, in a way, Shadow DOM is also another flavour of CSS-in-JS:

Before you complain that using a Shadow DOM and Web Components means that it absolutely requires JavaScript: this is true.

Thursday, July 6th, 2017

CSS is Awesome | CSS-Tricks

Geek humour is no laughing matter, as Chris demonstrates here with his thorough dissection of that coffee mug.

CSS is weird. It’s unlike any other code, and that makes a lot of programmers uncomfortable. But used wisely it can, in fact, be awesome.

It’s not often I say this, but read the comments.

Monday, July 3rd, 2017

Fixing fieldsets — That Emil is Emil Björklund

This is an excellent proposal from Emil. If we can apply display: contents to fieldsets, then we would finally have a way of undoing the byzantine browser styles that have hindered adoption of this element. This proposal also ensures backwards compatibility so there’d be no breakage of older sites:

The legacy appearance of fieldsets probably needs to be preserved for compatibility reasons. But display: contents is not supported in any old browsers, and is most likely used on exactly zero sites using the legacy look of fieldsets.

Whaddya say, browser makers?