A passionate frontend developer from Nottinghamshire, UK.
Portfolio: jackdomleo.dev
A CSS stylesheet to quickly highlight a11y concerns.
Home Page: https://checka11y.jackdomleo.dev
License: MIT License
A passionate frontend developer from Nottinghamshire, UK.
Portfolio: jackdomleo.dev
The package.json is corrupted after a merge conflict. There's a comma in the wrong place. This makes the package.json to be invalid and the project cannot be installed or built.
package.json should be error free.
Did a quick fix in this PR: #45
Checka11y.css currently flags any element but <li> that is directly nested within an unordered or ordered list as incorrectly placed. The documentation links to Understanding WCAG 2.0 but that page only provides high-level guidance.
The restriction on what elements may appear within lists is actually spelled out in the HTML standard already. However, it is a bit more permissive than Checka11y.css: In addition to <li>, it allows for script-supporting elements, that is <script> and <template>. It would be great if Checka11y.css allowed those two elements as well.
Inputs missing labels (often when Placeholders are being used as labels) might have unclear intentions.
<input type="text" placeholder="Email" />
The placeholder in the above example is rarely read by screenreaders
<label>Email</label>
<input type="text" />
The label in the above example exists, but is not associated with an element so will often be misinterpreted.
<label for="email">Email Address</label>
<input name="email" type="text" />
The above is the best-accepted solution, which most screen readers understand (unlike <label><input></label>
).
We should check 2 things
This won't account for if any inputs/labels have attributes present but their counterparts don't exist, however.
The minified version is not being generated correctly because it is created but then overwritten by the expanded version.
If you run npm run build
, it only generates checka11y.css but not checka11y.min.css
When you run npm run build
both checka11y.css and checka11y.min.css are created.
This is happening because there is a small misconfiguration in the package.json. The output of the minified version doesn't have the .min
in the name.
While the act of opening in a new window or tab isn't an accessibility concern itself, according to W3, it's essential to provide advanced warning to a user when a link opens in a new window or tab.
The A11y Project link:https://www.a11yproject.com/checklist/#identify-links-that-open-in-a-new-tab-or-window
W3 link: https://www.w3.org/TR/WCAG20-TECHS/G201.html
Solution
Provide only a warning message when the following is detected:
a[target="_blank"] { ... }
The new role="text"
is nice because it prevents a screenreader from breaking up sentences with <span>
or <strong>
inside, however when using it on a heading, it causes the heading to lose its semantic meaning.
h1, h2, h3, h4, h5, h6 {
&[role="text"] {
// Show warning
}
}
https://openinclusion.com/blog/using-role-text-enhance-mobile-screen-reader-output/
Screen readers and other assistive technologies use shortcuts and keyboard combinations to facilitate their use. Access keys could interfere and conflict with the AT behavior and should be avoided.
Show a warning if an element has an access key. As it is an HTML attribute (accesskey
), the elements with access keys are easily selectable via CSS:
[accesskey] {
/* warning */
}
Would it be useful to add links to the list of features on the README as a form of validity?
Looking at the project, I was amazed how many features are already implemented. However, I think I found one feature that would help the project to get to the next level. This is all about live coding.
By live coding I mean that it would be pretty cool if we as developers could see the bugs we are making while we are programming.
Since tools like W3C's are well established and do not offer such a feature, this would be a reason for many users to switch to this project.
##How to implement?
Since the website is not allowed to reload during such sessions, every single script would have to be modified during implementation. The method appendChild, makes it possible to reload a Javascript functionality without reloading the website itself. Here is a code example:
var s = document.createElement('script');
s.src = 'path/to/script-that-injects-data-or-NEW-widgets.js';
document.body.appendChild(s)
Now that we can reload the scripts which check if something is wrong without our script disappearing, there is only one thing missing.
- Recognize when a user has typed something
This is implemented quite simply. First you have to develop an IDE like front-end via HTML, where you can write your code later. With an ID you can validate HTML, CSS, Javascript etc. while typing, with a code structure like shown here as an example:
var inputBox = document.getElementById('codeinput');
var s = document.createElement('script');
s.src = 'path/to/script-that-injects-data-or-NEW-widgets.js';
inputBox.onkeyup = function(){
document.body.appendChild(s)
}
Voilla :)
What do you think about it?
Only a single navigation element is permitted. This is because <nav>
dictates the primary navigation for the page (often the page header).
Where multiple navigations exist on a page (for example, the footer), any which aren't considered primary should not be wrapped in a <nav>
tag.
Evidence: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/nav
(See usage notes)
Show a warning if any title
attribute is detected. title
has many accessibility issues and should be replaced with a more accessible technique. This rule should not apply to the <iframe>
, since title
is required on <iframe>
to describe its content.
[title] {
// Show warning
}
iframe[title] {
// Remove warning
}
Headings should be in the correct order See here for more information.
Skipping heading ranks can be confusing and should be avoided where possible
For example, this is correct:
<h1>This is a heading</h1>
<h2>This is a subheading</h2>
This is incorrect because it goes from h1
straight to h3
(skipping h2
):
<h1>This is a heading</h1>
<h3>This is an h3 heading</h3>
Not completely sure how this can be done with CSS
. I have tried this
h1+h3,
h1+h4 {
border: var(--checka11y-error-border-width, 5px) solid var(--checka11y-error-color, red) !important;
}
which checks if an h1
heading is followed by an h3
or h4
header. However, this doesn't take into account elements in between the headers. Any ideas welcome.
Yes. My implementation was too "opinionated" and it assumed a particular structure (which is a big mistake). One possible solution would be to remove the requirement to have the previous headings first. For example, right now, if it finds an h2, it will show an error if there isn't an h1 in the ancestors (which is the case, as h1 and h2 are cousins on the linked page); The solution would be to remove that condition, it will cover fewer cases, but it won't throw false positives like that. - @alvaromontoro
N/A
The heading checks are more lenient so they don't throw any false errors.
The heading checks are throwing false errors.
This would be a good project to have published to npm with some good usage docs.
Anchor tags should not be used as buttons, it is bad for accessibility and usability. Links should redirect to a resource/page, if they don't they probably should be buttons.
Display a warning if a link is being used as a button. Examples of links being used as buttons:
<a href="#">Do something</a>
<a href="javascript:void(0)" role="button">Do another thing</a>
<a href="javascript:doSomething(0)">Do another thing</a>
Basically, what should trigger the warning would be:
href="#"
(a link that doesn't go anywhere)href
starting with "javascript:" (a link that calls a function instead of redirecting)role="button"
should probably display the warning.It would be nice to indicate if the value set on the lang
attribute on the <HTML>
is set to a know language string as defined here by w3.
Although this is a very long piece of work and may prove to be better suited in a JS accessibility tool.
Images should nave a descriptive alternative text. Images in which the alternative text is "image" or "graphic" or a " " (blank space), are not providing enough information for assistive technologies.
This one is tricky because it can be really language-dependant. The same word that works in English (image) may work in French (image) but not in Spanish (imagen) or German (bild). Also, images don't have ::before
and ::after
pseudo-elements to display the error.
The language barrier is difficult to skip, the solution could include some common words in different languages that would trigger the rule, but having all of them may be complex. Some of them (e.g., a blank space). As for the highlight, the project could include an inline image in SVG or base64 with a message through the content
property.
Then the selector/rule could be something like this:
image[alt=" "],
image[alt="image"i],
image[alt="graphic"i],
image[alt="photo"i],
image[alt="picture"i],
... {
border: 4px solid red;
content: url(path-to-error-image)
}
Users may define their own stylesheet for accessibility purposes. Inline styles can only be overridden using !important
, and inline styles with !important
cannot be overridden via a user stylesheet, so they should be avoided.
From WebAIM: "To improve accessibility, end users may change browser default styles and may define custom styles that override any other styles in the "cascade". Pages must be adaptable and flexible to end user style customizations."
Show an error/warning if inline styles are present and they have an !important
, as users won't be able to override those styles with a custom stylesheet. The CSS rule could be like this:
[style*="!important"] {
/* error/warning */
}
Anchor tags that are missing link text should probably be highlighted. I think the same could apply for buttons. It's not common, but it happened to me with frameworks where the property being accessed to display the link text was missing or came in as an empty string from the db. The linter won't catch this since <a href="">{{ title }}</a>
is valid, but the output <a href=""></a>
is not :)
A quick code pen: https://codepen.io/tricinel/pen/gOMYBWx
When submitting a PR, 2 automatic checks are run: Tests & Linting. But the linting check always fails.
N/A
Linting check runs successfully:
Fails no matter what.
According to MDN and w3, a <section>
"should" contain a heading element (the heading element is used to describe the section
). This should only be a warning and not an error because MDN and w3 both state "should" and not "must"; it's an advisory rather than a requirement.
The gh-pages
branch is reserved for the documentation/live demo website for Checka11y.css. We just need a website creating, with:
A website! π₯
Linking to a source that is not https
could be seen as not good. While this is not strictly an a11y feature, I feel it is still an important thing to highlight. We should be avoiding using links that aren't https
.
Show a warning if a link's href
doesn't contain https
.
a:not([href*="https"]) {
...
}
Looks like a nice project, and I know the website is still in the works, but it might be nice to add a simple demo page that demonstrates how this works, even if it's just temporary prior to the website launch.
Headings are essential to communicate the organization and flow of a page. An empty/unreadable heading does not make sense from a semantic point of view, it could create problems with assistive technologies, and is a sign of an underlying problem (e.g., using tags/elements for visual results instead of for what they are supposed to mean).
And quoting Deque's site: "It is a best practice to ensure all heading elements (those marked with <h1>
through <h6>
) contain content."
There should be some tests for headings to ensure that they contain content and it's "valid" content. Some of those checks would be making sure that the headings:
...are not empty (e.g., using the :empty
pseudo-class):
h1:empty,
h2:empty,
... { /* error */ }
...are reachable by assistive technology (e.g., they don't have aria-hidden="true"
)
h1[aria-hidden="true"],
h2[aria-hidden="true"],
... { /* error */ }
...have valid content (e.g., the content is not a single image element)
h1 img:only-child { /* error */ }
"Unexpected video and audio can be distracting and disruptive, especially for certain kinds of cognitive disability such as ADHD. Certain kinds of autoplaying video and animation can be a trigger for vestibular and seizure disorders." - The A11y Project.
Link: https://www.a11yproject.com/checklist/#make-sure-that-media-does-not-autoplay
Proposed solution
Check for when the autoplay
attribute is used and provide a warning.
[autoplay] {
...
}
I see this quite often in code bases, where devs will attach an onclick
to some div
or span
and call it a day. This breaks keyboard navigation. Worse...sometimes there are onclick handlers that will just navigate the user to another page. This specifically fails Success Criterion 1.3.1 and 2.1.1.
I quickly mocked this up in codepen: https://codepen.io/tricinel/pen/VwjZEPK.
I'm not sure if we should be that aggressive and ban all elements except buttons and anchor tags.
Whenever an element has aria-hidden="true"
, it shouldn't have descendants that are focusable. These are:
<a>
<area>
<audio controls>
<button>
<iframe>
<input>
<select>
<summary>
<textarea>
<video controls>
tabindex
set to a numeric value other than -1
Example
<div aria-hidden="true">
<button>Click me!</button> <!-- <-- This should show a warning. -->
</div>
The solution would be to display a warning whenever a focusing element is present:
Example:
[aria-hidden="true"]{
button::after{
@include contentMessage(warning, "Focusable element in a hidden element.");
}
}
The problem is that some elements such as <select>
can't have a :after
class, so it won't work. Maybe there's a way to style the parent element instead?
[aria-hidden="true"] elements contain focusable descendants - Google Developers Web.Dev
We are looking for someone to design and donate Checka11y.css a logo and an icon.
Design brief
Logo:
Checka11y.css
1280px width by 640px height
Icon:
500px by 500px
We thank you in advance! π
If you have any designs, please submit below in the comments (or message Jack on Twitter or message Jack on LinkedIn).
You will be credited for the design and added as a contributor (for this to happen, we will ask you to create a pull request adding the images to the repository).
As an accessibility tool, there can't be any accessibility issues caused by the notification of error messages, but in its current state there are definitely some problems I can see.
Suggestions:
Each feature should have its own feature code (I.e. W0001
or E0001
), which the developer can lookup in the features.md
, where there will be notes about possible solutions or links to resources to help them resolve their a11y issue.
N/A
The dir
attribute can only have the values, ltr
, rtl
and auto
.
Link: https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/dir
Proposed solution
Throw an error if the dir
attribute is anything other than ltr
, rtl
or auto
.
[dir]:not( [dir="rtl"] ):not( [dir="ltr"] ):not( [dir="auto"] ) {
...
}
[dir]:not( [dir="rtl"] ):not( [dir="ltr"] ):not( [dir="auto"] )::after {
...
}
A <button>
tag should not contain interactive content.
Following an approach similar to what is done for the <a>
tag, show an error message when interactive content is present as a descendant of a button.
This would be a project enhancement: adding a testing tool. Right now, all the checks to verify that the new change didn't affect anything already in place have to be done manually. This is error-prone (it's easy to miss something) and unsustainable in the long run, when many tests are reached.
My suggestion would be adding Cypress as the testing tool. Cypress is simple and easy, and as a test, I was able to get something up and running in 10 minutes:
It will help run all the tests in an automated way, without missing anything. For each new feature, the developer would be in charge of writing the test for their feature and verify that the rest are still Ok (e.g. just run the tests and make sure all of them pass.)
A lang
attribute should exist in the <html>
tag, which signifies to the screen reader what language the page is in.
Evidence: https://www.w3.org/WAI/standards-guidelines/act/rules/html-page-lang-b5c3f8/
The below features in the README need to be refactored to use the direct
keyword. This needs changing because almost anything can go within an <li>
, <dt>
and <dd>
, but these can only be the direct children of <ul>
, <ol>
and <dl>
.
- Checks <li> is the only child of <ol> and <ul>
- Checks <dt> and <dd> are the only children of <dl>
Proposed solution
- Checks <li> is the only direct child of <ol> and <ul>
- Checks <dt> and <dd> are the only direct children of <dl>
The <u>
tag used to represent an underlined chunk of text. Since HTML5, its semantic meaning has changed (now it represents text that has some non-textual annotation associated), but many times it is still used just to underline text because its default styles include an underline.
This is an accessibility problem because, in general, an underlined piece of text is used to represent a link. So the <u>
tag should be avoided. From MDN: "Be careful to avoid using the <u>
element with its default styling (of underlined text) in such a way as to be confused with a hyperlink, which is also underlined by default."
If there is a <u>
tag on the page, show a warning as it is most likely an incorrect use of the tag. The CSS selector could be as simple as this:
u {
/* warning */
}
In the warning, a list of alternatives to <u>
could be provided. From MDN:
In most cases, you should use an element other than
<u>
, such as:
<em>
to denote stress emphasis<b>
to draw attention to text<mark>
to mark key words or phrases<strong>
to indicate that text has strong importance<cite>
to mark the titles of books or other publications<i>
to denote technical terms, transliterations, thoughts, or names of vessels in Western texts
A solution to showing error/warning on void HTML elements such as <img />
or elements that cannot have a ::before
and ::after
attribute such as <iframe>
. We currently show a border with no error/warning text. The following elements are ones I've found so far that don't accept the pseudo-elements (::before
and ::after
):
<img>
<iframe>
<audio>
<select>
<object>
<input>
<textarea>
<video>
Any that works accessibly and correctly.
Nesting the following inside an <a>
is invalid:
<a>
<audio> (if the controls attribute is present)
<button>
<details>
<embed>
<iframe>
<img> (if the usemap attribute is present)
<input> (if the type attribute is not in the hidden state)
<keygen>
<label>
<menu> (if the type attribute is in the toolbar state)
<object> (if the usemap attribute is present)
<select>
<textarea>
<video> (if the controls attribute is present)
Solution
Show an error in the above elements are detected nested anywhere inside an <a>
.
As a consumer of Checka11y.css, I would like to sometimes only ever see errors or only ever see warnings.
Maybe a specific stylesheet with only errors?
N/A
To comply with valid HTML and correct HTML semantics, the direct children of a <dl>
can only be <dt>
and <dd>
.
W3: https://www.w3.org/TR/UNDERSTANDING-WCAG20/content-structure-separation-programmatic.html
MDN Docs: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dl
Solution
Maybe a selector like this may work:
dl > *:not(dt):not(dd):after { ... }
Would be great to use this as bookmark in the browser, then you can just click the bookmark whenever you wanna check the status.
Code:
javascript:(function(){var a=document.createElement('link');a.rel='stylesheet';a.href='https://checka11y.jackdomleo.dev/css/checka11y.min.css';document.body.appendChild(a)})();
Feel free to add it to the website/readme or similar.
Within the Pull Request Process section, of the contributing guidelines, it is mentioned to update the test.html file, but it doesn't exist. It should be index.html, within the test directory, I suppose?
Buttons and links should contain something that indicates what they are or what they are going to go. Having an empty link, or a button that is only an image, or an empty input button without a value can be confusing and doesn't provide enough information for screen reader users.
From WCAG 2.1 Success Criterion 2.4.4 Link Purpose (In Context): "The purpose of each link can be determined from the link text alone or from the link text together with its programmatically determined link context [...]."
Verify that buttons and links follow some basic patterns:
:empty
pseudo-class):only-child
pseudo-class)All the page functionality must be available via keyboard, but if elements have mouse events associated, those event handlers may not be triggered correctly with the keyboard. For example:
<div onclick="doSomething()">This div is clickable but the effect cannot be triggered via keyboard</div>
Apart from not being accessible via keyboard, many times these issues are a reflection of a different underlying problem (i.e., the <div>
above should probably be a button.)
Display a warning if there's an element that has mouse event handlers associated with it. The ones that are added via JavaScript are not reachable via CSS, but if the event is inline, it can be targeted with CSS. E.g., the following rule will apply styles to the <div>
above:
[onclick],
[ondblclick],
[onmouseover],
[onmouseenter],
[onmouseleave],
[onmousedown],
[onmouseup] {
/* warning/error */
}
And it could be extended to avoid false positives. For example, by discarding elements that would actually trigger the mouse event via keyboard like a button or a link (e.g.: [onclick]:not(a):not(button)
)
Cypress was implemented in #68, but only a few tests were created for a few features. We ideally need to test every feature.
Test the features.
N/A
Check the tabIndex
of commonly tabbed to elements to ensure that they remain accessible.
##Β Problem
Sometimes, elements which should be able to be tabbed to have their tabIndex incorrectly set, meaning they are skipped over when navigating using the keyboard
<button type="submit" tabIndex="-1">Submit</button>
The above button would be skipped past when navigating using the keyboard, making its associated form un-submittable.
For a specified list of elements, if a tabIndex is present and equal to "-1" an error should be shown.
Elements:
Any others which I've missed?
Screen Readers read the data according to the dom nodes so if the flex-direction is set to column-reverse or row-reverse then screen readers wont be able to read them correctly.
I cant think of a solution for this more discussion is required.
https://developer.mozilla.org/en-US/docs/Web/CSS/flex-direction#Accessibility_concerns
The error/warning messages inherit too many styles which causes inconsistencies on the web page. I propose looking at adding some styles (worth playing around to see what else is needed) such as:
text-transform: initial;
text-decoration: none;
letter-spacing: ____;
All messages have as much consistent styling as possible.
The messages inherit too many styles from its parent.
Hello again. Thanks for writing this. It's interesting.
In order to help people contribute to this repository, it would be great to use GitHub to check all pull-requests automatically.
Automatically running lint and tests on all incoming PR's
N/A
I'm willing to write this for you.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.