---
title: "Reduced transparency"
description: "What each rung of the material ladder becomes when the reader has asked for less translucency. The layout must not move, and this page says why."
url: "https://opsinjs.pensievelabs.org/accessibility/reduced-transparency"
source: "https://opsinjs.pensievelabs.org/accessibility/reduced-transparency.md"
section: "Accessibility"
kind: "accessibility"
reviewed: "2026-09-02"
reviewer: "design"
aliases: ["reduce transparency setting", "backdrop blur off", "frosted glass"]
---

> Elements written as `<PascalCase … />` below are opsinjs documentation
> components. Their attributes are the content: the values they render are
> generated from `tokens/*.json` and `registry/catalogue.ts` and are
> published separately at https://opsinjs.pensievelabs.org/r/index.json and under the Reference
> section.
> Nothing is missing from this page. The data simply does not live in
> the prose.

<PageTemplate kind="accessibility" />

## What we guarantee [#what-we-guarantee]

Three of the six rungs on the material ladder are translucent, and translucency
over arbitrary content is the single most reliable way to produce text that
cannot be read. `prefers-reduced-transparency: reduce` is therefore implemented as
a first-class degradation in `app/globals.css` and `app/product.css`, not as an
afterthought.

| Rung | Normally                         | Under reduced transparency        |
| ---- | -------------------------------- | --------------------------------- |
| 0    | Opaque page background, no blur  | Unchanged                         |
| 1    | Opaque card surface, no blur     | Unchanged                         |
| 2    | Opaque card surface with shadow  | Unchanged                         |
| 3    | Translucent, 8 px backdrop blur  | Opaque card surface, blur removed |
| 4    | Translucent, 20 px backdrop blur | Opaque card surface, blur removed |
| 5    | Translucent veil, slight blur    | Opaquer veil, blur removed        |

The rungs are numbered here rather than named; their names, their intended uses
and the rule for choosing between them are on
[The ladder](../foundations/materials/the-ladder.mdx). The values above are the
ones actually declared for `--opsin-material-N-bg` and `--opsin-material-N-blur`
in the stylesheet.

Two guarantees follow from that table:

**Nothing moves.** Only the background colour and the blur radius change. No
padding, no radius, no size, no position. A layout that is correct with
translucency is byte-for-byte the same layout without it, which means the
preference cannot introduce a reflow bug and cannot be a source of a truncated
value.

**The topmost rung gets more opaque, not less.** Rung 5 is the veil that
separates a modal surface from what is behind it. Removing its translucency
entirely would remove the separation, so instead it darkens. The reader asked
for less see-through, not for less contrast.

The full ladder, the rungs' intended uses and the contrast floor that governs
text on them are on
[The ladder](../foundations/materials/the-ladder.mdx) and
[Reduced transparency in Foundations](../foundations/materials/reduced-transparency.mdx).

## What you own [#what-you-own]

**Any translucent surface you build yourself.** A custom overlay with
`rgba()` and `backdrop-filter` is not reached by the media query above. Either
build it from a rung, or add your own reduced-transparency branch.

**Photographic and video backdrops.** The ladder's measured contrast assumes the
declared opaque fallback behind the surface. Text over a photograph has no
guaranteed contrast at all, and the fix is a scrim, not a heavier font weight. See
[The contrast floor](../foundations/materials/the-contrast-floor.mdx).

**Your composited-surface budget.** Reduced transparency is also a performance
lever: with blur removed, the compositing cost of a screen drops. That does not
license three stacked blurred surfaces the rest of the time. The budget is at
most three, and the reasoning is on
[Performance budget](../foundations/materials/performance-budget.mdx).

**Windows and Linux.** `prefers-reduced-transparency` maps cleanly to the Apple
and Android settings. On Windows the closest control is the transparency-effects
toggle, and browser support for reporting it has historically been uneven. Do not
assume the query fires everywhere; treat it as an enhancement that is *available*
rather than *guaranteed*.

## How to check [#how-to-check]

<Steps>
  ### Turn the preference on [#turn-the-preference-on]

  macOS and iOS: Settings → Accessibility → Display → Reduce transparency. Android:
  Settings → Accessibility → Colour and motion. Or emulate the query in developer
  tools for a quick pass.

  ### Screenshot before and after and difference them [#screenshot-before-and-after-and-difference-them]

  **Expected result:** the two images differ only in the fill and blur of
  rungs 3, 4 and 5. **Failure looks like** anything moving. A shifted baseline, a
  changed card height and a repositioned close button all mean that something
  other than colour was tied to the translucent style.

  ### Read the text on every translucent surface over your worst backdrop [#read-the-text-on-every-translucent-surface-over-your-worst-backdrop]

  Put the busiest, highest-contrast content you have behind the surface: a
  photograph, a dense chart, a wall of text. Then check the reading with
  transparency both on and off. The *off* case is the easy one.

  ### Check the modal separation [#check-the-modal-separation]

  Open a dialog with the preference on. &#x2A;*Expected result:** the content behind is
  clearly subordinate. **Failure looks like** a scrim so light that the reader
  cannot tell which layer is interactive, which is a keyboard and screen-reader
  problem as much as a visual one.
</Steps>

## Measured results [#measured-results]

<ContrastReport scope="materials" />

Contrast on rungs 3 and 4 is measured against each rung's declared opaque
fallback, which is the reduced-transparency value. That makes the published
figure the *reduced-transparency* figure, and the normal case is measured
against the same fallback rather than against a real backdrop. That is an
optimistic simplification, and it is stated here rather than hidden.

## Known gaps [#known-gaps]

* **No real-backdrop measurement exists.** We measure against the fallback, not
  against a distribution of photographs.
* **Windows and Linux support for the query is not verified** in this codebase,
  and there is no JavaScript fallback.
* **One component renders the ladder.** `Surface` reads
  `--opsin-material-<rung>-*` for all six rungs and swaps to the opaque fallback
  under the query; every other built component sits on a rung rather than
  choosing one, so the ladder has had exactly one implementation to be wrong in.

## Updates to this page [#updates-to-this-page]

<Reviewed />
