Skip to main content

Journal

GOV.UK visitor stats for January 2022

Thanks once again to Matt Hobbs and GOV.UK for sharing their website visitor stats publicly so that we can learn from them. As ever, lots of juicy detail in Matt’s thread.

GOV.UK stats for January (1-31):

- Chrome - 45.08%

- Safari - 36.82%

- Edge - 7.38%

- Samsung Internet - 7.08%

- Firefox - 1.35%

- Android Webview - 0.72%

- Safari (in-app) - 0.61%

- Internet Explorer - 0.5%

100% = 187,969,863

#browserstats

—Matt Hobbs, @TheRealNooshu

In particular, their “usage by device type” stats see mobile at ~67%, Desktop at ~30.5%, Tablet at ~2.5%.

In terms of comparative traffic, according to Simliar Web’s Top 10 most visited UK websites list they’re hovering around #10.

Skip to Content: Online Accessibility Insights from Léonie Watson

Here’s a lovely, short (13 min) interview from an accessibility expert with a really positive outlook—highly recommended.

Q: What’s just one thing that every single person can do in the progression toward an accessible internet?

A: When you’re talking to colleagues, peers… promote the notion that accessibility is just part of what we do because we’re good at our job. It’s not extraordinary, it’s not unusual, it’s not something you can drop because you’re pushing for launch.


Division and construction in design systems

Over the last couple of days I’ve been watching an interview with Brad Frost on Storybook’s channel. I’m still only halfway through but it’s great so far.

One part I’m loving is, from about 25 mins in, when Brad talks abut how Atomic Design crucially includes the notion of not only “breaking interfaces down” (like every DS does) but also “building them back up”. It’s not just the atoms and molecules that are important, but also combining them into (in Atomic Design parlance) organisms and templates, too. For example when using Storybook as an internal workshop (in my team our equivalent is LookBook), he makes a point of it not just including components but also templates, so that:

we can internally test with a high degree of confidence before handing over to our user-consumers that when our components are assembled together, they work”.

I like the idea of our workshop containing not just components but also multicomponent arrangements, or even full page templates. It’d mean less need to go arrange this stuff in the consuming application all the time. Brad’s chat also chimes with some recent thoughts I’ve been having about Patterns and also a tweet from Heydon Pickering regarding a catalogue vs a system.

Essentially, I think that in component libraries, notions of hierarchy and composition are really important. Simply having “a catalogue of components” (including lots that are common to all Design Systems) might not hugely separate your library from Bootstrap or Material. However it’s our ability to combine our custom legos into specific higher order arrangements, and our care for making sure they combine together harmoniously that creates our own special sauce.

What open-source design systems are built with web components?

Alex Page, a Design System engineer at Spotify, has just asked:

What open-source design systems are built with web components? Anyone exploring this space? Curious to learn what is working and what is challenging. #designsystems #webcomponents

And there are lots of interesting examples in the replies.

I plan to read up on some of the stories behind these systems.

I really like Web Components but given that I don’t take a “JavaScript all the things” approach to development and design system components, I’ve been reluctant to consider that web components should be used for every component in a system. They would certainly offer a lovely, HTML-based interface for component consumers and offer interoperability benefits such as Figma integration. But if we shift all the business logic that we currently manage on the server to client-side JavaScript then:

  • the user pays the price of downloading that additional code;
  • you’re writing client-side JavaScript even for those of your components that aren’t interactive; and
  • you’re making everything a custom element (which as Jim Neilsen has previously written brings HTML semantics and accessibility challenges).

However maybe we can keep the JavaScript for our Web Component-based components really lightweight? I don’t know. For now I’m interested to just watch and learn.

My first Web Component: a disclosure widget

After a couple of years of reading about web components (and a lot of head-scratching), I’ve finally got around to properly creating one… or at least a rough first draft!

Check out disclosure-widget on codepen.

See also my pen which imports and consumes the component.

Caveats and to-dos:

  • I haven’t yet tried writing tests for a web component
  • I should find out how to refer to the custom element name in JavaScript without repeating it
  • I should look into whether observedAttributes and attributeChangedCallback are more appropriate than the more typical event listeners I used

References

I found Eric Bidelman’s article Custom Elements v1: Reusable Web Components pretty handy. In particular it taught me how to create a <template> including a <slot> to automatically ringfence the Light DOM content, and then to attach that template to the Shadow DOM to achieve my enhanced component.

Saving CSS changes in DevTools without leaving the browser

Scott Jehl recently tweeted:

