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
22 changes: 22 additions & 0 deletions checka11y-warnings.css
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,28 @@ a[href="#"]::after, a[role=button]::after, a[href^="javascript:"]::after {
background-color: var(--checka11y-bg-warning);
}

section:empty::before, section > :not(h1, h2, h3, h4, h5, h6, img):last-child::before {
display: block;
font-size: 1rem;
font-family: verdana, geneva, tahoma, sans-serif;
font-weight: 700;
font-style: initial;
padding: var(--checka11y-space-4) var(--checka11y-space-6);
border-radius: 0.75rem;
letter-spacing: initial;
text-decoration: none;
text-transform: initial;
text-shadow: none;
content: "WARNING (W0012): A <section> should contain a heading element." !important;
color: var(--checka11y-text-warning);
border: 0.4rem solid var(--checka11y-border-warning);
background-color: var(--checka11y-bg-warning);
}

section > :is(h1, h2, h3, h4, h5, h6) ~ :not(:is(h1, h2, h3, h4, h5, h6, img)):last-child::before {
content: none !important;
}

[title]::after {
display: block;
font-size: 1rem;
Expand Down
22 changes: 22 additions & 0 deletions checka11y.css
Original file line number Diff line number Diff line change
Expand Up @@ -792,6 +792,28 @@ a[href="#"]::after, a[role=button]::after, a[href^="javascript:"]::after {
background-color: var(--checka11y-bg-warning);
}

section:empty::before, section > :not(h1, h2, h3, h4, h5, h6, img):last-child::before {
display: block;
font-size: 1rem;
font-family: verdana, geneva, tahoma, sans-serif;
font-weight: 700;
font-style: initial;
padding: var(--checka11y-space-4) var(--checka11y-space-6);
border-radius: 0.75rem;
letter-spacing: initial;
text-decoration: none;
text-transform: initial;
text-shadow: none;
content: "WARNING (W0012): A <section> should contain a heading element." !important;
color: var(--checka11y-text-warning);
border: 0.4rem solid var(--checka11y-border-warning);
background-color: var(--checka11y-bg-warning);
}

section > :is(h1, h2, h3, h4, h5, h6) ~ :not(:is(h1, h2, h3, h4, h5, h6, img)):last-child::before {
content: none !important;
}

[title]::after {
display: block;
font-size: 1rem;
Expand Down
3 changes: 3 additions & 0 deletions codes.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,3 +124,6 @@ A list of every Checka11y.css error & warning code with details on what the issu

- ### W0011
The highlighted element `<a>` has been detected to have `href="#"`, `role="button"` , `href="javascript:doSomething(0)"`. Those anchor elements are often used to trigger a click event on the page. This can be disorientating to a user, especially those with visual impairments and those with cognitive disabilities. Links should redirect to a resource/page. [Read more about this here](https://www.htmhell.dev/8-anchor-tag-used-as-button).

- ### W0012
The `<section>` element represents a generic standalone section of a document, which doesn't have a more specific semantic element to represent it. This means `<section>` element should be identified, typically by including a heading (`<h1>`-`<h6>` element) as a child of the `<section>` element. [Read more about this here](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/section)
43 changes: 43 additions & 0 deletions cypress/integration/section_spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
describe('<section>', () => {
const sectionLastChildHTML = [];
before(() => {
cy.visit('/test/index.html');

// Get all last child element from a section with heading element.
cy.get('section > :is( h1, h2, h3, h4, h5, h6 ) ~ :not( :is( h1, h2, h3, h4, h5, h6, img ) ):last-child')
.each(element => {
cy.get(element)
.invoke('prop', 'outerHTML').then(html => {
sectionLastChildHTML.push(html);
})
});
});

it('should show warning on last child if section does not have heading element', () => {
cy.get('section > :not( h1, h2, h3, h4, h5, h6, img ):last-child')
.each((element) => {
cy.get(element)
.invoke('prop', 'outerHTML').then(html => {
if(!sectionLastChildHTML.includes(html)) {
cy.get(element)
.before('content')
.should('eq', 'WARNING (W0012): A <section> should contain a heading element.');
}
})
});
});

it('should show warning on if section is empty', () => {
cy.get('section:empty')
.each((element) => {
cy.get(element)
.invoke('prop', 'outerHTML').then(html => {
if(!sectionLastChildHTML.includes(html)) {
cy.get(element)
.before('content')
.should('eq', `WARNING (W0012): A <section> should contain a heading element.`);
}
})
});
});
});
1 change: 1 addition & 0 deletions features.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,4 @@ A list of every a11y concern Checka11y.css will check for and highlight with lin
- [W0009](./codes.md#W0009): Checks for focusable elements inside `aria-hidden="true"` elements.
- [W0010](./codes.md#W0010): Checks for heading elements containing `role="text"` attribute.
- [W0011](./codes.md#W0011): Checks for anchor tags that are used as buttons.
- [W0012](./codes.md#W0012): Checks for heading element inside `<section>` element.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@
"Shona McKenzie (https://github.com/shonamckenzie)",
"Ashar Setiawan (https://github.com/azhsetiawan)",
"Bogdan Lazar (https://github.com/tricinel)",
"Martin Sidorov (https://github.com/Matrix278)"
"Martin Sidorov (https://github.com/Matrix278)",
"Shaddam Amru Hasibuan <shaddam.a.h@gmail.com> (https:/github.com/shamahdotdev)"
],
"keywords": [
"checka11y",
Expand Down
1 change: 1 addition & 0 deletions src/warnings/checka11y-warnings.scss
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
@import "./features/images";
@import "./features/inline";
@import "./features/links";
@import "./features/section";
@import "./features/title";
@import "./features/underline";
@import "./features/headings";
18 changes: 18 additions & 0 deletions src/warnings/features/_section.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/* W0012: A <section> should contain a heading element */

/**
* TODO: Investigate refactoring to use :has() when supported by major browsers
* Currently, the first selector below will give a warning to all last child element inside a section and then remove it with the second selector by selecting if there's a heading element inside a section.
* This can be solved easily and more practical by using :has(h1 - h6) to check if a section contains heading element.
*/

section {
&:empty::before,
> :not( h1, h2, h3, h4, h5, h6, img ):last-child::before {
@include contentMessage(warning, "W0012", "A <section> should contain a heading element.");
}

> :is( h1, h2, h3, h4, h5, h6 ) ~ :not( :is( h1, h2, h3, h4, h5, h6, img ) ):last-child::before {
content: none !important;
}
}
10 changes: 10 additions & 0 deletions test/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -380,5 +380,15 @@ <h2>Anchor tags should not be used as buttons</h2>
<a href="javascript:void(0)" role="button">Do another thing</a>
<a href="javascript:doSomething(0)">Do another thing</a>
</section>
<section>
<h2>A <code>&lt;section&gt;</code> should contain a heading element</h2>
<section>
<h2>This is a heading element.</h1>
</section>
<section><!-- This is an empty section --></section>
<section>
<p>this is not a heading element, just a cool paragraph.</p>
</section>
</section>
</body>
</html>