Matthias Ott – Painting With the Web – beyond tellerrand Düsseldorf 20025 - YouTube
A great talk by Matthias on what you can do with web standards today!
A great talk by Matthias on what you can do with web standards today!
I was at the State Of The Browser event recently, which was great as always.
Manu gave a great talk about colour in CSS. A lot of it focused on OKLCH. I was already convinced of the benefits of this colour space after seeing a terrific talk by Anton Lovchikov a while back.
After Manu’s talk, someone mentioned that even though OKLCH is well supported in browsers now, it’s a shame that it isn’t (yet) in design tools like Figma. So designers are still handing over mock-ups with hex values.
I get the frustration, but in my experience it’s not that big a deal in practice. Here’s why: oklch()
isn’t just a way of defining colours with lightness, chroma, and hue in CSS. It’s also a function. You can use the magical from
keyword in this function to convert hex colours to l, c, and h:
--page-colour: oklch(from #49498D l c h);
So even if you’re being handed hex colour values, you can still use OKLCH in your CSS. Once you’re doing that, you can use all of the good stuff that comes with having those three values separated out—something that was theoretically possible with hsl
, but problematic in practice.
Let’s say you want to encode something into your CSS like this: “if the user has specified that they prefer higher contrast, the background colour should be four times darker.”
@media (prefers-contrast: more) {
--page-colour: oklch(from #49498D calc(l / 4) c h);
}
It’s really handy that you can use calc()
within oklch()
—functions within functions. And I haven’t even touched on the color-mix()
function.
Hmmm …y’know, this is starting to sound an awful lot like functional programming:
Functional programming is a programming paradigm where programs are constructed by applying and composing functions. It is a declarative programming paradigm in which function definitions are trees of expressions that map values to other values.
Everyone is quite rightly linking to this great interactive explainer on colour. It does a great job of describing complex concepts in a clear accessible way.
When you think of heraldry what comes to mind is probably knights in shining armor, damsels in distress, jousting, that sort of thing. Medieval stuff. But I prefer to think of it as one of the earliest design systems.
This totally checks out.
I had a lot of fun making the website for Patterns Day.
If you’re interested in the tech stack, here’s what I used:
Actually, technically it’s all HTML because the styles are inside a style
element rather than a separate style sheet, but you know what I mean. Also, there is technically some JavaScript but all it does is register a service worker that takes care of caching and going offline.
I didn’t use any build tools. There was no pipeline. There is no node_modules
folder filling up my hard drive. Nothing was automated. The website was hand-crafted the long hard stupid way.
I started with the content. I wrote out the words and marked them up with the most appropriate HTML elements.
Time to layer on the presentation.
For the design, I turned to Michelle for help. I gave her a brief, describing the vibe of the conference, and asked her to come up with an appropriate visual language.
Crucially, I asked her not to design a website. Instead I asked her to think about other places where this design language might be used: a poster, social media, anything but a website.
Partly I was doing this for my own benefit. If you give me a pixel-perfect design for a web page and tell me to code it up, either I won’t do it or I won’t enjoy it. I just don’t get any motivation out of that kind of direct one-to-one translation.
But give me guardrails, give me constraints, give me boundary conditions, and off I go!
Michelle was very gracious in dealing with such a finicky client as myself (“Can you try this other direction?”, “Hmm… I think I preferred the first one after all!”) She delivered a colour palette, a type scale, typeface choices, and some wonderful tiling patterns …it is Patterns Day after all!
With just a few extra lines of CSS, the basic typography was in place.
I started layering on the colours. Even though this was a one-page site, I still made liberal use of custom properties in the CSS. It just feels good to be able to update one value and see the results, well …cascade.
I had a lot of fun with the tiling background images. SVG was the perfect format for these. And because the tiles were so small in file size, I just inlined them straight into the CSS.
By this point, I felt like I was truly designing in the browser. Adjusting spacing, playing around with layout, and all that squishy stuff. Some of the best results came from happy accidents—the way that certain elements behaved at certain screen sizes would lead me into little experiments that yielded interesting results.
I’m not sure it’s possible to engineer that kind of serendipity in Figma. Figma was the perfect tool for exploring ideas around the visual vocabulary, and for handing over design decisions around colour, typography, and texture. But when it comes to how the content is going to behave on the World Wide Web, nothing beats a browser for fidelity.
By this point I was really sweating the details, like getting the logo just right and adjusting the type scale for different screen sizes. Needless to say, Utopia was a godsend for that.
I was also checking back in with Michelle to get her take on design decisions I was making.
I could’ve kept tinkering but the diminishing returns were a sign that it was time to put this out into the world.
It felt really good to work on a web page like this. It felt like I was getting my hands into the soil of the web. I don’t think it’s an accident that the result turned out to be very performant.
Getting hands-on like this stops me from getting rusty. And honestly, working with CSS these days is a joy. There’s such power to be had from using var()
in combination with functions like calc()
and clamp()
. Layout is a breeze with flexbox
and grid
. Browser differences are practically non-existent. We’ve never had it so good.
Here’s something I noticed about my relationship to CSS; my brain has finally made the switch to logical properties. Now if I’m looking at some CSS and I see left
, right
, top
, or bottom
, it looks like a bug to me. Those directional properties feel loaded with assumptions whereas logical properties feel much more like working with the grain of the web.
Unusual colour combinations that are also accessible—keep smashing that “New colors” button.
This is a terrrific presentation by Chris, going through some practical implementations of modern CSS: logical properties, viewport units, grid, subgrid, container queries, cascade layers, new colour spaces, and view transitions.
It’s often said that it’s easier to make a fast website than it is to keep a website fast. Things slip through. If you’re not vigilant, performance can erode without you noticing.
It’s a similar story for other invisible but important facets of your website: privacy, security, accessibility. Because they’re hidden from view, you won’t be able to see if there’s a regression.
That’s why it’s a good idea to have regular audits for performance, privacy, security, and accessibility.
I wrote about accessibility testing a while back, and how there’s quite a bit that you can do for yourself before calling in an expert to look at the really gnarly stuff:
When you commission an accessibility audit, you want to make sure you’re getting the most out of it. Don’t squander it on issues that you can catch and fix yourself. Make sure that the bulk of the audit is being spent on the specific issues that are unique to your site.
I recently did an internal audit of the Clearleft website. After writing up the report, I also did a lunch’n’learn to share my methodology. I wanted to show that there’s some low-hanging fruit that pretty much anyone can catch.
To start with, there’s keyboard navigation. Put your mouse and trackpad to one side and use the tab
key to navigate around.
Caveat: depending on what browser you’re using, you might need to update some preferences for keyboard navigation to work on links. If you’re using Safari, go to “Preferences”, then “Advanced”, and tick “Press Tab to highlight each item on a web page.”
Tab around and find out. You should see some nice chunky :focus-visible
styles on links and form fields.
Here’s something else that anyone can do: zoom in. Increase the magnification to 200%. Everything should scale proportionally. How about 500%? You’ll probably see a mobile-friendly layout. That’s fine. As long as nothing is broken or overlapping, you’re good.
At this point, I reach for some tools. I’ve got some bookmarklets that do similar things: tota11y and ANDI. They both examine the source HTML and CSS to generate reports on structure, headings, images, forms, and so on.
These tools are really useful, but you need to be able to interpret the results. For example, a tool can tell you if an image has no alt
text. But it can’t tell you if an image has good or bad alt
text.
Likewise, these tools are great for catching colour-contrast issues. But there’s a big difference between a colour-contrast issue on the body copy compared to a colour-contrast issue on one unimportant page element.
I think that demonstrates the most important aspect of any audit: prioritisation.
Finding out that you have accessibility issues isn’t that useful if they’re all presented as an undifferentiated list. What you really need to know are which issues are the most important to fix.
By the way, I really like the way that the Gov.uk team prioritises accessibility concerns:
The team puts accessibility concerns in 2 categories:
- Theoretical: A question or statement regarding the accessibility of an implementation within the Design System without evidence of real-world impact.
- Evidenced: Sharing new research, data or evidence showing that an implementation within the Design System could cause barriers for disabled people.
The team will usually prioritise evidenced issues and queries over theoretical ones.
When I wrote up my audit for the Clearleft website, I structured it in order of priority. The most important things to fix are at the start of the audit. I also used a simple scale for classifying the severity of issues: low, medium, and high priority.
Thankfully there were no high-priority issues. There were a couple of medium-priority issues. There were plenty of low-priority issues. That’s okay. That’s a pretty good distribution.
If you’re interested, here’s the report I delivered…
There are a few issues with the pink colour. When it’s used on a grey background, or when it’s used as a background colour for white text, the colour contrast isn’t high enough.
The SVG arrow icon could be improved too.
--red
is currently rgb(234, 33, 90)
. Change it to rgb(210, 20, 73)
(thanks, James!)currentColor
. Consider hardcoding solid black (or a very, very dark grey) instead.Alt text is improving on the site. There’s reasonable alt text at the top level pages and the first screen’s worth of case studies and blog posts. I made a sweep through these pages a while back to improve the alt text but I haven’t done older blog posts and case studies.
The site is using headings sensibly. Sometimes the nesting of headings isn’t perfect, but this is a low priority issue. For example, on the contact page there’s an h1
followed by two h3
s. In theory this isn’t correct. In practice (for screen reader users) it’s not an issue.
h3
instead of h1
.h3
headings for the industry sector (“Charities”, “Education” etc.) but these should probably not be headings at all. On the blog index page we use a class “Tags” for a similar purpose. Consider reusing that pattern on the case studies index page.h3
and the subsequent three headings are h2
s. Ideally this would be reversed: a single h2
followed by three h3
s.Sometimes the same text is used for different links.
The only form on the site is the newsletter sign-up form. It’s marked up pretty well: the input
has an associated label
, although a visible (clickable) label
would be better.
The site doesn’t use JavaScript to mess with tabbing order for keyboard users. The source order of elements in the markup generally makes sense so all is good.
The focus styles are nice and clear too!
The site is using HTML landmark elements sensibly (header
, nav
, main
, footer
, etc.).
While I’m talking about the SVGs on The Session, I thought I’d share something else related to the rendering of the sheet music.
Like I said, I use the brilliant abcjs JavaScript library. It converts ABC notation into sheet music on the fly, which still blows my mind.
If you view source on the rendered SVG, you’ll see that the path
and rect
elements have been hard-coded with a colour value of #000000
. That makes sense. You’d want to display sheet music on a light background, probably white. So it seems like a safe assumption.
Ah, but when it comes to front-end development, assumptions are like little hidden bombs just waiting to go off!
I got an email the other day:
Hi Jeremy,
I have vision problems, so I need to use high-contrast mode (using Windows 11). In high-contrast mode, the sheet-music view is just black!
Doh! All my CSS adapts just fine to high-contrast mode, but those hardcoded hex values in the SVG aren’t going to be affected by high-contrtast mode.
Stepping back, the underlying problem was that I didn’t have a full separation of concerns. Most of my styling information was in my CSS, but not all. Those hex values in the SVG should really be encoded in my style sheet.
I couldn’t remove the hardcoded hex values—not without messing around with JavaScript beyond my comprehension—so I made the fix in CSS:
[fill="#000000"] {
fill: currentColor;
}
[stroke="#000000"] {
stroke: currentColor;
}
That seemed to do the trick. I wrote back to the person who had emailed me, and they were pleased as punch:
Well done, Thanks! The staff, dots, etc. all appear as white on a black background. When I click “Print”, it looks like it still comes out black on a white background, as expected.
I’m very grateful that they brought the issue to my attention. If they hadn’t, that assumption would still be lying in wait, preparing to ambush someone else.
In design, both in the digital and physical worlds, color should never be the sole indicator of meaning. A simple test: if your work was converted to grayscale, would it still be usable?
Andy describes life online with deuteranopia and dispenses some practical advice for designers:
If there’s any uncertainty, adding labels, icons, or textures to each meaningful color of your design will make it accessible to many more people, regardless of their ability to perceive color.
This is a genuinely lovely use of machine learning models: provide a prompt for an illustration to print out and colour in.
Mike explains his motivation for building this:
My son’s super into colouring at the moment and I’ve been struggling to find new stuff for him.
I like this approach to offering a design system. It seems less prescriptive than many:
Designed not as a rule set, but rather a toolbox, the Data Design Language includes a chart library, design guidelines, colour and typographic style specifications with usability guidance for internationalization (i18n) and accessibility (a11y), all reflecting our data design principles.
A lovely website (or web book?) dedicated entirely to colour contrast, complete with interactive illustrative widgets.
A comprehensive guide for exploring and learning about the theory, science, and perception of color and contrast.
This is a thoughtful proposal for a browser feature from Bram. Very convincing!
A fascinating four-part series by Lisa Charlotte Muth on colour in data visualisations:
At first glance, this looks like a terrible idea. But the key is in the implementation. In this case, the implementation is truly awful.
The section on detecting “auto dark theme” is, as far as I can tell, not intended as a joke.
Mind you, this could all be a galaxy-brain idea to encourage more developers to provide their own dark mode styles. (In much the same way that AMP was supposed to encourage better performance.)
I was doing some accessibility work with a client a little while back. It was mostly giving their site the once-over, highlighting any issues that we could then discuss. It was an audit of sorts.
While I was doing this I started to realise that not all accessibility issues are created equal. I don’t just mean in their severity. I mean that some issues can—and should—be caught early on, while other issues can only be found later.
Take colour contrast. This is something that should be checked before a line of code is written. When designs are being sketched out and then refined in a graphical editor like Figma, that’s the time to check the ratio between background and foreground colours to make sure there’s enough contrast between them. You can catch this kind of thing later on, but by then it’s likely to come with a higher cost—you might have to literally go back to the drawing board. It’s better to find the issue when you’re at the drawing board the first time.
Then there’s the HTML. Most accessibility issues here can be caught before the site goes live. Usually they’re issues of ommission: form fields that don’t have an explicitly associated label
element (using the for
and id
attributes); images that don’t have alt
text; pages that don’t have sensible heading levels or landmark regions like main
and nav
. None of these are particularly onerous to fix and they come with the biggest bang for your buck. If you’ve got sensible forms, sensible headings, alt
text on images, and a solid document structure, you’ve already covered the vast majority of accessibility issues with very little overhead. Some of these checks can also be automated: alt
text for images; label
s for inputs.
Then there’s interactive stuff. If you only use native HTML elements you’re probably in the clear, but chances are you’ve got some bespoke interactivity on your site: a carousel; a mega dropdown for navigation; a tabbed interface. HTML doesn’t give you any of those out of the box so you’d need to make your own using a combination of HTML, CSS, JavaScript and ARIA. There’s plenty of testing you can do before launching—I always ask myself “What would Heydon do?”—but these components really benefit from being tested by real screen reader users.
So if you commission an accessibility audit, you should hope to get feedback that’s mostly in that third category—interactive widgets.
If you get feedback on document structure and other semantic issues with the HTML, you should fix those issues, sure, but you should also see what you can do to stop those issues going live again in the future. Perhaps you can add some steps in the build process. Or maybe it’s more about making sure the devs are aware of these low-hanging fruit. Or perhaps there’s a framework or content management system that’s stopping you from improving your HTML. Then you need to execute a plan for ditching that software.
If you get feedback about colour contrast issues, just fixing the immediate problem isn’t going to address the underlying issue. There’s a process problem, or perhaps a communication issue. In that case, don’t look for a technical solution. A design system, for example, will not magically fix a workflow issue or route around the problem of designers and developers not talking to each other.
When you commission an accessibility audit, you want to make sure you’re getting the most out of it. Don’t squander it on issues that you can catch and fix yourself. Make sure that the bulk of the audit is being spent on the specific issues that are unique to your site.
A wonderful bit of spelunking into the annals of software interfaces by Elise Blanchard.
There’s a good discussion here (kicked off by Jen) about providing different theme-color
values in a web app manifest to match prefers-color-scheme
in media queries.
Accidental colour palettes captured in the wild.