Keyboard and Screen Reader Web Accessibility
Note: this page is in progress and is for my own practice and notes on web accessability. Information may not be correct, nor have I yet applied this advice to my other pages.
Headings
Headings should be used for sorting information, not just making text large and bold (use CSS for that).
Headings range from H1 to H6, and shouldn't skip numbers between.
Only one H1 heading should exist on a single page; it is usually the title of the page. It may also be the title of the article, but if there are multiple articles they may be labeled with H2. Any subsections within the articles can be labeled with H3 and further if those are split into sections.
Landmarks and other Semantic Elements
Landmark elements allow screen reader users to easily navigate a page by skipping from section to section. Semantic elements in general provide context for what an element contains. Divs do not offer these advantages.
Navigation
< nav >
This section describes any collection of links that the user can use to navigate the page or website. This can be site pages or a table of contents within a page.
Navigation is not used for links to other sites, only those used within the site.
If a list is used for navigation, the whole list element (not just list items) should go within the nav element.
Note that the navigation element is the only landmark element with a tag that is shortened (nav); the following elements are fully written out in HTML tags.
Header and Footer
Header
A header is the thin bar at the top of some websites and usually stays the same across that site's pages.
Headers usually contain the site name or logo, and site navigation links.
Footer
A footer is like a header but at the bottom of a page. They usually contain copyright information.
Sometimes they contain navigation links, but not always
Main and Aside
Main
Main contains the primary content of a page, excluding the header, navigation, the footer, and any side content. This is basically what you focus on first in a page. Your article or articles will be here.
Like H1 there should be only one main element in an HTML document (page).
Aside
Aside is for any additional content not within the main body, usually on the side. In context of common neocities features, it could contain an update log, chat section, etc.
It is a little unclear what exactly is appropriate to go in an aside element. Some sources suggest content unrelated to the main content should go into a section element rather than an aside element. This leaves me wondering what exactly should go in an aside element and what counts as related.
Section
A more generic element that can still be skimmed by screen readers. This is used for regions that do not fit any of the above elements. Since it is a generic element, it should be given an aria-label to indicate its content. (Aria labels are discussed further below).
Article
The article element describes a section that could be presented independent from the rest of the page. Some pages have only one article, but a page can contain multiple articles. For example, a blog that shows all entries on the same page could have each entry contained in its own article element.
Note that the above elements are landmarks, but the article element is not, though it is semantic.
Additional Notes
Main, Header, Footer, and Aside should be "top level landmarks" meaning they should not be nested inside other landmarks (inside other elements like divs is fine). Navigation, and section can be nested in other elements (ex. navigation inside of header, section inside of main).
No important content should be outside of a landmark. (I imagine a purely decorative image outside would be fine since it should have an empty alt anyways.)
A page should have a main landmark if no other, as your page will have some main content even if it does not have a header, footer, or side content.
Aria Labels
ARIA - Accessible Rich Internet Applications
Aria labels give additional context to sections that would be helpful for screen reader users to know. This attribute is preferable to the title attribute for accessibility.
For example this page has two navigation sections that would be undifferentiated to the screen reader user if no labels are used.
< nav aria-label="site" > site navigation links < /nav >
< nav aria-label="page" > page navigation links < /nav >
I chose "site" and "page" as the two different labels to indicate where the user is navigating. Since navigation is already given by the nav element, it would be repetative to include that in the label.
Labels can also be used for buttons that have only icons displayed (an x button or a menu button) to indicate what clicking the button will do. Ex. < button aria-label="close" > x < /button >
or < button aria-label="menu" > ≡ < /button >
This page has multiple articles, but since they have headings we can use those headings to give context.
< article aria-labelledby="article1" >
< h2 id="article1"> Article Title Example < /h2 >
< /article >
Here we use aria-labelledby instead of aria-label which we used before.
Roles
Role attributes are similar to aria label attributes and landmark HTML elements. In fact, many roles correspond to a landmark.
- banner - header
< header > header content < /header >
< div role="banner" > header content < /div >
- contentinfo - footer
- main - main
- complementary - aside
- navigation - nav
- region - section (will only work if the region is also given a aria-label)
If the right semantic HTML elements are used, some roles may be redundant. For example, using the banner role (role="banner"
) in a header element would be repetitive. The banner role would only be used if the header element could not be used for some reason and a different element was being used as a header.
The heading role < div role="heading" aria-level="2" > Heading 2 Example < /div >
would be better replaced by a heading element < h2 > Heading 2 Example < /h2 >
. But since headers only go down to the sixth level, a heading role and aria-level < div role="heading" aria-level="7" > Heading 7 Example < /div >
can justifiably be used to designate further subheadings.
Image Descriptions
Alt
More people are familiar with using the alt attribute to describe images than other web accessibility tools, but theres more to describing images than just alt="example image description here"
Important to note, is that the alt attribute is for short image descriptions. It's basically a quick glance at an image.
Images that are purely decorative or not important to the page can be given an alt tag with no content (alt="") to create a nondisruptive experience. Similarly, an icon next to a word of the same meaning should have an empty alt, since a description would be repetitive.
Images that serve as a link should have a description that indicates where the link goes to rather than a description of the image (think about the function of the image).
Aria
aria described by
aria-describedby=""
If the image is described by text that is already included in the document, you can use aria-describedby="paragraphid"
where the describing paragraph is given an ID, which is put in the aria-describedby attribute.
If you want the description hidden from sighted users you can use CSS to hide the description, which will not make it unaccessable for screen reader users. This may be desired for art galleries, but consider displaying a detailed description for all viewers with images like charts and diagrams.
W3C guide on aria-describedby
aria description
aria-description=""
This functions just like alt text, but for longer detailed image descriptions rather than brief ones.
It is important to note that this is in the current draft for ARIA by the W3C, thus not offical yet, so it is recommended to continue using aria-describedby.
W3C guide on aria description
Figure
The figure element and its child element, figcaption, are semantic HTML elements that can be used to provide built in image descriptions that are visable to every user. You may want to include a short alt description, but an additional detailed description would be redundant.
< figure >
< img src="image.png" alt="brief description" >
< figcaption > caption of the image < / figcaption>
< /figure >
Buttons
Any element that the user needs to select to preform an action (close, submit, open, etc) should be a button element (rather than a div, span, image, or link). This is because buttons have built in functions that allow keyboard users to select the button without having to click a mouse. Buttons also have built in styling that gives them a border and outline when the keyboard is positioned on them (this outline is important for sighted but otherwise disabled users to tell where they are on the screen)
Links can be styled to look like buttons, but link elements should only used if it takes the user to a different location (site, page, place within a page).
Making an element function as a button
A button element should be used from the get go, but if absolutely necessary, a different element can be made to function like a button.
The following information is cobbled together by me, someone who is not an accessability expert, in attempt to make some of my pages more accessible.
Keyboard selectable
First I like to make the not-buttons keyboard selectable (selectable using the tab key) using javascript. This is helpful for both blind users and users who can't use a mouse.
< script >
var x = document.querySelectorAll('.classexample');
for(var i=0; i<x.length; i++) {
x[i].setAttribute('tabindex', '0');}
< /script >
This code goes at the bottom of the body in the HTML document.
The tab index attribute tabindex="0"
makes an element focusable using the tab key, but the above javascript is useful for giving it to multiple elements of the same class or tag. If it is just one or a few buttons rather than a large section of elements, consider just changing them into real buttons.
That only allows the user to focus on an element, not actually activate the function if they don't use a mouse. You will need to give your element an onkeypress event that activates the same function as the onclick event.
Focus styling
Next I make it so if the user is on the element (focused) there is a visual indication (useful for sighted users who can't use a mouse).
.classexample:focus {
border: 2px solid blue;
outline: 1px solid white;}
A border and outline are standard focus properties given to buttons and links, so I emulated it here.
If your elements have a hover effect, consider giving the focus CSS the same properties.
Button role
Using javascript to give elements the button aria-role lets the screen reader user know that the elements are buttons that can be selected.
< script >
var x = document.querySelectorAll('.classexample');
for(var i=0; i<x.length; i++) {
x[i].setAttribute('aria-role', 'button');}
< /script >
Making Hover Effects Keyboard Accessable
If your hover effect is just making a button or link different colored you don't need to worry about making it keyboard accessable, since browsers automatically give these elements a border and outline to show when they are focused on.
If your hover effect displays a hidden element, you will need to do a little extra work to make it keyboard accessable to someone who cannot use a mouse.
First you will need to make the element(s) focusable using the tab key. If it is only a few elements you can use the tab index attribute in each one tabindex="0"
. If it is a class of elements, javascript may be more convienient.
< script >
var x = document.querySelectorAll('.classexample');
for(var i=0; i<x.length; i++) {
x[i].setAttribute('tabindex', '0');}
< /script >
It is likely you have already styled the CSS for what will change when a user hovers over certain elements. You can copy paste these selectors and their properties and replace hover with focus .classexample:hover {}
.classexample:focus {}
My HTML color map page uses this. When the user mouse hovers over a color circle it shows the colors name, hex value, and RGB value. Before, without a mouse, a user could not access these values, but now by simply tabbing, these values show up.