Transcript: The impact that high quality mark-up can have on accessibility, performance, and discoverability
If you are interested in web accessibility, building a personal web site is a great way to get practical experience. You don't need to use frameworks or content management systems. Using Semantic HTML, CSS, and a little JavaScript we can address some web accessibility fundamentals.
I've recently made my own simple web site and learned a lot.
In this video I share what I learned about:
- Using GitHub pages to host a site.
- Landmarks and their benefits for those who use screen readers.
- Making a hamburger menu accessible through using Accessible Rich Internet Application attributes (ARIA).
- Scroll to top buttons and the important of accounting for those who prefer reduced motion
- Creating a light and a dark theme that accounts for operating system preference and also allows viewers to toggle between them.
- How I attempted to future-proof my colour choices by accounting for the Accessible Perceptual Contrast Algorithm (APCA) which will be used in the next generation of the Web Content Accessibility Guidelines.
- How to use JavaScript to change ARIA attributes.
I'll be referring to the Web Content Accessibility Guidelines, using worked examples, and giving demonstrations using the NVDA screen reader.
NVDA: Main menu, menu button, collapsed, sub-menu. Expanded.
I'll also share what I learned on the way about performance and discoverability.
I'm still learning. No doubt there are mistakes or errors, so let me know in the comments. This video has captions. On my web site you can find all the links I refer to and a full, hyperlinked transcript. Originally, I gave this presentation as part of a "show and tell" for my colleagues, I've edited the presentation to share here on YouTube.
Alright! Let's get started!
Hi everyone, today were going to consider the impact that high quality mark-up can have on accessibility, performance, and discoverability. This is based on my real-world experiences from building a personal site on GitHub pages. Here's a brief list of what I will cover and give practical examples of.
Now, I chose GitHub pages because the URL you get has some credibility even though it's free, and the site is really fast due to their Content Delivery Network. My workflow was really simple: I prepare files in Notepad, save them in a shared directory I could access from different devices, and GitHub has a desktop app that will publish the pages online. It's just like the old days but you're not using FTP, you're using the GitHub desktop app.
So, what did I learn?
Let's start with layout. It's your typical responsive layout. I've used colours to make the different sections a bit clearer for you. Responsiveness brings to mind this important Web Content Accessibility Criterion. Reflow is expected now. We're responsible for ensuring that our services at the University of Southampton deliver this basic requirement.
The brilliant Una Kravets has a wonderful video on YouTube sharing 10 modern layouts in a line of CSS.
Let's consider one way that high quality semantic mark-up impacts accessibility.
We can use semantic HTML to declare landmarks for different parts of a page. So, we could say this is the header and footer. This is the navigation. This is the main content. And a defined article within it. And this is the sidebar, tagged as an aside. In my case I've broken this down into sections.
It's easy to forget what we lose if we cannot view a site, we miss having that "at a glance" view of the structure and nature of the content. Using a screen reader, we can navigate between these landmarks, as long as they have been declared – either with semantic HTML or using ARIA roles. This can help a screen reader user to get a feel for the structure of a page and to move quickly between landmarks. A course page on Blackboard, for example, has three navigational landmarks to traverse before you get to the content.
Using the NVDA screen reader, the header is declared the "banner landmark". Navigation is "navigation landmark". The main section is "main landmark". The aside or sidebar is the "complementary landmark". And the footer is the content info landmark.
The success criterion Info and Relationships is intended to ensure that information and relationships that are implied by visual or auditory formatting are preserved when the presentation format changes. Using landmarks to identify regions of a page is one of the ‘sufficient techniques' for meeting this criterion.
The accessibility insights browser plugin has a tool that reveals how landmarks are used on a page. Why not try it out on the sites you use, maintain, or support?
36% said you use simplified views or reader modes. Using semantic landmarks is an effective way to ensure that the content that should be shown is identified.
To conclude our look at layout, reflow is an obvious requirement. Use of landmarks has many benefits, particularly for screen reader users and reader modes.
On to navigation. I followed this guide from W3 Schools on implementing a responsive navigation menu. My site is really basic and simple, there's only five links in the menu. On a smaller screen a hamburger button is used to reveal the menu.
Using the method was a good way to identify what was missing, in this video I test it with a screen reader. Listen carefully to what the screen reader announces and pay attention to the focus order. Let's take a look.
NVDA: "Menu, menu button, submenu".
So, I've selected the button but how would a screen reader know that anything has actually happened. And look! The focus has moved to the browser controls instead of the next menu item.
NVDA: "Tab bar, tab control, tab actions menu, nav demo, new tab, toolbar, address, zoom, add this, in private settings and more, nav demo document, home link"
So, we saw that when the hamburger menu is activated there is no confirmation that something has changed, and when we tab from the hamburger button, we had to tab all through the browser controls until we got to the menu items.
Here is the mark-up I had already done a bit of tidying and made some initial improvements. The hamburger is a link with a role of button, which isn't necessarily bad but it's definitely not best practice. Using a semantic button would be more appropriate. It also appears at the end of the list, explaining why focus moves out of the navigation after the hamburger was selected. The hamburger icon uses font awesome which is a third-party font hosted externally.
So, lets review my updated implementation. I'll talk more about ARIA (Accessible Rich Internet Applications) later, but I've given the navigation menu the semantic " nav" tag and an aria label that screen reader users will hear. I've used a button instead of a link, and put that button at the beginning so the following tab will be to the menu items, and added aria properties to link it semantically to the navigation.
Most importantly I've given it an expanded aria attribute, so I can show whether the menu is expanded or not, and assistive technology will now understand that. When the hamburger is initially shown we know that it will not be expanded, and we can change that attribute with JavaScript.
I got rid of font awesome and used an inline scalable vector graphic or SVG to represent the hamburger, and made that hidden to screen reader users because the button itself has all the information they need.
This is the initial JavaScript for the action that takes place when you press the button. Originally it was to change a CSS class that would reveal the menu items. I added a few lines in the same vein that would change the value of the aria-expanded attribute from false, meaning it is collapsed, to true, meaning it is expanded. This is really simple because I don't need to know what the original value was, I just assumed that whenever the button is selected we're going to toggle between one or the other.
This then recalls the Name, role, value success criterion which states that for all UI components: the name and role can be identified by using a computer program, the aspects that a user can change can be changed by a computer program, and users of assistive technology are made aware of that change. The expanding / collapsing menu is a nice simple example of this in action. I'll share another one later.
So, lets revisit our example with the screen reader, listen again carefully to the experience, and observe the focus order.
NVDA: "Main menu, menu button, collapsed, sub menu." "Expanded"
So, the screen reader knows that the menu has been expanded.
NVDA: "Collapsed"
…and then it's been collapsed.
NVDA: "Expanded, home link"
Look the focus is moved to the next menu item.
NVDA: "Presentations link, blog posts link, projects link, about link."
So, that was a much improved experience wasn't it? But it is quite a simple one. Maybe so simple you might not have thought of it before?
A common mistake in accessibility is not testing the experience of components that only appear in "mobile mode" or when the screen is zoomed in. It's common across our sites at the University of Southampton to find hamburger design patterns that cannot be used with a keyboard.
We must remember that impairments and disabilities can be intersectional. I may prefer to use a keyboard than a mouse or trackpad, and I may also like to zoom content in. Not everyone who uses a hamburger menu is tapping a mobile phone.
If you haven't heard or ARIA (Accessible Rich Internet Applications) before it's used to modify the "accessibility tree" that the browser creates and affects only assistive technology, what we call "AT".
It's used to add extra information, express semantic relationships and inform assistive technology of changes.
This meme shows a "full stack developer" applying a massive bottle of olive oil labelled "ARIA" to a salad that is labelled "accessible website". The first rule of ARIA is to use native elements where possible, and only to use ARIA if you have to. That button was a semantic element, but we had to add an ARIA attribute to inform AT users of a menu collapsing or expanding.
A key thing for learning designers to be aware of is that ARIA brings numerous techniques for making interactive learning objects work well with AT - but they may not have been implemented in our authoring tools.
Learning how to test for accessibility is important. As is building our understanding of what's possible so we can identify good practice.
It's fairly common to find "scroll to top" buttons on website. Personally, I find them useful as I'm often reading lengthy web pages. The presentation support pages I make also tend have long lists of resources, so I added scroll to top and scroll to bottom on my site.
This is another aspect that is frequently missed in terms of keyboard navigation. It's nice to use the scroll-behavior setting to give a smooth scrolling experience, but we should give a choice to turn this off for those with vestibular issues. And it's no use being keyboard navigable if the focus on the page is not also moved to the top of the page. It's not just me saying this, these are clear instructions in the Web Content Accessibility Guidelines.
So, here's my implementation. I'm using a button. I think it's debatable if it should be a link, but I see this as more of performing an action. The button calls a function that we will look at in a moment. I'm using the recommended ARIA pattern for alt text to an SVG. The function sets where the focus should land as well as scrolling to the top. You have to set the focus to something that is interactive. I've picked the skip link. The scroll-behavior is set to smooth in CSS. And for those who have set to prefer reduced motion the automatic behaviour is set, using this CSS media query.
This is where users can choose to disable animations in Windows, and in Chrome you can emulate this preference from the rendering options in dev tools.
If you're still not sure what I mean by the differences in scroll behaviour I've made this video. Watch on the left the smooth scroll of a user who has not set a preference, in comparison with a user on the right who has turned off animations on their computer.
The AAA success criterion Animations from Interactions requires us to allow users to prevent animations from being displayed on web pages. That's because some users find that fancy scroll effects like parallax or animations in general can cause nausea and migraines.
More than 70 million people are affected by vestibular disorders. Effects can include vertigo and hearing loss. Using the web when you have these experiences can be really tough, and that's what this success criterion is designed to accommodate.
Reviewing a few University of Southampton sites, none meet all the good practices that I have identified. Why not go back and check your sites?
Some final thoughts about navigation. We saw that the small details like hamburgers and scroll to top buttons have accessibility considerations. We saw there are opportunities to respect user preference with animations and we'll see more of this next. Hopefully, I've shown the importance of really listening to and considering the screen reader experience.
Next, we're onto colour. Just like reflow, providing a dark and light mode is expected on modern sites. When I last checked the results, 40% of you prefer to use dark mode, 20% prefer light mode and 40% will swap between themes based on your preference and circumstance. In Windows we can set what colour scheme we prefer, and in Chome DevTools we can emulate the preference.
There are benefits to both modes. Dark mode has become popular because it can save energy on LED displays and has some accessibility benefits. There's just as many benefits for light mode. It's important to provide users with a choice.
It should be well accepted now that maximalist contrast should be avoided in digital. There is such a thing as too much contrast when we're presenting information in digital formats.
A typical way to respect colour scheme preference is to use CSS media queries. For my site I split the colour information into two CSS files (one for dark and one for light) and added a media query to them. This meant that the browser only loads one of those two CSS files.
Picking colours from the University of Southampton palette for dark mode I settled on these. "Plain black" for background, "Neutral 4" for text, "Marine 6" for focus indicators and hover states, and "Horizon 1" for links. Of course, all are at AAA levels of contrast. I used University colours because I'm still building my understanding of colour combinations that work well.
You might wonder why I have three shades of black. While I retained "Rich Black" for legacy reasons because I had used it in previous PowerPoint templates, I added a non-University black which was a 10% tint from the University colour "Plain Black". I used that to add some borders to the site when it's over a certain width. I noticed this is a common practice on many sites and it helps make content more readable on larger screens. At the moment I have it set to a 10% margin. There's probably a better method, so do let me know if you have any suggestions.
For light mode I had a bit less flexibility from our University palette and I wasn't to use as many colours as I would have wanted. I wanted to have a creamier white than pure white. The new University corporate PowerPoint templates have this kind of dull grey, white, but I wasn't very keen on that. I wanted a more creamy one. I had two shades of white because I was using them for margins.
In light mode, I chose "Rich Black" with an "Ivory" creamy white. Research presented in 2012 found that this combination was almost equally preferred by dyslexic readers and those without dyslexia, it also had low fixation durations for each group. Shorter fixations are preferred to longer ones. People who tend to make fewer eye fixations during reading usually have a higher reading pace than people who make more frequent fixations.
Using SVG favicons you can even set them to have different colour schemes depending on theme choice, by adding CSS styles within the SVG.
Here are examples from my personal site of clear WCAG 2.2 compliant focus indicators in dark mode. Here you can see focus indicators for an unselected button on the left and the selected button on the right, and on the left we have two links and on the right one of those links has been selected. You can see the same approach in light mode.
One of the reasons designers may remove focus indicators is that users see them when they use a mouse or touch pad to click on links. I used this CSS to apply a different style for mouse clicks, you may be able to see a little drop shadow added around the link and no outline.
In WCAG 2.2 which is expected to be finalised soon, to reach the AAA success criterion for focus indicators, we need at least 2 CSS pixel border, with a contrast of 4.5:1 or above, and the focus to not be hidden by author created content.
It wouldn't be an accessibility presentation without talking about contrast. In WCAG 2.1 and 2.2 we're used to thinking in terms of contrast ratios. WCAG 3.0, which is probably a few years down the line, uses the Accessible Perceptual Contrast Algorithm. It's still in development and it's going to be a very big change. It's much more sophisticated than the previous measure of contrast and is arguably more accurate. It produces a Lightness contrast rating, the higher the better.
We will find that some combinations that met WCAG 2 will fail under the new measurement. You can see here two examples from the University colour palette.
For this site I decided to future proof by ensuring colours I chose would meet both WCAG 2 and APCA. Chrome Dev tools can be configured to measure for APCA, and you can use the CSS overview to find all failing examples. Using this in combination with the colour matrix script I had written was really useful for identifying which colours would work. So, in dark mode, the body text is above 90 Lc and the same in Light mode. I do find that when you're in light mode you are going to get higher contrast ratings under APCA.
It's good practice not to make design decisions based on presumptions. Some may not know how to change their colour scheme at OS level or might not be aware that it's possible. Some might not like an implementation of dark or light theme that you've decided upon on your site. So, it's good to give people a choice.
I had already put a light bulb icon in the top left of the site to represent "ideas and thinking", but it looked like a good fit for putting in as a colour theme toggle. The idea is that it's going to set a preference using localStorage. I'm using the UI pattern of an on / off button, mainly because at home I have dimmer switches and you push them in and out to turn them on and off, so I settled on using aria-pressed. I needed to be sure that changes were announced to the screen reader. We need to use more than colour alone to represent the difference, so in dark mode the light is on and you can tell because of those little lines coming out around the bulb.
This was an interesting challenge for me and i'm going to talk you through the details. Now, this is my implementation. If you've spot any issues or have suggestions on how to make it better please do let me know in the comments.
Here's the button, when it loads it's set to not pressed, so when the web page loads the button this aria state is set to not pressed that's only going to be the correct state if you are in light mode. I also have a span here with an aria-live region that I will populate to announce changes.
So, I needed to do three things. First set whether the button was actually pressed or not depending on whether it was light or dark mode. When changing themes, the preference had to be saved, the change announced to the screen reader, and the value of the pressed attribute to be changed when. If a preference had been saved to load the desired theme instead of that preferred at Operating System level. broke it down into these three parts because it helped me make a solution piece by piece.
This part is setting whether the button is pressed or not on page load, it depends on what theme is being used. Dt is the operating system preference, and themePref is the site-specific preference if there is one. So, if the OS preference is dark, and the local site preference is dark, then the button is pressed. Likewise, if the OS preference is light but the local site preference is dark, then that means the user wants dark mode and the button's going to be pressed. If the OS preference is dark and there's no local site preference, then the button is pressed. In all other cases we're going to be in light mode, the button isn't pressed.
Once we press that button, we want it to change themes, change the value of aria pressed, and save the preference. This the function that is performed when the light bulb icon is selected. It's based on a choice, if at the beginning the button was pressed, that means it was in dark mode, so the user wants to change to light mode so we're going to change aria pressed to not pressed. Change the CSS loaded in the head to be the light.CSS colours. I appreciate this is a bit of a hack. We're going to set the choice in localStorage and add a notification to the screen reader and if the button was not pressed at the beginning meaning we're in light mode, then the user wants to go into dark mode and the rest of the function is going to do the opposite. I'm not going to show you it here because it's the kind of it's the same thing that we saw above but everything's just swapped around.
This is the hidden text for screen reader users, there's a CSS class that hides it from view, and it's an aria-live region so the text created by the function is squirted into that span tag and then announced to the screen reader.
The final piece is respecting the choice of themes, it checks if there is a preference from the user; have they pressed the button and it saved their preference? So then when they go to other pages on the site, we need to make sure that their preference is respected. So, here we check if there is that local preference, we set the theme accordingly, and set the state of the button.
So, let's hear and see how this works from the screen reader's perspective.
NVDA: "Welcome document. Visited link; skip to content. Banner landmark. Change between light and dark theme; toggle button: not pressed. Dark theme enabled, the button is now pressed."
You might think, "Hang on Matt, do we really need to make this compatible with screen readers - changing between light and dark mode? Because they're not going to see it right?" Well, remember what we said about intersectionality, not everyone who uses a screen reader is blind and there are different levels of sight that people might have. Who are we to say what functionality anyone can and can't use on our site? Perhaps the screen reader user is navigating our page using the screen reader but they have others in the among them, perhaps members of the family who prefer a different mode, and so the screen reader user is changing the theme on the page? We don't know what people are going to be using on our website. Accessibility is about removing barriers to using our services and sites for everyone. We're reminded of that basic success criterion about names and roles, states and properties, and notification of changes.
My site was really simple so there was no excuse for it not to be performant, but here's what Ii learned that i think you might find useful for me to share with you
As well as using the W3C Validator to test for conformant HTML, I used the webpagetest.org to run performance tests on my website as I built it. Out of curiosity, I had a look at a few other services at the University of Southampton that are well known for our audience.
One of the options on webpagetest.org is that you can test from different locations and on different devices, here is a set of tests that were run on 3G connected mobile in Mumbai. If the experience is good in Mumbai on a 3G phone, then it's probably going to be good everywhere. I'm going to give you a quick review of what these features are about.
- First byte is how long it takes from requesting the page to getting the first byte of data.
- Start Rendermarks the moment when a web page displays the first asset.
- First Contentful Paint (FCP) is when the browser renders the first bit of content, providing the first feedback to the user that the page is actually loading.
- Speed Index (SI) is how quickly the contents of a page are visibly populated.
- LCP stands for Largest Contentful Paint and tracks the time it takes for the largest visual part of the page to load. It's a measure of how long it takes for a user to start working with our site.
- TBT Total Blocking Time, TBT is the total time between the First Contentful Paint (FCP)and Time to Interactive (TTI).
- Total bytes is the amount of data downloaded. When you pay for your data, you don't want to be paying for things that aren't going to be giving you value.
From a sustainability point of view, it's worth paying attention to how much content is downloaded to users, some might be on metered connections. The reason this number is so high on the site, the Digital Learning Blog, is that there's an auto playing YouTube video at the beginning, so we've already downloaded 12 megabytes in the time that webpagetest.org has initiated and completed its its testing of that page. That's quite a lot of data particularly if you're paying for it, byte by byte.
WebPage test also shows us what parts are being loaded on the page and how long each individual part takes. Render-blocking resources, marked here with an X, arethings that block or delay the browser from rendering page content to the screen. Do we need the H5P plugin? Do we need to load both font-awesome and google fonts, which is a GDPR risk? These may all be legitimate, but has anyone actually sat down and thought about this before?
Chrome has a feature called Lighthouse. As this brilliant article explains, you can trick the results of Google Lighthouse but still it is worth using. You get ratings for Performance, Accessibility, Best Practice and SEO. My site is very, very simple, so getting 100 isn't special, but it did make me want to look at the scores of other sites.
I expect that our corporate communications team will be monitoring regularly the lighthouse scores for the corporate site because it's so important. It's the page that new people who want to find out about the University are going to be accessing so it needs to be performant, accessible, follow best practices, and have great Search Engine Optimisation.
This is our e-learning support resources it's soon going to be replaced with a new version so we definitely want to be monitoring performance, and we can definitely do better than 58 for performance can't we? In fact, all of our WordPress sites have terrible scores for performance. The Digital Learning Blog has only got 54.
I'm going to take us on a little side-track now to talk about accessibility of the Digital Learning Blog. The thing about WordPress sites is quite often once you've picked a theme, you're kind of locked in to the accessibility that that theme provides and it can be quite hard to make improvements without changing the whole theme. Tamsyn Smith and I looked into this. There was lots we couldn't fix: there's still a hamburger button that cannot be used with the keyboard - but we were able to use the Additional CSS option in WordPress to make a lot of changes. In fact, 325 lines is what we did in total.
Let's take a look at a few examples so we've got before on the left and after on the right. So, this is the masthead which you can see on the left this before state was pretty much unreadable, but this was fixed by adding background colour with a little opacity and changing the text colour. That footer is also pretty terrible on the left isn't it? We're able to fix that and also remove a few details that just weren't needed. My favourite is this the menu, the mega menu along the top. Obviously, no one had ever tested it with a keyboard before, because as you can see the menu items appear behind the content on the left, the before state. On the right there you can see that a change to the z- index brought the menu on top. We've made numerous other improvements to the menu since then but that was definitely the biggest.
What did i do on my site in terms of performance? Well i used TinyPNG and TinyJPG to optimise image size, and i added lazy loading on images and YouTube embeds so that they would only be loaded up once you got to that point on the page. Where i had used extra scripts like jQuery I only loaded those on the pages where they were actually going to be used because it's only on about two of the pages that i'm actually using any jQuery. I reduced critical chaining requests by using media queries for the light and dark CSS files in the head of the page.
So, to summarize we just need to be using some of these free management tools to get an understanding of whether users will find our site slow or fast. There's a little bit of automated accessibility checking and this isn't talking about load testing or anything like that this is simple tests that we can do and if we find any issues then we need to be talking to the site managers to find out why is… what is the justification for poor performance? Why are our WordPress sites so terrible at performance?
In terms of discoverability on my site. I added a site map, registered the site on the google search console, and added an RSS feed. I could still add a local search and breadcrumb navigation – but this is really simple site. Right now, there's only 34 pages, but I'll try and get to adding a few more of those later.
Let's put the meh in meta, here's a look at some of the meta tags. Here you can I've added some I open graph tags and Twitter card tags. It's expected now that when we share a link on teams, Twitter, LinkedIn and so on that we're going to get a nice preview It also can help to build awareness of our site and establish credibility. We want people to share our content and we want it to look good wherever it appears. There are validators online that can help you to check how the previews will look. It's great to see it happening, here accessibility legend Alistair McNaught is sharing a page on Twitter, and on the right is a connection request on LinkedIn from someone who found me through my personal site. I recommend using card validators to fine tune how your links will look when they are shared.
In terms of what's next, I would like to move the build process into a static site generator like eleventy, that will make updating the site template much more efficient. I would like to hide videos embeds behind a click to load pattern, for both privacy and performance reasons. The traditional approach to dark mode is to use CSS variables and then build classes from them, so if I ever find the time to look at that and refactor then I definitely want to do that because I haven't used CSS variables before and it looks really powerful. As I think of more things I want to share on the site I will be building up that component library that I've started for different design patterns, (like soon I want to do a responsive table pattern) with appropriate ARIA where necessary and light/dark colour schemes. I've got lots of accessibility related projects I have in mind that I want to build and now I've got a platform to put build them on. So, in a way the hard work is done, and the fun begins!
In this presentation I really wanted to share my struggles to deepen my understanding of accessibility and to share some concrete examples and my approach to solving them. I hope that has helped. I also know that I'm still learning and there's probably some mistakes in there. So, if I've got anything wrong or you have any suggestions for improvements, please let me know in the comments.
We've reached the end of the video. Remember: everything I refer to is listed on this web page. The transcript also has handy hyperlinks to these resources.
The code snippets were created using PrismJS and styled using a11y syntax highlighting CSS by Eric Bailey. A big thank you to Eric for making that, and also for his articles about vestibular issues and the "prefers reduced motion media query", which I quoted from earlier in this presentation.
You can download the slide deck and other resources at this link. Visit my site for other presentations. Thanks for watching! Let me know your feedback, good or bad. See you in the next one.