Browser devtools have made redesigning a site such a pleasure. I love writing and adjusting a CSS file right in the sources panel and seeing design changes happen as I type, and saving it back to the file. (…) Designing against live HTML allows happy accidents and discoveries to happen that I wouldn't think of in an unconstrained design mockup

I feel very late to the party here. I tend to tinker in the DevTools Element Styles panel rather than save changes. So, inspired by Scott, I’ve just tried this out on my personal website. Here’s what I did.

  1. started up my 11ty-based site locally which launches a localhost URL for viewing it in the browser;
  2. opened Chrome’s DevTools at Sources;
  3. checked the box “Enable local overrides” then followed the prompts to allow access to the folder containing my SCSS files;
  4. opened an SCSS file in the Sources tab for editing side-by-side with my site in the browser;
  5. made a change, hit Cmd-S to save and marvelled at the fact that this updated that file, as confirmed by a quick git status check.
  6. switched to the Elements panel, opened its Styles subpanel, made an element style change there too, then confirmed that this alternative approach also saves changes to a file.

This is a really interesting and efficient way of working in the browser and I can see me using it.

There are also a couple of challenges which I’ll probably want to consider. Right now when I make a change to a Sass file, the browser takes a while to reflect that change, which diminishes the benefit of this approach. My site is set up such that Eleventy watches for changes to the sass folder as a trigger for rebuilding the static site. This is because for optimal performance I’m purging the compiled and combined CSS and inlining that into the <head> of every file… which unfortunately means that when the CSS is changed, every file needs rebuilt. So I need to wait for Eleventy to do its build thing until the page I’m viewing shows my CSS change.

To allow my SCSS changes to be built and reflected faster I might consider no longer inlining CSS, or only inlining a small amount of critical stuff… or maybe (as best of all worlds) only do the inlining for production builds but not in development. Yeah, I like that latter idea. Food for thought!

Partnering with Google on web.dev (on adactio.com)

At work in our Design System team, we’ve been doing a lot of content and documentation writing for a new reference website. So it was really timely to read Jeremy Keith of Clearleft’s new post on the process of writing Learn Responsive Design for Google’s web.dev resource. The course is great, very digestible and I highly recommend it to all. But I also love this new post’s insight into how Google provided assistance, provided a Content handbook as “house style” for writing on web.dev and managed the process from docs and spreadsheets to Github. I’m sure there will be things my team can learn from that Content Handbook as we go forward with our technical writing.

Theming to optimise for user colour scheme preference

“Dark mode” has been a buzz-phrase in web development since around 2019. It refers to the ability provided by modern operating systems to set the user interface’s appearance to either light or dark. Web browsers and technologies support this by allowing developers to detect whether or not the OS provides such settings, and if so which mode the user prefers. Developers can create alternate light and dark themes for their websites and switch between these intelligently (responsively?) to fit with the user’s system preference.

I’ve been meaning to do some work on this front for a while and finally got around to it. (You might even be reading this post with your computer’s dark colour scheme enabled and seeing the fruits of my labour.) Here’s how I set things up and the lessons I learned along the way.

Switching your computer’s appearance

On a Mac:

System Preferences > General > Appearance

On Windows:

Colors > Choose your color

On iOS:

Settings > Display & Brightness > Appearance

On Android:

Settings > Dark Theme

Emulating this in browser DevTools

In Chromium-based browsers you can open DevTools, then open the Rendering tool (which might be hidden behind More Tools). In the Emulate CSS media feature prefers-color-scheme dropdown, select prefers-color-scheme: dark or prefers-color-scheme: light.

The theme-color HTML meta tag

You can use the theme-color HTML meta tag to indicate to the browser a colour it can use to customise the display of the page and surrounding elements such as the address bar. The reason we have a meta tag solution to this rather than leaving it to CSS is performance; it allows the browser to make the relevant updates immediately.

In practice you might specify your “highlight colour”—Clearleft currently use their signature green. Alternatively you could specify both your light theme and dark theme background colours, using the media attribute to associate each with the user colour scheme preference it is optimised for. This is the approach I chose.

<!-- Set theme color to white when user prefers light mode -->
<meta name="theme-color" content="rgb(255,255,255)" media="(prefers-color-scheme: light)">
<!-- Set theme color to a custom black when user prefers dark mode -->
<meta name="theme-color" content="rgb(38,38,38)" media="(prefers-color-scheme: dark)">

The theme-color meta tag has mixed support. It works well in Safari and iOS Safari. Meanwhile Chrome only applies the colour on installed progressive web apps (PWAs).

