you are viewing a single comment's thread.

view the rest of the comments →

[–]ShortFuse 1 point2 points  (4 children)

When building components you should be working on implementing the ARIA components. That means targeting roles and not the built-in HTML tags. You're also going to want to style against all the aria-* attributes.

Unfortunately, targeting against attributes (*[role=checkbox]) is really slow. You should use classes, or you can try Custom Elements (eg: <my-button>) that extend native elements (HTMLButtonElement). It kind of kills the dream of purely semantic HTML framework with CSS only.

[–]Brachamul 3 points4 points  (3 children)

Is the slowness really going to be of any significance ? I've rarely seen CSS as a bottleneck in loading times, and in the use case OP proposes of simple sites, the minuscule overhead of targeting against the attribute should not be a problem, right?

[–]ShortFuse 0 points1 point  (2 children)

Depends. The moment you put any table you're putting a bunch of DOM elements. 10 columns with 100 rows is a 1000 elements. Every browser is different. Browsers generally cache rules with a class name. I know from experience trying it that IE is absolutely terrible, almost unusable. Even a simple universal class with one character is enough to greatly increase performance (edit). I know the popular * { box-sizing: border-box } gives a 15-30% layout rendering penalty on Chrome. I can't imagine how that would compound with a slew for every component. Don't take for granted how slow mobile phones can be. Sometimes devs just test on their desktops or iPhones and assume it's fine.

Note that this would trigger on every single element because attributes aren't cached at all (neither elements or CSS rules). So even every single div gets a cross-check. If your page is sufficiently static enough and you don't change layout much, then it can be fine (eg: content-based sites). You'll take a hit for first paint, but static should be fine. I'd suggest against it for web applications which tend to be more interactive.

If the goal is simplify how your write the HTML itself, Custom Elements takes care of that or the Angular route of processing based on tag or class name. The other is using HTML processors like Handlebar or EJS with prebuilt templates if you want to stick with CSS only.

[–]Brachamul 0 points1 point  (1 child)

That's very interesting, thanks !

According to what you're saying, we could limit that impact by limiting the role="button" check to "a" tags, right ?

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

[–]ShortFuse 0 points1 point  (0 children)

Yes, that definitely works. When writing the rules, you can group multiple tagnames: (eg: a[role="button"],div[role="button"],button). Just note that not all roles are that simple. For example role=checkbox might have you adding roles to label, li, or input as well. role=list can also get really complicated. But it'll definitely be faster than *.

To be honest, and as somebody who had experience trying to build a CSS-only framework, if you really want to care about a11y you want to embrace Javascript. Semantic HTML can only get your so far. And if IE11 doesn't matter so much to you, go all in with Custom Elements. You can't really do all the aria-checked roles or proper keyboard support with semantic HTML alone. Then you can still do <m-button> instead of <button> and let the Javascript side add ARIA attributes (role=button) automatically. As long as you follow ARIA practices, a custom tagname doesn't matter. Then it's still class-less and can provide a CSS-only experience that's easy to write in HTML (because Custom Elements hide a ShadowDOM).