Journal
How we think about browsers, on GitHub’s blog
Keith Cirkel of Github has written about how they think about browsers and it’s interesting. In summary Github achieve:
- improved performance;
- exploiting new native technologies; and
- universal user access/inclusion
…via a progressive enhancement strategy that ensures a basic experience for all but delivers an enhanced experience to most. Their tooling gets a bit deep/exotic in places but I think the basic premise is:
- decide on what our basic experience is, then use native HTML combined with a bare minimum of other stuff to help old browsers deliver that; and
- exploit new JS features in our enhanced experience (the one most people will get) to make it super lean and fast
Pretty cool.
Using accessibility literacy to counter accessibility ignorance, by Devon Persing
The idea of accessibility literacy (having the right vocabulary, knowing the trustworthy info sources etc) makes sense.
The section on Accessibility ignorance and ableism presents some home truths about organisational attitudes to accessibility that need addressed.
Accessibility ignorance actually goes beyond just a lack of accessibility literacy. Accessibility ignorance is a facet of ableism, since it causes people to make decisions that actively harm disabled people.
- Accessibility ignorance isn't usually malicious.
- It's assuming that accessibility is taken care of because your organization has an accessibility specialist on staff, or has accessibility "baked in" to a design system.
- It's providing accessibility training for only teams that build products and not people that work in support, legal, operations, leadership, or other parts of the organization.
- It's expecting accessibility work to happen without impacting schedules and roadmaps that didn't originally take accessibility work into account.
- It's assuming disabled people don't use your product.
- It's not hiring disabled people.
- It's hiring disabled people but only to do accessibility work.
- …
The article wraps up with some great advice on cultivating accessibility literacy, and the senior buy-in needed to support it.
Getting Started With CSS Cascade Layers, by Stephanie Eckles
Yesterday I read Eric Meyer discussing CSS Cascade Layers and commenting that the speed at which it had transitioned from first public working draft to shipping as a full public release in every major desktop and mobile browser had made his head spin. Amazing stuff and an indicator of the turbo-boosted pace at which modern CSS is now evolving.
It also made me want to properly read up on Cascade Layers, because I knew some of the theory but now wanted to consider using it in practice. I’m no great fan of “cascade-taming” CSS frameworks like BEM and SUIT (although I acknowledge why we have them) so I’m interested to know if Cascade Layers can replace them. Stephanie Eckles’ article is an excellent primer.
I liked the idea of a specifying a stack like this:
@layer reset, base, theme, components, utilities;
You can then write styles into any of those layers at any point in a stylesheet, safe in the knowledge that the original stack definition sets the order of priority rather than the sequence in which we wrote specific styles.
Stephanie also addresses the question of whether we should write every component as a layer, which is something I’ve been considering. She advises that you could… but it’s probably not going to achieve the scoping effect that you want.
layers are not intended to solve scoping or encapsulation of styles. For that, keep an eye on another spec also being authored by Miriam Suzanne for actual native CSS scoping.
Lastly, Stephanie tackles how ready Cascade Layers are to use right now. At the time she wrote the article – January 2022 – the feature wasn’t widely supported, so wasn’t an option. Additionally Cascade Layers can’t really be used as a progressive enhancement because its nature is so all-encompassing and because testing for feature support using @supports
isn’t an option.
However like Eric Meyer mentions, a few months is a long time in CSS support! And as I write in June 2022 the browser support picture is currently looking quite healthy. However given that the first browsers to add support were only released a few months ago in February or March of this year, I think we might need to wait a bit longer – maybe til the percentage of users on non-supporting browsers is negligible – before using this on larger, higher-traffic sites.
Nothing to stop us experimenting on our smaller and intranet-based sites, though!
Refactoring a modal dialogue in 2022
My team will soon be refactoring our modal dialogue component. Ours has a few deficiencies, needs better developer experience and documentation, is not built to our Design System component standards, and could use a resilience boost from some progressive enhancement.
For a long time the best – meaning accessible, framework-agnostic, feature-packed – modal implementations were custom. Specifically:
However with recent browser advances (especially from Safari), there’s an argument that the time has now come that we no longer need custom solutions and can go native. So we might reach for the native <dialog>
HTML element.
However first I think we’d need to make an informed decision regarding our satisfaction with support, based on the updated advice in Scott O’Hara’s article Having an Open Dialog.
Additionally we should definitely be keeping one eye on proposals around the exciting new togglepopup
and popup
attributes which promise the holy grail of entirely HTML-powered modal dialogues with no JavaScript dependency.
Does the HTML details element solve progressively-enhanced disclosures?
The HTML details
element continues to gain fans and get developers’ juices flowing. Scott Jehl recently tweeted:
I love the details/summary HTML elements. So versatile. My favorite part is being able to show a collapsed state from the start without worrying about potential operability issues if JavaScript fails to run (since its behavior doesn't need it).
Scott goes on to describe how creating disclosure widgets (controls that hide and show stuff) with resilience in mind is so much more difficult when not using <details>
since it can require complex progressive enhancement techniques. At the very least these involve making content available by default in case JavaScript fails, then hiding it when the disclosure widget script loads successfully, ideally without a jarring flash of content in between.
Like Scott says, the <details>
element is different because you can have the content collapsed (hidden) by default without worrying about JavaScript and workarounds since the hidden content can be toggled open natively. That‘s a real superpower… and also makes you wonder: how many different places and different ways might we use this super-element?
GitHub’s use of details
Back in 2019, GitHub caused a flutter by going all-in on <details>
to make various interesting UI elements interactive without JS. Muan has co-created a number of components for Github where <details>
is used to, for example, open menus. They also shared notes from a talk on this subject. And Chris Coyier for one was impressed and intrigued.
Zach Leatherman’s details-utils
I’ve previously noted Zach Leatherman’s details-utils – a great example of using a web component to enhance an existing HTML element, in this case <details>
. The enhancements include:
- animated open/close
- a quantum aspect ideal for responsive design – closed by default on narrow screens, open by default on wide
- and more
And Zach has already used it on the navigation menus on jamstack.org and netlify.com, amongst other use cases.
Notes of caution
- The details element and in-page search by Manuel Matuzovic
- A details element as a burger menu is not accessible on Cloud Four’s blog
- The details and summary elements, again by Scott O’Hara
- Disclosure widgets by Adrian Roselli
- Details and summary are not…
- Details content showing up in find (Ctrl+F)
Alternative approaches
Using a custom disclosure widget put together with JavaScript and ARIA is not the end of the world. In fact I recently tried my hand at a disclosure widget web component and early impressions are that the combination of fast, async ES modules plus native DOM discovery (which you get with web components) might alleviate the “flicker of content” issue I mentioned at the start.
Summing up
I’d been cautious about using details
for more than cases matching its intended usage but had started thinking the time was right to take it further – possibly using Zach’s web component. However based on the findings shared in the above Notes of caution section I’ve decided to stay safe to keep the user experience predictable and accessible. The behaviour when the user does an in-page search, and the current browser inconsistencies in announcing the summary
as an expand/collapse button tell me that a custom JS and ARIA disclosure widget is better for the custom UI cases.
Min-Max clamp calculator, by 9elements
Here’s a handy tool from the smart folks at 9elements for making a value – such as a font-size, or margin – fluidly responsive. In their words the tool…
calculates the CSS clamp formula to interpolate between two values in a given viewport range.
It’s inspired by Utopia but is for situations when you only need a single clamp formula rather than one for each interval in a type or spacing scale.
Beyond that, the website for this tool just looks great and is choc-full of tricks. It uses some snazzy CSS, includes Zach Leatherman’s details-utils web component for animated disclosures and is made with Astro, Svelte and PostCSS.
A better birthday input, by Vitaly Friedman
I recently signed up to Vitaly from Smashing Mag’s Smart Interface Design Patterns newsletter. This latest edition regarding “date of birth” inputs was interesting, and well timed as my work colleagues and I are about to revisit our form patterns. It’s a nice explainer on why we should approach UI for dates the user knows differently from UI for dates the user will choose.
Vitaly recommends that when asking the user for a very specific date that they already know without needing to consult a calendar, drop-downs and calendar look-ups are unnecessary. And avoiding them is probably ideal, because <input type=date>
and <select>
based interfaces have some usability and accessibility kinks, as do many date-picker libraries.
It’s better to rely on three simple, adjacent text input fields with a label above each field. See GOV.UK’s Date input component for a great example.
Date pickers should only be required when you’re asking for a date that the user will choose (say, booking a holiday or appointment) rather than one they’ll know. Vitaly doesn’t recommend a date picker, but I reckon the date-picker web component from the clever folks behind the Duet Design System could be a good option.
Oh, and this also reminds me that I need to get the finger out and pick up a copy of Adam Silver’s Form Design Patterns.
Interactive type tutorial, from Erik Kennedy
Here’s a handy interactive tool for learning “the logic of great typography” from Erik Kennedy, the man behind the Learn UI Design course.
Tables and pseudo-tables: lessons and tactics
At work I have to think about complex HTML tables a lot. The challenge with doing tables well is that 99% of online table tutorials use fairly simple examples… whereas in reality design and product teams often want to squeeze in lots more. It’s really hard to balance those needs against accessibility, systemisation, styling and responsiveness.
Heads up: I’ve published this post early while it’s still a work in progress because it’s better for me to have it available for reference than languishing in drafts and forgotten. Apologies if you read it in a temporarily rough state.
Following a lot of work on tables I’ve recently gained additional insight into the possibilities and constraints, thanks to an accessibility review by Tetralogical and some great articles by Adrian Roselli.
Here are my new rules of thumb.
Avoid complex recreations of tables with alternate elements
In addition to developing a component wrapping the HTML table
element to handle simple data tables, I recently created an alternate component for “tables with bells and whistles”. It used a combination of the HTML description list element plus CSS Grid plus some display: contents
in lieu of the currently poorly supported subgrid. This approach allowed recreating a table-like appearance but facilitating much more responsive layout flexibility, amongst other benefits.
Unfortunately this resulted in an accessibiliy fail around using the description list in this way. Popular combinations of browsers and assistive technologies do not support description lists sufficiently to convey the intended crucial relationships between the faux table headers and faux table cells.
Note: I think it’s OK to use the description list element in general – just not for such an unconventional and complex use case.
ARIA Grid role: an alternative in theory (if not in practice)
I noted that Github handle their “repository directory indexes” using the ARIA grid role. Their HTML is like this (I’ve abbreviated it a touch):
<div role="grid" aria-labelledby="files" class="…">
<div class="sr-only" role="row">
<div role="columnheader">Type</div>
<div role="columnheader">Name</div>
<div role="columnheader" class="d-none d-md-block">Latest commit message</div>
<div role="columnheader">Commit time</div>
</div>
<!-- interesting 'fake' row here -->
<div role="row" class="…">
<div role="rowheader" class="…">
<a rel="nofollow" title="Go to parent directory" class="…" href="…"><span class="…" style="…">. .</span></a>
</div>
<div role="gridcell" class="…"></div>
<div role="gridcell"></div>
</div>
<!-- first real row -->
<div role="row" class="Box-row Box-row--focus-gray py-2 d-flex position-relative js-navigation-item navigation-focus">
<div role="gridcell" class="…"><svg …></svg></div>
<div role="rowheader" class="…">
<span class="…"><a class="…" href="…">my-file-name.md</a></span>
</div>
<div role="gridcell" class="…">
<span class="…"><a href="…">The commit message</a></span>
</div>
<div role="gridcell" class="…">
<time-ago datetime="2021-06-17T16:45:42Z">11 months ago</time-ago>
</div>
</div>
<!-- more rows go here -->
</div>
I like the idea of looking at alternatives to tables but don’t think I’d take this approach right now. Where there are lots of focusable elements it turns those multiple tab-stops into one (the grid is a single widget) which is perhaps useful for some cases, but I’ve yet to encounter them. It’d also require you to do manual focus management within the widget.
It’s an interesting approach though, and one I’ll keep in the back of my mind.
You can achieve “bells and whistles” within a table accessibly
Here are some handy techniques – done accesibly – courtesy of Adrian Roselli:
- Accessibly including inputs in tables
- Under-engineered responsive tables
- Responsive accessible tables – this more complex approach employs JavaScript to i) apply appropriate ARIA roles to existing table HTML, and ii) create clever alternate labelling using pseudo elements. It uses CSS to change the
display
of the table and its children to create a small-screen-friendly layout. The JS-applied roles serve to maintain the necessary semantics that would otherwise be lost when applying the radical CSS changes. - Charlie Cathcart’s responsive table is similar to the above although perhaps less comprehensive. However it might have other interesting aspects.
- Clip long, overflowing content
- Expandable rows
- Fixed headers
References
- Grids pt1: To grid or not to grid by Sarah Higley
- ARIA Grid as an anti-pattern by Adrian Roselli
Layering elements with Grid rather than positioning
A while back I bookmarked Michelle Barker’s CSS Grid based overlay technique which neatly allows layering one element atop another using CSS Grid rather than absolute positioning. Now, Stephanie Eckles has taken the idea a step further with her Smol Stack Layout which offers a more flexible markup structure, some intuitive grid area naming and a neat aspect-ratio
API.
Stephanie’s component is feature-packed and opinionated to the extent that it took me a while to understand all the moving parts. So for simplicity I’ve created a pared-back version on CodePen: see Layering utility with CSS Grid.
While Michelle’s utility kept the markup really simple with the container doubling-up as the first visual “layer in the cake”, I think for flexibility and robustness I prefer Stephanie’s approach where the container only serves to set the aspect ratio, with the layers represented by two or more child elements.
Layering text upon images
In Smol background picture, Stephanie goes further, leaning on her layering utility to cleverly layer text upon images. This is a modern alternative to the type of effect we previously achieved with background images. It uses a content image marked up using <picture>
to progressively enhance the format (heavier-weight jpg
for old browsers, lightweight webp
for new browsers) and is styled with object-fit: cover
in order to perfectly span its container.
This modern approach is great because often from an accessibility perspective our background images should really be content, described properly with alt
, to provide equivalent visual and non-visual experiences. Furthermore using a content image tends to be better for performance with there now being so many new image techniques and attributes at our disposal when compared to background images. Lastly, handling the image as content makes it more flexible for styling.
Using Grid for a “Hero” Banner
Another noteworthy member of this family of techniques from Stephanie is her Hero with CSS Grid. Here she uses the same idea of a single grid-template-area with child content and image stacked up in layers, alongside some nifty use of grid positioning properties to align elements within that. This one is very flexible, very responsive, and super-useful.
Summing up
I really like this move away from absolute positioning because it always felt brittle. It doesn’t play well with responsive layouts, and isn’t resilient to cases where adjacent elements could overlap. Furthermore you often see absolute positioning used in conjunction with pseudo elements and while I’ve occasionally taken this approach (and appreciate the creativity behind these techniques) I’ll admit I find it much easier to read and maintain CSS that relates to actual structural elements rather than “magical” CSS elements. I much prefer these simple, modern and fit-for-purpose CSS Grid based approaches.