Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
466 changes: 466 additions & 0 deletions checka11y-warnings.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion checka11y-warnings.min.css

Large diffs are not rendered by default.

466 changes: 466 additions & 0 deletions checka11y.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion checka11y.min.css

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions codes.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,3 +151,6 @@ A list of every Checka11y.css error & warning code with details on what the issu

- ### W0016
The `viewport` meta tag contains a property that disables the zoom and/or the viewport scale. Such a property may prevent users from interacting with the web page, and make it more difficult to view the content.

- ### W0017
The highlighted element is an interactive element with `aria-hidden="true"`. This means the interactive element is inaccessible to assistive technologies. Either remove the `aria-hidden="true"`, or restructure the HTML in cases where the element is ment for decoration purposes or its a duplicate. [Read more about this here](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Attributes/aria-hidden).
25 changes: 25 additions & 0 deletions cypress/e2e/aria_hidden_spec.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
describe("[aria-hidden]", () => {
beforeEach(() => {
cy.visit("/test/index.html")
})

it("should contain border-color rgb(255, 255, 102)", () => {
const interactiveSelectors = ['[role="button"]', '[role="combobox"]', '[role="link"]', '[role="menuitem"]', '[role="menuitemcheckbox"]', '[role="menuitemradio"]', '[role="option"]', '[role="scrollbar"]', '[role="searchbox"]', '[role="slider"]', '[role="spinbutton"]', '[role="switch"]', '[role="tab"]', '[role="radio"]', '[role="textbox"]', '[role="treeitem"]', "a", "button", "summary", '[role="separator"][aria-valuenow]', '[role="separator"][aria-valuemin]', '[role="separator"][aria-valuemax]', "iframe"]

interactiveSelectors.forEach((selector) => {
cy.get(`${selector}[aria-hidden="true"]`).each((element) => {
cy.wrap(element).after("border-color").should("eq", "rgb(255, 255, 102)")
})
})

cy.get(`#interactive-elements input[aria-hidden="true"], #interactive-elements video[controls][aria-hidden="true"], #interactive-elements area[aria-hidden="true"], #interactive-elements audio[controls][aria-hidden="true"], #interactive-elements iframe[aria-hidden="true"], #interactive-elements select[aria-hidden="true"], #interactive-elements textarea[aria-hidden="true"], #interactive-elements video[controls][aria-hidden="true"]`).each((element) => {
cy.wrap(element).should("have.css", "border-color", "rgb(255, 255, 102)")
})
})

it("should contain warning content", () => {
cy.get(`#interactive-elements div[aria-hidden="true"], #interactive-elements a[aria-hidden="true"], #interactive-elements button[aria-hidden="true"], #interactive-elements summary[aria-hidden="true"]`).each((element) => {
cy.get(element).after("content").should("eq", "WARNING (W0017): Interactive element containing aria-hidden")
})
})
})
1 change: 1 addition & 0 deletions features.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,4 @@ A list of every a11y concern Checka11y.css will check for and highlight with lin
- [W0014](./codes.md#W0014): Checks for anchor tags that contain a link to content site.
- [W0015](./codes.md#W0015): Checks for images with the `longdesc` attribute.
- [W0016](./codes.md#W0016): Checks for zoom/scale being disabled in the meta `viewport`.
- [W0017](./codes.md#W0017): Checks if interactive elements contain `aria-hidden="true"`.
59 changes: 42 additions & 17 deletions src/warnings/features/_aria-hidden.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,46 @@
/* W0009: Elements with aria-hidden should not have focusable descendants. */

[aria-hidden="true"] {
a,
button,
summary {
&::after {
@include contentMessage(warning, "W0009", "Focusable element in a aria-hidden element.");
}
}

area,
audio[controls],
iframe,
input,
select,
textarea,
video[controls] {
@include vectorMessage(warning, "W0009", 350, "Focusable", "element in a aria-hidden element.");
}
a,
button,
summary {
&::after {
@include contentMessage(warning, "W0009", "Focusable element in a aria-hidden element.");
}
}

area,
audio[controls],
iframe,
input,
select,
textarea,
video[controls] {
@include vectorMessage(warning, "W0009", 350, "Focusable", "element in a aria-hidden element.");
}
}

/* W0017: Interactive Elements should not have aria-hidden */
$interactive-elements: ("a", "button", "summary", '[role="separator"][aria-valuenow]', '[role="separator"][aria-valuemin]', '[role="separator"][aria-valuemax]');

@each $el in $interactive-elements {
#{$el}[aria-hidden="true"]::after {
@include contentMessage(warning, "W0017", "Interactive element containing aria-hidden");
}
}

$interactive-tags: ("area", "audio[controls]", "iframe", "input", "select", "textarea", "video[controls]");

@each $tag in $interactive-tags {
#{$tag}[aria-hidden="true"] {
@include vectorMessage(warning, "W0017", 350, "Interactive", "element containing aria-hidden");
}
}

$interactive-roles: ("button", "combobox", "link", "menuitem", "menuitemcheckbox", "menuitemradio", "option", "scrollbar", "searchbox", "slider", "spinbutton", "switch", "tab", "radio", "textbox", "treeitem");

@each $role in $interactive-roles {
[role="#{$role}"][aria-hidden="true"]::after {
@include contentMessage(warning, "W0017", "Interactive element containing aria-hidden");
}
}
62 changes: 60 additions & 2 deletions test/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ <h6></h6>
</section>
<section>
<h2>Headings: reachable by assistive technologies</h2>
<p>Headings should be reachable by assistive technologies (do not use <code>aria-hidden</code> or similars on a heading).</code></p>
<p>Headings should be reachable by assistive technologies (do not use <code>aria-hidden</code> or similars on a heading)</p>
<h1 aria-hidden="true">H1 with aria-hidden="true"</h1>
<h2 aria-hidden="true">H2 with aria-hidden="true"</h2>
<h3 aria-hidden="true">H3 with aria-hidden="true"</h3>
Expand Down Expand Up @@ -336,7 +336,7 @@ <h2>Avoid using mouse event handlers without the appropriate keyboard alternativ
<div>
<div onclick="">A div with onclick</div>
<div onclick="" onkeydown="">A div with onclick and onkeydown</div>
<div onclick="" onkeydown="" role="button">A div with with onclick, onkeydown and role=button</div>
<div onclick="" onkeydown="" role="button">A div with onclick, onkeydown and role=button</div>
<div onclick="" onkeydown="" role="button" tabindex="-1">A div with onclick, onkeydown, role=button and tabindex=-1</div>
</div>
</section>
Expand Down Expand Up @@ -425,5 +425,63 @@ <h2>A <code>&lt;a&gt;</code> has an <code>href</code> linking to a content site
<li><a href="https://spotify.com/en/">Spotify Link</a></li>
</ul>
</section>
<section id='interactive-elements'>
<h2>Interactive Elements: not reachable by assistive technologies</h2>
<p>Interactive Elements should be reachable by assistive technologies (do not use <code>aria-hidden</code> on a Interactive Elements.) </p>
<a aria-hidden="true" href='https://github.com/jackdomleo7/Checka11y.css'>Anchor for Interactive purposes</a>
<map name="workmap" aria-hidden="true">
<area shape="rect" coords="34,44,270,350" alt="Clickable area" href="https://checka11y.jackdomleo.dev"/>
</map>

<map name="workmap" >
<area shape="rect" coords="34,44,270,350" alt="Clickable area" href="https://checka11y.jackdomleo.dev" aria-hidden="true"/>
</map>

<audio aria-hidden="true" controls></audio>

<button aria-hidden="true">Button</button>

<iframe aria-hidden="true" src="https://checka11y.jackdomleo.dev" title="Checka11y.css website"></iframe>

<input aria-hidden="true" type="text" />

<select aria-hidden="true"><option>Option</option></select>

<details >Interactive details element<summary aria-hidden="true">Summary</summary></details>

<textarea aria-hidden="true">textarea</textarea>

<video aria-hidden="true" controls></video>

<div aria-hidden='true' role='button'>interactive custom button</div>
<div role="link" aria-hidden="true">Custom Link</div>
<div role="combobox" aria-hidden="true">ComboBox</div>

<ul role="menu">
<li role="menuitem" aria-hidden="true">Menu Item 1</li>
<li role="menuitem" tabindex="0">Menu Item 2</li>
</ul>

<div role="menuitemcheckbox" aria-hidden="true">Menu Checkbox</div>
<div role="menuitemradio" aria-hidden="true">Menu Radio</div>
<div role="option" aria-hidden="true">Option</div>
<div role="radio" aria-hidden="true">Radio Button</div>
<div role="scrollbar" aria-hidden="true">Scroll Bar</div>
<div role="searchbox" aria-hidden="true">Search Box</div>
<div role="separator" aria-valuenow aria-hidden="true">Separator with aria-valuenow</div>
<div role="separator" aria-valuemax aria-hidden="true">Separator with aria-valuemax</div>
<div role="separator" aria-valuemin aria-hidden="true">Separator with aria-valuemin</div>
<div role="slider" aria-hidden="true">Slider</div>
<div role="spinbutton" aria-hidden="true">Spin Button</div>
<div role="switch" aria-hidden="true">Switch</div>

<div role="tablist">
<div role="tab" aria-selected="true">Tab 1</div>
<div role="tab" aria-hidden='true'>Tab 2</div>
</div>

<div role="textbox" aria-hidden="true">Text Box</div>
<div role="treeitem" aria-hidden="true">Tree Item</div>
</section>
</body>
</html>
Loading