Example
Jump to section titled: ExampleHTML
Jump to section titled: HTMLOption 1. Good for simple top level navigation.
<!-- see note below on aria-label. -->
<nav aria-label="Main">
<ul>
<!-- aria-current for users without visual clues. -->
<li><a href="/" aria-current="page"> Home </a></li>
<li><a href="/about" > About </a></li>
<li><a href="/services"> Services </a></li>
<li><a href="/contact"> Contact </a></li>
<!-- Link to footer nav. Icon hidden to screen readers -->
<li><a href="#more-navigation"
aria-label="More navigation links in the footer.">More
<span aria-hidden="true">▼</span></a></li>
</ul>
</nav>
Note:
- <nav> is a Landmark that gives screen readers an idea of structure.
- aria-label="Main" tells screen reader which navigation this is.
- aria-current="page" tells screen readers what page they are on.*
- <ul role="list"> is not needed. Safari now announces the number of list items if within <nav>.
<a href="/components/" aria-current="true"
aria-label="Currently viewing a single post under Components.">
Components</a>
Option 2. Adds a visually hidden heading as screen reader users look for headings more than landmarks.
<!-- see note below -->
<nav aria-labelledby="main-nav">
<h2 id="main-nav" class="visualy-hidden">Main Navigation</h2>
<ul>
<li><a href="/" aria-current="page"> Home </a></li>
<li><a href="/about" > About </a></li>
<li><a href="/services"> Services </a></li>
<li><a href="/blog"> Blog </a></li>
<li><a href="/contact"> Contact </a></li>
</ul>
</nav>
Note: Aria-labelledby is generally better. But, in a top level navigation it's likely this hidden <h2> will break the The "H1 must come first" rule.
CSS
Jump to section titled: CSSNot complete.
/* Flex to apportion link according to size */
header nav ul, {
display: flex;
flex-wrap: wrap;
gap: var(--space-m);
}
.nav a[href][aria-current="page"],
.nav a[href][aria-current="true"] {
text-decoration: underline;
text-decoration-thickness: .4rem;
text-decoration-color: var(--brand);
text-underline-offset: .8rem;
}
/* Styling the second nav target */
#more-navigation:target ul {
outline: .2rem solid var(--text);
outline-offset: var(--space-xl);
padding-inline-end: var(--space-2xl);
}
/* stop animation for those prefer reduced motion */
@media (prefers-reduced-motion: no-preference){
#more-navigation:target ul{
animation: slide-in-elliptic-left-fwd
0.4s cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s both;
}
}
/* Target animation created with animista.net */
@keyframes slide-in-elliptic-left-fwd {
0% {
transform: translateX(-800px) rotateY(30deg) scale(0);
transform-origin: -100% 50%;
opacity: 0;
}
100% {
transform: translateX(0) rotateY(0) scale(1);
transform-origin: 1800px 50%;
opacity: 1;
}
}
Note:
- Flex on the <ul> justifies content horizontally according to item size.
- Highligting the current page helps with UX.
- Globally padding the <a> tag increases the target size.
- If clearly navigation we can break the rule on underlining <a> tags.