Accessibility
Kelp includes a few utility classes for handling accessibility use cases in your UI.
Visually Hidden
The .visually-hidden
class hides content visually in the UI, but leaves it accessible to screen readers.
This class is sometimes paired with an ARIA live region used to announce changes to the UI that a sighted user would be aware but a visually impaired user would not.
<div
role="status"
class="visually-hidden"
id="announce"
></div>
const announce = document.querySelector('#announce');
announce.textContent = 'Content loaded'
It can also be used as an alternative to the [aria-label]
attribute.
This is useful when automated translation is a concern. Translators often skip [aria-label]
, but will translate content in a .visually-hidden
element.
<button>
<span class="visually-hidden">
Favorite This
</span>
<span aria-hidden="true">
❤️
</span>
</button>
Focusable Visually Hidden
The .visually-hidden-focusable
class hides content visually the same way the .visually-hidden
class does, but becomes visible when it receives focus.
This technique is most commonly used with skip nav links.
<a
class="visually-hidden-focusable"
href="#main"
>
Skip to Content
</a>
<nav><!-- ... --></nav>
Horizontal Scroll
The .scroll-horizontal
class enabled horizontal scrolling (if needed) on an element, without creating overflow issues on the rest of the document.
The most common use case for this class is with wide tables that might be wider than their parent element on smaller screens.
(You might have to make the browser window really small to see it on the example below.)
First | Last | Hero Name | Super Power | Costume Color |
---|---|---|---|---|
Peter | Parker | Spiderman | Spider Stuff | Red and Blue |
Bruce | Wayne | Batman | Bat Stuff | Black |
Tony | Stark | Ironman | Iron Stuff | Red and Yellow |
<div class="scroll-horizontal">
<table>
<!-- ... -->
</table>
</div>
Focus Styles
Kelp automatically applies consistent focus styles to focusable elements.
You can adjust them with a handful of CSS variables applied to the kelp.effects
cascade layer.
@layer kelp.effects {
/* Light Theme (default) */
:where(:root),
.kelp-theme-light {
--focus-ring-color: var(--color-blue-50);
--focus-ring-style: solid;
--focus-ring-width: var(--size-6xs);
--focus-ring-offset: var(--size-6xs);
}
/* Dark Theme */
.kelp-theme-dark {
--focus-ring-color: var(--color-blue-60);
}
}
Reduced Motion
Kelp automatically disables motion effects when the user has the prefers-reduced-motion
setting enabled in their OS.
If your effect is CSS-driven, you don’t need to do anything to respect this setting. It happens automatically as long as the /css/utilities/accessibility.css
class is included in your stylesheet (its automatically included in the main kelp.css
file).
/**
* Remove all animations and transitions for people that prefer not to see them
*/
@media (prefers-reduced-motion: reduce) {
*, :after, :before {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}