Author Information

Brian Kardell
  • Developer Advocate at Igalia
  • Original Co-author/Co-signer of The Extensible Web Manifesto
  • Co-Founder/Chair, W3C Extensible Web CG
  • Member, W3C (OpenJS Foundation)
  • Co-author of HitchJS
  • Blogger
  • Art, Science & History Lover
  • Standards Geek
Follow Me On...
Posted on 04/25/2017

Reflecting on Roles

Just a silly little experiment based on an observation...

So much of what we write is trying to classify and identify things so that we can 'talk about them'. This is true in designs and meetings as well as practically in code: CSS Selectors can be used by DOM, programatically, and by CSS declaratively to 'talk about' something in terms of function or style.

ARIA provides a way for you to explain to the browser that a thing is or behaves as something it can understand. For example, an element can have a role=heading or role=button and the browser will expose that to AT appropriately. This works because native elements have implicit roles as defined ARIA in HTML and ARIA defines a rich taxonomy for explaining these.

Now, however, let's say we want to talk about headings, or buttons. For us, verbally, that's trivial. For AT, that's trivial. But in terms of CSS selectors, it's kind of a pain in the ass. Let's say that you want to style "the first letter of any paragraph immediately following a heading" and you've got a number of approaches across your site(s). Traditionally, to write this, you'd have to write:

h1 + p::first-letter,
h2 + p::first-letter,
h3 + p::first-letter,
h4 + p::first-letter,
h5 + p::first-letter,
h6 + p::first-letter,
[role=heading] + p::first-letter { ... }

Eventually, we'll be able to use the :matches to make this a little better:

:matches(h1,h2,h3,h4,h5,h6,[role=heading]) + p::first-letter { ... }

But.. that still isn't super great and that's kind of a trivial thing to want to express. The thing is, the browser already knows they're all headings, it's just invisible to us for many practical purposes. If they were exposed to us somehow, we could write a simple rule like.

[role=heading] + p::first-letter { ... }

Note, the syntax there is debatable - practically speaking it would probably make more sense to use a pseudo-class like :role(heading) for this purpose.

It's not limited to headings either - the taxonomy is useful in a lot of ways. Take buttons for example. If you wanted to generically talk about the style of "things that are buttons" - traditionally you would have to write something like:

[role="button"] { ... }

But, again, the browser already knows that these are all "button", so it seems almost tragic that you can't just write something like:

[role=button] {
  background-color: #ccccff;
  border-color: blue;
  border-radius: 0.25rem;
  display: inline;
  border: 1px;
  margin: 0.25rem;
  padding: 0.5rem;
  font-size: 0.8rem;
  font-family: sans-serif;

and that would apply to.. you know.. all the buttons. And for buttons, we do a lot - we style the hover state and the focus state and so on.

Now... I think that maybe this matters more than just "it feels nicer to write" because the simple fact is that without something like this, the data seems to show that we resort to workarounds. For example, the Bootstrap .btn class, which ultimately leads to lots of things that are not accessible, and ultimately just 'less' in pursuit of something that is pretty easy for authors to express.

So here's a thing...

This is a little script written using mutation observers that you can include in the head of your document and it will expose the implicit roles defined ARIA in HTML (if there isn't a role already). While you might think that is 'heavy', it simply looking at the tag name, doing a lookup and potentially setting an attribute - not really terrible at all.

The point isn't "we should use this" it is simply to give authors kind of enough to play with things and see if it's totally nuts or potentially really helpful for authors. If not, then maybe a way to begin to discuss what that might mean in terms of a real solution.


This page is, itself a demo. You can see lots of buttony things styled with a rule about buttons and headings all styled purple with rules just like the above...

Test ARIA Btn

Post Script

While writing this I thought I recalled a nearly similar thing come up a few years back, and even reached out to some folks to see if I could find it, so I didn't mention it. After posting, however, someone pointed me to it: In 2013, James Craig requested almost literally this, which just this last week was moved to a Github issue in the CSS A11Y Task Force repo which somehow I was not following. Great!

Also, after I wrote this, my friend Michiel Bijl from TPG wrote a follow-up Cascading Semantic Stylehooks as well.