This had me considering PWA matters again for the first time in a while. I previously definined a PWA “theme colour” for my website in my manifest.manifest file. However unlike in the theme-color meta tag approach, the manifest allows defining one theme colour only. While I don’t think there’d be any issue in having both the meta tag and manifest value in play simultaneously (my understanding is that the HTML would take priority over the manifest), I decided to keep things simple and removed theme_color from my manifest file for now.

Note: the w3c manifest spec may support multiple theme colours in future.

The color-scheme meta tag

The color-scheme meta tag is used to specify one or more color schemes/modes with which the page is compatible. Unlike theme-color you don’t provide an arbitrary colour value, but rather one of light or dark or both in combination. This tells the browser whether it can change default background, foreground and text colours to match the current system appearance. As Jim Nielsen notes in Don’t forget the color-scheme property, it gives the browser permission to automatically change standard form controls, scroll bars, and other named system colors.

I include this meta tag on each page (just after my theme-color meta tags). I indicate that my styles have been prepped to handle the browser applying either light or dark colour schemes and—via the order of values in the content attribute—that I prefer light.

<meta name="color-scheme" content="light dark">

Notes:

  1. I’ve also seen <meta name="supported-color-schemes"> however Thomas Steiner explained that this is an old syntax and has since been standardised as <meta name="color-scheme">;
  2. There is also a color-scheme CSS property, which I’ll come to later. Once again though, having an HTML meta tag helps browsers to apply things faster;
  3. although I’m currently intimating that I prefer light, in future I might update this to dark first (assuming I don’t hear of any reasons against it). The dark colour palette is really growing on me!

Ensuring colours are accessible

While working on a new dark colour palette and tweaking my light palette I made sure to check that colour contrast met accessibility requirements.

Useful tools on this front include:

  • Activating Chrome’s element inspector (the “box with arrow at bottom-right” icon) enables hovering an element to check the contrast of text against background;
  • Erik Kennedy’s Accessible Color Generator provides slightly modified colour alternatives when contrast is insufficient—really handy and I used this a couple of times;
  • Are my colors accessible? is another great “check contrast, digest results, then tweak” tool which provides more detailed information than the Chrome inspector, especially regarding the impact of small text on contrast.

Design Tokens

It quickly became clear that I’d need global colour settings that I could use across multiple technologies and multiple files. For example, I’d want to reuse the same custom background colour value in an HTML theme-color meta tag, in CSS, and perhaps also in a JSON-based manifest file.

I’d previously bookmarked Heydon Pickering’s article on design tokens in Eleventy and now was the time to give it a spin.

I created _data/tokens.json in which I defined raw tokens such as colorDark, colorDarker and colorLight.

Then in my Nunjucks-based HTML templates I could access that token data to define meta tag values using {{ tokens.colorLight }}. These values would be interpolated to the real CSS colour values during build.

I also created a new Nunjucks file, theme_css.njk, adding permalink: "css/theme.css" in its frontmatter so that it’d generate a CSS file. This file maps my design tokens to custom properties set on the root element, something like this:

:root {
  --color-dark: {{ tokens.colorDark }};
  --color-darker: {{ tokens.colorDarker }};
  --color-light: {{ tokens.colorLight }};
  --color-grey: {{ tokens.colorGrey }};
  --color-highlight: {{ tokens.colorHighlight }};
  --color-highlight-dark: {{ tokens.colorHighlightDark }};
  --color-highlight-darker: {{ tokens.colorHighlightDarker }};
  --color-text: {{ tokens.colorText }};
}

Custom properties FTW

Using custom properties allowed me to do the hard work of preparing my light and dark themes upfront and removed the need to constantly duplicate values and write code forks throughout my CSS.

Having previously created a base layer of reusable custom property representations of my design tokens, I began creating more specific custom properties to serve different contexts.

:root {
  --color-page-bg-light: var(--color-light);
  --color-page-bg-dark: var(--color-dark);
  --color-ink-dark: var(--color-text);
  --color-ink-light: var(--color-light);
}

CSS for default and dark-mode contexts

Now to set my light-mode defaults and fork these when the user prefers dark-mode.

Here’s my CSS:

:root {
  color-scheme: light;

  --color-highlight: var(--color-highlight-darker);
  --color-page-bg: var(--color-page-bg-light);
  --color-band: var(--color-darker);
  --color-ink: var(--color-ink-dark);
  --color-ink-offset: var(--color-grey);

  @media (prefers-color-scheme: dark) {
    color-scheme: dark;

    --color-highlight: var(--color-highlight-dark);
    --color-page-bg: var(--color-page-bg-dark);
    --color-band: var(--color-darker);
    --color-ink: var(--color-ink-light);
    --color-ink-offset: var(--color-grey);
  }

  accent-color: var(--color-highlight);
}

