Manifest · Manifest member
theme_color and background_color manifest members
Published
theme_color is the colour the operating system and browser use for the chrome around an
installed app: the title bar on desktop, the status bar and task-switcher card on Android, and
the accent of the install dialog. background_color is the colour painted behind the app
icon on the splash screen and inside the window from launch until the page’s own CSS has
painted. The two members exist so that nothing white flashes between the icon tap and the
first frame.
Chrome 46, Edge 79, Samsung Internet 5.0, Android WebView 46, and Firefox 79 on Android read
both members; Safari reads theme_color from iOS 15 and macOS 17 but has no consumer for
background_color (BCD html.manifest.theme_color and html.manifest.background_color).
Desktop Firefox installs no apps from the manifest and uses neither.
Member
Section titled “Member”- Type: string holding a CSS
<color>: a named colour, hex,rgb(),hsl(), or any other form the engine’s CSS parser accepts. Chromium stores the parsed value as an opaque colour, so an alpha channel is discarded. - Default: absent. With no
theme_colorthe engine uses its own chrome colour; with nobackground_colorthe splash screen is white (Chromium) or the system background. - Example value:
"theme_color": "#1a1a2e","background_color": "#1a1a2e".
A value the CSS parser rejects is dropped with property 'theme_color' ignored, 'bluish' is not a valid color. (the same message names background_color), and the member then behaves as
absent (manifest_parser.cc).
The manifest value is the colour of record only until a page is showing. Once loaded, a
<meta name="theme-color"> element in the document overrides theme_color for that page,
and because the element accepts a media attribute the page can declare one colour per
colour scheme, which the manifest cannot (MDN, <meta name="theme-color">). Chromium reads
background_color only for the splash screen and the pre-paint window fill, so the page’s
body background must be set to the same value or a visible colour step appears at first
paint.
Examples
Section titled “Examples”The examples share one dark-navy brand colour, #1a1a2e, and a light variant, #f5f5fa.
One manifest colour, two page colours for light and dark mode
Section titled “One manifest colour, two page colours for light and dark mode”The manifest carries the colour used before any page exists, so it holds the default scheme.
The two <meta> elements take over once the page loads and switch with the user’s system
setting.
{ "theme_color": "#1a1a2e", "background_color": "#1a1a2e"}<meta name="theme-color" content="#f5f5fa" media="(prefers-color-scheme: light)"><meta name="theme-color" content="#1a1a2e" media="(prefers-color-scheme: dark)">On Android the status bar follows the matching <meta> as soon as the page paints; during
the splash screen it shows the manifest value regardless of the scheme.
A splash screen that hands off without a colour step
Section titled “A splash screen that hands off without a colour step”Chromium composes the splash from background_color, the largest icons entry, and name.
Setting the document background to the same colour, before any stylesheet that might load
late, keeps the handoff from splash to page invisible.
:root { color-scheme: dark; background: #1a1a2e;}@media (prefers-color-scheme: light) { :root { background: #f5f5fa; }}A light-scheme user still sees the navy splash, because the manifest has one value; the step
from navy to #f5f5fa happens at first paint and lasts one frame, which is the trade-off for
not shipping two manifests.
Keeping the live theme colour and the page in sync
Section titled “Keeping the live theme colour and the page in sync”Nothing at runtime reports which colour the OS chrome adopted, so the page reads back its own
active <meta> element and uses that value for in-page surfaces such as a sticky header. When
no element matches, the code falls back to the manifest’s documented colour.
function activeThemeColor() { const dark = matchMedia('(prefers-color-scheme: dark)').matches; const metas = [...document.querySelectorAll('meta[name="theme-color"]')]; const match = metas.find((m) => !m.media || matchMedia(m.media).matches === true); return match?.content ?? (dark ? '#1a1a2e' : '#f5f5fa');}
document.querySelector('header').style.background = activeThemeColor();matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => { document.querySelector('header').style.background = activeThemeColor();});The listener matters on desktop, where the user can flip the system scheme while the app is open; the OS title bar updates by itself, and this keeps the header with it.
See also
Section titled “See also”- icons manifest member
- name and short_name manifest members
- PWAs on iOS and Safari
- Web Application Manifest: theme_color member (w3.org)
- Customize your app’s theme and background colors (developer.mozilla.org)
Specifications
| Specification | Status |
|---|---|
| Web App Manifest: theme_color / background_color | W3C draft |
| Web Application Manifest: theme_color member | W3C |
| Web Application Manifest: background_color member | W3C |
- Legend
- Yes
- Partial
- Flag
- No
- Unknown
| Browser / Platform | Support | Versions | Confidence | Source | Notes |
|---|---|---|---|---|---|
| Chrome (Desktop) | Yes | 46 | high | source | 1 |
| Chrome (Android) | Yes | 46 | high | source | 23 |
| Edge (Desktop) | Yes | 79 | high | source | 45 |
| Firefox (Desktop) | No | — | high | source | 67 |
| Firefox (Android) | Yes | 79 | high | source | 8 |
| Safari (macOS) | Yes | 17 | high | source | 9 |
| Safari (iOS) | Yes | 15 | high | source | 10 |
| Samsung Internet | Yes | 5.0 | high | source | 1112 |
| WebView (Android) | Yes | 46 | high | source | 1314 |
| Chrome (Desktop) | Yes | 46 | high | source | 15 |
| Chrome (Android) | Yes | 46 | high | source | 1617 |
| Edge (Desktop) | Yes | 79 | high | source | 1819 |
| Firefox (Desktop) | No | — | high | source | 2021 |
| Firefox (Android) | Yes | 79 | high | source | 22 |
| Safari (macOS) | No | — | high | source | 2324 |
| Safari (iOS) | No | — | high | source | 252627 |
| Samsung Internet | Yes | 5.0 | high | source | 2829 |
| WebView (Android) | Yes | 46 | high | source | 3031 |
- Covers the `theme_color` entry.
- Covers the `theme_color` entry.
- Derived by browser-compat-data mirroring from Chrome.
- Covers the `theme_color` entry.
- Derived by browser-compat-data mirroring from Chrome.
- Covers the `theme_color` entry.
- No Firefox support is recorded in browser-compat-data.
- Covers the `theme_color` entry.
- Covers the `theme_color` entry.
- Covers the `theme_color` entry.
- Covers the `theme_color` entry.
- Derived by browser-compat-data mirroring from Chrome Android.
- Covers the `theme_color` entry.
- Derived by browser-compat-data mirroring from Chrome Android.
- Covers the `background_color` entry.
- Covers the `background_color` entry.
- Derived by browser-compat-data mirroring from Chrome.
- Covers the `background_color` entry.
- Derived by browser-compat-data mirroring from Chrome.
- Covers the `background_color` entry.
- No Firefox support is recorded in browser-compat-data.
- Covers the `background_color` entry.
- Covers the `background_color` entry.
- No Safari support is recorded in browser-compat-data.
- Covers the `background_color` entry.
- No Safari on iOS support is recorded in browser-compat-data.
- Derived by browser-compat-data mirroring from Safari.
- Covers the `background_color` entry.
- Derived by browser-compat-data mirroring from Chrome Android.
- Covers the `background_color` entry.
- Derived by browser-compat-data mirroring from Chrome Android.