Custom checks
You can extend Sa11y beyond checking for accessibility issues. For example, create checks that promote better usability, or encourage proper use of components and web style guidelines. Custom checks should be created within /src/sa11y-custom-checks.js
- which is seperate from Sa11y's core library.
How to create a custom check
You can create custom checks with just a few lines of JavaScript. There are two types of annotations you create: Button annotations and full-page banner annotations that are appended to the top of the page. There are also several utilities and selectors you can use.
Utilities
this.sa11y.computeAriaLabel()
- Process ARIA attributes on elements.this.sa11y.fnIgnore()
- Ignore children of element.this.sa11y.debounce()
- Simple debounce utility.this.sa11y.computeTextNodeWithImage()
- Compute alt text on images within a text node.this.sa11y.sanitizeForHTML()
- Converts various HTML characters back to their respective entity code.
Selectors
For performance, you can reuse these selectors when creating custom checks.
this.sa11y.$h
- Select all H1, H2, H3, H4, H5, H6, [role='heading'][aria-level]this.sa11y.$h1
- Select all H1this.sa11y.$img
- Select all IMGthis.sa11y.$links
- Select all A[HREF]this.sa11y.$inputs
- Select all INPUTthis.sa11y.$iframes
- Select all IFRAMEthis.sa11y.$videos
- Select all IFRAME that contains a video player onlythis.sa11y.$audio
- Select all IFRAME and AUDIO that contains an audio player onlythis.sa11y.$dataviz
- Select all IFRAME that contains a visualization onlythis.sa11y.$twitter
- Select all Twitter IFRAMEthis.sa11y.$embeddedContent
- Select all IFRAME that is not an identified audio player, video player, Twitter widget or visualizationthis.sa11y.$strongitalics
- Select all STRONG and EMthis.sa11y.$badDevLinks
- Select all links vialinksToFlag
prop.this.sa11y.$checkPDF
- Select all a[href$='.pdf']this.sa11y.$tables
- Select all TABLEthis.sa11y.$lang
- Select HTML's LANG attributethis.sa11y.$blockquotes
- Select all BLOCKQUOTEthis.sa11y.$p
- Select all Pthis.sa11y.$allCaps
- Select all H1, H2, H3, H4, H5, H6, LI, BLOCKQUOTEthis.sa11y.$readability
- Select all P and LI within specified container
Button annotation
- Create your condition.
- Use
this.sa11y.root
instead ofdocument
within your selector. - Add respective CSS classes.
- Highlighting text:
.sa11y-warning-text
or.sa11y-error-text
- Border around elements:
.sa11y-warning-border
or.sa11y-error-border
or.sa11y-good-border
- Highlighting text:
- Use the insertAdjacentHTML() method to append the annotation either before or after the element.
- Use
this.sa11y.annotate(string, string, boolean)
within the aforementioned method to generate the annotation.- String (type of annotation):
M["ERROR"]
orM["WARNING"]
orM["GOOD"]
- String:
C["YOUR_CUSTOM_TOOLTIP_MESSAGE"])
- Boolean (Optional): Pass
true
if you'd like to position the annotation inline with text.
- String (type of annotation):
Full-width banner annotation
- Create your condition.
- Use
this.sa11y.root
instead ofdocument
within your selector. - Banners should be appended after Sa11y's container. Use
this.sa11y.panel.insertAdjacentHTML()
method with a position parameter ofafterend
. - Use
this.sa11y.annotateBanner(string, string)
within the aforementioned method to generate the annotation.- String (type of annotation):
M["ERROR"]
orM["WARNING"]
orM["GOOD"]
- String:
C["YOUR_CUSTOM_TOOLTIP_MESSAGE"])
- String (type of annotation):
Recipes
Both recipes below are included in sa11y-custom-checks.js
Overusing a component on a page
The example detects if more than one announcement is detected on a page, although it could be easily extended to anything. Too many slideshows? Too many accordions? You name it.
const $checkAnnouncement = this.sa11y.root.querySelectorAll(".announcement-component");
if ($checkAnnouncement.length < 1) {
for (let i = 1; i < $checkAnnouncement.length; i++) {
$checkAnnouncement[i].classList.add("sa11y-warning-border");
$checkAnnouncement[i].insertAdjacentHTML(
"beforebegin",
this.sa11y.annotate(
M["WARNING"],
C["QA_TOO_MANY_COMPONENTS_EXAMPLE"]
)
);
}
}
Code explained
If Sa11y detects more than one instance of the .announcement-component
CSS class, it will be flagged as a warning. The warning button will only appear on every instance except the first component. C['QA_TOO_MANY_COMPONENTS_EXAMPLE']
represents a string (tooltip message).
Demo
Accordion component contains a form
Forms nested within accordion components can be problematic if it uses server-sided validation. The page will reload, and the accordion usually returns back to its closed state. This is problematic for everyone.
const $checkAccordions = this.sa11y.root.querySelectorAll(".sa11y-accordion-example");
$checkAccordions.forEach($el => {
const checkForm = $el.querySelector("form");
if (!!checkForm && checkForm.length) {
$el.classList.add("sa11y-error-border");
$el.insertAdjacentHTML("beforebegin",
this.sa11y.annotate(
M["ERROR"],
C["ACCORDION_FORM_MESSAGE"]
)
);
}
});
Demo
Add or suggest a recipe
Share your recipe on GitHub.