Retour au catalogue

Footer Dark Minimal

Footer sombre ultra-minimaliste. Marque centree, socials et copyright. Ideal pour les portfolios et sites mono-page.

footersimple Dark Responsive a11y
darkminimalportfolioagencycentered
Theme

How to build a dark minimal footer in React

A dark minimal footer in React centers the brand name, nav links, social links and copyright in a single vertical column using flexbox and CSS custom properties for theming. No external libraries needed; hover states are handled with inline onMouseEnter/onMouseLeave handlers.

  • Stack: React (client component), CSS custom properties, zero external dependencies, ~130 lines.
  • Animation: CSS-only, color transition on links at 0.15s, no Framer Motion.
  • Layout: single centered flexbox column; all sections are optional and render only when data is provided.
  • Accessible: native anchor tags, semantic footer element, text contrast at 40-50% white on dark background.
  • Responsive by default; flexWrap on the nav row handles narrow viewports.

Footer Dark Minimal is a centered, column-stacked React footer for dark-themed sites. It renders a brand name as an uppercase link, an optional tagline, a wrapping nav row, a social row and a copyright line, all separated by a 40px hairline divider. Every section renders conditionally, so you drop in only what you need.

Anatomy

A single `<footer>` element wraps a centered container div (max-width from `--container-max-width`, padding from `--container-padding-x`). Inside, five stacked children: an `<a>` for the brand name (uppercase, 700 weight), an optional `<p>` for the description, a `<nav>` with wrapping flex row for page links, a flex row for social platform links, a 40px horizontal rule as a `<div>` (1px height, `--color-border-dark`), and a `<p>` for the copyright string. Gap between rows is 1.5rem.

How it works

The component is a straightforward presentational React function with no state or effects. Theming relies entirely on CSS custom properties (`--color-background-dark`, `--color-foreground-on-dark`, `--color-border-dark`) so it adapts to any preset without a line of JS. Hover on links is handled with onMouseEnter/onMouseLeave that mutate `e.currentTarget.style.color` directly, a deliberate choice to avoid a style sheet or CSS modules dependency while keeping the bundle minimal. The 40px divider between social links and copyright is a plain `<div>` acting as a visual pause before the legal line.

How to build it in React

  1. Set up the outer shell

    Create a `<footer>` with background set to `var(--color-background-dark)` and 3rem vertical padding. Inside, a centered `div` uses flexbox column with `alignItems: 'center'` and a 1.5rem gap. All children stack automatically.

    <footer style={{ background: "var(--color-background-dark)", padding: "3rem 0" }}>
      <div style={{ display: "flex", flexDirection: "column", alignItems: "center", gap: "1.5rem" }}>
        {/* children */}
      </div>
    </footer>
  2. Brand name and description

    Render the brand as an uppercase `<a href='/'>` at font-weight 700 and letter-spacing 0.05em. Wrap the description in a conditional block, only render when the string is non-empty. Cap it at max-width 400px and drop the opacity to 40% white so it recedes behind the brand.

    {brandDescription && (
      <p style={{ color: "rgba(255,255,255,0.4)", maxWidth: "400px", textAlign: "center" }}>
        {brandDescription}
      </p>
    )}
  3. Nav and social rows

    Both rows are `display: flex` with a 1.5rem gap and `flexWrap: 'wrap'` on the nav so it breaks on small screens. Links start at 50% white opacity and step up to 80% on hover. Use onMouseEnter/onMouseLeave to set the color directly on `e.currentTarget.style`, no CSS class needed.

    onMouseEnter={(e) => (e.currentTarget.style.color = "rgba(255,255,255,0.8)")}
    onMouseLeave={(e) => (e.currentTarget.style.color = "rgba(255,255,255,0.5)")}
  4. Hairline divider and copyright

    Add a `<div>` that is 40px wide, 1px tall, with `background: var(--color-border-dark)` and a 0.5rem top/bottom margin. Below it, the copyright `<p>` drops to 11px (0.6875rem) at 25% white opacity so it barely registers visually, present for legal requirements, invisible to the eye.

    <div style={{ width: "40px", height: "1px", background: "var(--color-border-dark)", margin: "0.5rem 0" }} />
    <p style={{ fontSize: "0.6875rem", color: "rgba(255,255,255,0.25)" }}>{copyright}</p>

When to use it

Use it on dark-themed single-page sites, portfolios, agency pages, or SaaS landing pages where the footer is a closing punctuation mark rather than a navigation hub. It works best when the page already carries a strong visual identity and the footer just needs to exit cleanly. Skip it when you need multi-column link groups, newsletter sign-ups or heavy legal sections, the single-column layout has no room for that density.

Used by

  • Stripe, Uses centered dark footers with minimal link rows on campaign and product landing pages.
  • Loom, Dark footer with brand mark, a flat nav row and a subdued copyright line on its marketing pages.
  • Framer, Minimal centered footer on product landing pages, brand-first with links in a single row.

FAQ

Can I add a logo image instead of the text brand name?

Replace the `<a>` text node with an `<img>` or an SVG inline component. Keep the anchor wrapper so the logo remains a home link; adjust the width to whatever fits your mark.

How do I change the link hover color from white to an accent color?

In the onMouseEnter handler, swap `rgba(255,255,255,0.8)` for your accent value, for example `var(--color-accent)`. Do the same for the onMouseLeave reset. No CSS class or extra state needed.

Is this footer accessible for keyboard and screen reader users?

The component uses a semantic `<footer>` element and native `<a>` tags, so keyboard navigation and screen readers work without extra ARIA. The low-opacity copyright text may fail WCAG AA contrast; add an `aria-label` with the full text if legal compliance requires it.

Why are hover styles handled with inline JS instead of a CSS class?

The component uses inline styles throughout to stay self-contained and avoid a dependency on CSS modules or a global stylesheet. The onMouseEnter/onMouseLeave pattern is the pragmatic trade-off for a simple, isolated component. If your project uses Tailwind, replacing inline styles with utility classes and the `hover:` variant is straightforward.

"use client";

interface SocialLink {
  platform: string;
  href: string;
}

interface NavLink {
  label: string;
  href: string;
}

interface FooterDarkMinimalProps {
  brandName?: string;
  brandDescription?: string;
  socialLinks?: SocialLink[];
  navLinks?: NavLink[];
  copyright?: string;
}

export default function FooterDarkMinimal({
  brandName = "Brand",

Code complet réservé à Pro

Code source intégral, export multi-framework et playground.

Passer en Pro, 9,99€/mois

Reviews

Dark Minimal Footer React, Centered Layout Tutorial