NavigationSite footer
Site footer
The closing statement. A serif headline, a one-line description, the same nav as the header, and a copyright line.
Demo
The footer sits in the same warm-neutral palette as the rest of the site. The doc system uses a slightly different footer shape; this is the production site footer.
Default
Anatomy
- Three rows: lead, nav, copyright
- Lead:
font-instrument-serif, 1.5 rem, 1.2 line-height - Body: 0.875 rem, 0.5 rem gap below the lead,
--muted-foreground - Nav: 0.875 rem, 1.5 rem row gap, 1.5 rem column gap
- Copyright row: 0.75 rem,
--muted-foreground, 0.75 rem padding-top, 1 px--line-subtletop border - Padding: 3.5 rem vertical, 1.5 rem horizontal at desktop, 2 rem at mobile
Implementation
site-footer.tsx
import Link from "next/link"
interface NavLink { label: string; href: string }
interface SiteFooterProps {
links: NavLink[]
lead: string
body?: string
}
export default function SiteFooter({ links, lead, body }: SiteFooterProps) {
const year = new Date().getFullYear()
return (
<footer className="site-footer" role="contentinfo">
<div className="site-footer__inner">
<div className="site-footer__lead">
<p className="font-serif text-2xl">{lead}</p>
{body ? <p className="mt-2 text-sm text-muted-foreground">{body}</p> : null}
</div>
<div className="site-footer__meta">
<nav className="site-footer__nav" aria-label="Footer">
{links.map(({ href, label }) => (
<Link key={href} href={href} className="site-footer__link">{label}</Link>
))}
</nav>
<div className="site-footer__bottom">
<span>© {year} izaias</span>
<a href="https://medium.com/@iz.iuqo" target="_blank" rel="noopener noreferrer" className="site-footer__link">Medium</a>
</div>
</div>
</div>
</footer>
)
}Props
| Prop | Type | Default | Description |
|---|---|---|---|
links | { label: string; href: string }[] | None | Required: the nav items |
lead | string | None | Required: the lead headline |
body | string | None | Optional secondary line |