Fylgja Classic Footer
A classic footer groups the site’s secondary links into titled columns, with a subfooter below for the copyright and social links. The subfooter is the same row as the Inline Footer, with icon links in place of the text links.
Preview
<footer class="divide-y" style="--flow: 1.5rem; border-color: color-mix(in oklab, var(--root-bg) 75%, var(--root-fg))">
<nav aria-label="Footer" class="auto-grid gap" style="--max-col-size: max(8rem, (100% - 4.5rem) / 4); --gap: 2rem 1.5rem; --py: 0 2rem">
<div class="flow" style="--flow: 0.75rem">
<h2 style="--h-size: 1rem">Product</h2>
<ul style="--list-flow: 0.5rem">
<li><a href="#">Features</a></li>
<li><a href="#">Pricing</a></li>
<li><a href="#">Changelog</a></li>
</ul>
</div>
<div class="flow" style="--flow: 0.75rem">
<h2 style="--h-size: 1rem">Resources</h2>
<ul style="--list-flow: 0.5rem">
<li><a href="#">Documentation</a></li>
<li><a href="#">Guides</a></li>
<li><a href="#">Blog</a></li>
</ul>
</div>
<div class="flow" style="--flow: 0.75rem">
<h2 style="--h-size: 1rem">Company</h2>
<ul style="--list-flow: 0.5rem">
<li><a href="#">About</a></li>
<li><a href="#">Careers</a></li>
<li><a href="#">Contact</a></li>
</ul>
</div>
<div class="flow" style="--flow: 0.75rem">
<h2 style="--h-size: 1rem">Legal</h2>
<ul style="--list-flow: 0.5rem">
<li><a href="#">Privacy</a></li>
<li><a href="#">Terms</a></li>
<li><a href="#">Cookies</a></li>
</ul>
</div>
</nav>
<div class="flex-wrap gap align flow-none" style="--gap: 0.5rem 1.5rem">
<p><small>© 2026 Acme. All rights reserved.</small></p>
<nav aria-label="Social">
<ul class="flex gap" style="--gap: 1rem">
<li><a href="#" class="flex" aria-label="GitHub"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M15 22v-4a4.8 4.8 0 0 0-1-3.5c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35 0-3.5 0 0-1 0-3 1.5-2.64-.5-5.36-.5-8 0C6 2 5 2 5 2c-.3 1.15-.3 2.35 0 3.5A5.403 5.403 0 0 0 4 9c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65-.17.6-.22 1.23-.15 1.85v4"/><path d="M9 18c-4.51 2-5-2-7-2"/></svg></a></li>
<li><a href="#" class="flex" aria-label="Bluesky"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M6.335 5.144C4.681 3.945 2 3.017 2 5.97c0 .59.35 4.953.556 5.661C3.269 14.094 5.686 14.381 8 14c-4.045.665-4.889 3.208-2.667 5.41C6.363 20.428 7.246 21 8 21c2 0 3.134-2.769 3.5-3.5.333-.667.5-1.167.5-1.5 0 .333.167.833.5 1.5.366.731 1.5 3.5 3.5 3.5.754 0 1.637-.571 2.667-1.59C20.889 17.207 20.045 14.664 16 14c2.314.38 4.73.094 5.444-2.369.206-.708.556-5.072.556-5.661 0-2.953-2.68-2.025-4.335-.826C15.372 6.806 12.905 10.192 12 12c-.905-1.808-3.372-5.194-5.665-6.856z"/></svg></a></li>
<li><a href="#" class="flex" aria-label="YouTube"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M2.5 17a24.12 24.12 0 0 1 0-10 2 2 0 0 1 1.4-1.4 49.56 49.56 0 0 1 16.2 0A2 2 0 0 1 21.5 7a24.12 24.12 0 0 1 0 10 2 2 0 0 1-1.4 1.4 49.55 49.55 0 0 1-16.2 0A2 2 0 0 1 2.5 17"/><path d="m10 15 5-3-5-3z"/></svg></a></li>
<li><a href="#" class="flex" aria-label="RSS feed"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 11a9 9 0 0 1 9 9"/><path d="M4 4a16 16 0 0 1 16 16"/><circle cx="5" cy="19" r="1"/></svg></a></li>
</ul>
</nav>
</div>
</footer>Usage
- Give the
<footer>thedivide-yutility with a border color and a--flow. That draws the line above the subfooter and spaces it, with no extra rule. - The menu is one
<nav>withauto-grid. It fits as many columns as the footer has room for, each at least--max-col-sizewide, so it adapts to the space it gets instead of the screen size, and long links never run into the next group. - Each group is a heading and a
<ul>wrapped in aflowcontainer, so the title has no top margin and the columns line up.--list-flowon the list adds back the space between links that base removes inside a nav. - The subfooter uses
flex-wrap gap align, so the copyright sits at the start and the social links at the end, and the row wraps on narrow screens. - Social links are icon links. Each
<svg>isaria-hiddenand the link gets its name fromaria-label.
Anatomy
| Part | Responsibility |
|---|---|
<footer> |
The container, and through divide-y the subfooter border. |
Footer <nav> |
The grid of link groups. |
| Group | A heading and its list of links. |
| Subfooter | The copyright and the social nav, laid out like the inline footer. |
Social <nav> |
The icon links, named with aria-label. |
Accessibility
- A
<footer>that is a direct child of<body>is thecontentinfolandmark. - Label each nav (“Footer”, “Social”) so it is not confused with the main navigation.
- Every icon link needs an accessible name. Put it in
aria-labeland hide the icon witharia-hidden="true". - The icons are 24 pixels square, which meets the WCAG 2.2 minimum target size. Keep the gap between them so they are not tapped by mistake.
Examples
For the same footer with a wide branding column beside the menus, use the Brand Footer. When the page only needs the legal links, use the Inline Footer.
Related: Inline Footer, Brand Footer, Navbar.
FAQ
How does the line above the subfooter get drawn?
The divide-y utility puts a top border on every child except the first, and the --flow variable adds the space above it. The border color is set once on the footer and inherited.
How many columns does the menu use?
Up to four, and fewer when space runs out. The --max-col-size of max(8rem, (100% - 4.5rem) / 4) keeps each column at least 8rem wide and at least a quarter of the row, so the groups span the full width and wrap instead of overlapping. Raise 8rem if your longest link is wider, and change the 4 to match your number of groups.
Why one nav for all the groups instead of one per group?
Each nav is a landmark, and four landmarks in the footer make the landmark list noisy. One labeled nav with a heading per group keeps it short, and the headings still let screen reader users jump between groups.
Which heading level should the group titles use?
Whatever fits the page outline, usually h2 since the footer sits outside the main content. The visual size is set with --h-size, so the level never has to be picked for its size.