body {
  background-color: var(--color-page-bg);
  color: var(--color-ink);
}

Let’s break that down.

The color-scheme property allows us to specify one or more colour schemes/modes with which an element is compatible. I’m defining it on the root element i.e. for the whole page. My approach was to start by specifying support for a light colour scheme only, then define background and text colour custom properties with values optimised for light colour scheme.

Using @media (prefers-color-scheme: dark) {…} we can check the user’s colour scheme preference. When the user prefers dark, I change color-scheme to dark to let the browser do its “set sensible defaults” thing, and I update the custom property values to those optimised to blend with a dark appearance.

The reusable, theme-sensitive custom properties I’ve plumped for are:

  • highlight colour: really just my brand colour, although lightened a touch in dark mode for better contrast;
  • page background colour;
  • “band” background colour: something I’d use as a band of alternative background colour to distinguish special sections like the header or footer;
  • ink colour: my default text colour;
  • “offset” ink colour: a grey for little bits of meta text like dates and categories.

I’m sure I’ll evolve these over time.

Lastly, the accent-colour CSS property is used by some form controls e.g. radios and checkboxes. I set that to my highlight colour with the intention of creating a more branded experience.

SVG considerations

My SVG-based logo didn’t look right in dark mode, however the fix was pretty simple. I applied BEM-style element classes to any problematic path elements of the SVG then wrote CSS for those. The CSS tests for prefers-color-scheme: dark and updates the path’s fill or stroke colour as necessary.

What about leaving everything to the browser?

Having read Jim Nielsen’s brilliant article on CSS System Colors I tried feeding the browser color-scheme: light dark, removing my arbitrary dark theme colours, and leaving the colour palette entirely up to the browser. Along the way I learned some interesting lessons on system colours—which we can also choose to use as valid CSS colours in our custom components—such as Canvas and CanvasText.

I love this idea in principle! However in practice:

  • only Safari’s colour palette looks consistent with the rest of the Mac OS. The palette applied by Chrome doesn’t; it has its own, different “black”. So for the control you’ve given away, you don’t necessarily achieve that nice “consistency with the OS” reward in return;
  • as far as I know you can’t lighten or darken the system colours so it’s hard to create a multi-tone, complimentary palette, and also be confident in achieving sufficient colour contrast. That’s fine if you only need a single background colour for the entire page with no alternate bands of colour (like on Jim’s blog) however I think that’s a little restrictive. (Maybe I’m getting too hung up on control here though, and introducing additional arbitrary colours would work fine alongside a variable “system black”);
  • Firefox and iOS Safari are a little problematic in their support for the technologies involved, leading to writing a few hacky workarounds.

For the combined reasons above I’m sticking with manually defined colours for now (however I have a pull request I can revisit later if the mood takes).

What could I do better?

With extra time, I might:

  • think more deeply about dark theme design, perhaps following some of the tips regarding shadows, depth and colour contrast in CSS Tricks’ A complete guide to dark mode on the web;
  • consider providing a theme switcher control to allow the user to choose the website theme they want regardless of the current OS appearance. (But I probably won’t; I’m not sure it’s necessary)

References

Building a toast component (by Adam Argyle)

Great tutorial (with accompanying video) from Adam Argyle which starts with a useful definition of what a Toast is and is not:

Toasts are non-interactive, passive, and asynchronous short messages for users. Generally they are used as an interface feedback pattern for informing the user about the results of an action. Toasts are unlike notifications, alerts and prompts because they're not interactive; they're not meant to be dismissed or persist. Notifications are for more important information, synchronous messaging that requires interaction, or system level messages (as opposed to page level). Toasts are more passive than other notice strategies.

There are some important distinctions between toasts and notifications in that definition: toasts are for less important information and are non-interactive. I remember in a previous work planning exercise regarding a toast component a few of us got temporarily bogged down in working out the best JavaScript templating solution for SVG icon-based “Dismiss” buttons… however we were probably barking up the wrong tree with the idea that toasts should be manually dismissable.

There are lots of interesting ideas and considerations in Adam’s tutorial, such as:

  • using the <output> element for each toast
  • some crafty use of CSS Grid and logical properties for layout
  • combining hsl and percentages in custom properties to proportionately modify rather than redefine colours for dark mode
  • animation using keyframes and animation
  • native JavaScript modules
  • inserting an element before the <body> element (TIL that this is a viable option)

Thanks for this, Adam!

(via Adam’s tweet)

There’s some nice code in here but the demo page minifies and obfuscates everything. However the toast component source is available on GitHub.

External Link Bookmark Note Entry Search