3 min read

Dark website sections with scoped CSS variables

A developer note on building a dark footer or call-to-action section with CSS variables, including a Tailwind v4 mapping and state checks.

On this page

A dark footer can give a light website a strong finish. It doesn't require a visitor-facing dark-mode switch or a second copy of every component. For a fixed section palette, a few scoped CSS variables can be enough.

Use the pattern below when a section needs its own background, text and accent colors.

Define the colors components actually use

Give the page a small set of variables for background, text, muted text, borders and accents. Use those variables in the components instead of repeating fixed colors throughout the stylesheet.

:root {
  --surface: #fafaf7;
  --text: #15181c;
  --muted: #565e67;
  --border: #c7ccd1;
  --accent: #185fb7;
}

.page-section {
  background: var(--surface);
  color: var(--text);
}

.section-note {
  color: var(--muted);
}
.section-link {
  color: var(--accent);
}
.section-rule {
  border-color: var(--border);
}

The values here are an illustrative palette. Check the actual text sizes, states and contrasts in your design.

Override the variables on the section

Apply another class to the section that needs the dark treatment:

.tonal-band {
  --surface: #101820;
  --text: #f5f7fa;
  --muted: #b3bec9;
  --border: #586674;
  --accent: #80baff;
}
<section class="page-section tonal-band">
  <h2>Talk with our office</h2>
  <p class="section-note">Find the right contact details below.</p>
  <a class="section-link" href="/contact">Contact the office</a>
</section>

Descendants that use these custom properties inherit the values from the section. Components outside it retain the page values. MDN's custom-property documentation explains the inheritance behavior.

Watch for hard-coded colors

A component with a fixed white background won't automatically become dark because an ancestor overrides --surface. The component must use the variable. The same applies to icons, form fields, borders, hover states and focus indicators.

Review all those states against the new surface. A screenshot of the default button misses its hover and keyboard-focus behavior. Test text over images separately; a palette that works on a solid panel may be unreadable over a bright photograph.

If you use Tailwind, map the variables deliberately

In Tailwind v4, an illustrative mapping is:

@theme inline {
  --color-surface: var(--surface);
  --color-copy: var(--text);
}

A component can then use bg-surface text-copy. The inline mapping lets those utilities refer to the underlying variables used by the section. Check the generated CSS for your setup; the plain CSS example above doesn't require Tailwind. See Tailwind's guidance on referencing other variables.

Know when this pattern is too small for the job

A fixed section palette and a user-controlled site theme are different requirements. A theme preference may need persistence, system-preference handling and a control that remains understandable to keyboard and screen-reader users. Scoped variables can still be part of that system, but they don't implement it by themselves.

For an agency site with one dark closing section, keep the implementation proportionate. Start with the approved composition, give its components the colors they need and test the actual states. The design should look intentional without adding machinery the visitor never uses.

For the design side of that decision, see the Coker closing section in our insurance agency website examples.

Keep reading

All articles

See what your agency’s site could look like.

Book a Call