Status page CSS
The hooks your own CSS can rely on across releases. Everything not listed here may change without notice.
Enter your CSS in Custom CSS under Advanced. Use the editor wherever it has a control: logo, accent colour, header colour for light and dark, background and theme are set there, and the editor derives readable text colours from them. CSS is for what the editor does not offer. How to create the page is in Publish a status page.
How it is applied
Your CSS sits in a style element inside the page, after the layout's own stylesheet, so at equal specificity your rule wins. Nothing scopes it for you: selectors reach the whole page document, so start them with .sp. The layouts' own rules are plain and class-prefixed (.sp .sp-…), so write yours the same way, not shorter. Dark mode is the class dark on the document element: write .dark .sp … for it.
CSS written before the layouts arrived (October 2026) targets markup that no longer exists and has to be rewritten against these hooks.
Attributes on the root
The element .sp carries these attributes, and all values are stable. Status elements carry data-s.
| Attribute | Values | What it tells you |
|---|---|---|
data-layout | essential, brand, overview | The layout the page uses. |
data-surface | open, cards | Open paper with hairlines (Essential) or cards (Brand, Overview). |
data-state | ok, warn, down, idle | The overall state of the page. |
data-ground | paper, white, cool | The chosen background. |
data-head | brand | Present only when a header colour is set for the current theme. |
data-tv | – | Present (empty) in the TV view. |
data-s | up, ok, degraded, warn, down, maintenance, stale, idle | The state of a status element such as a service row or a message. |
Blocks you can target
Only these blocks are documented. Their inner structure is not.
| Class | What it is | Layouts |
|---|---|---|
.sp-head | Header band: logo or name, language, notify button. | all |
.sp-logo | Your logo image. | all |
.sp-ident-name | The company name when there is no logo. | all |
.sp-btn, .sp-btn-head, .sp-btn-accent | Buttons. The head variant sits in the header, the accent variant uses the accent colour. | all; head variant: Essential, Overview |
.sp-state | The answer to "is everything up?": headline, mark and meta line. | all |
.sp-counts | Counts per state in the answer strip. | Overview |
.sp-msg | An open incident or a running maintenance message. | all |
.sp-note | The announcement. | all |
.sp-maint | One planned maintenance entry. | all |
.sp-card | The panel around the planned maintenance entries. | Brand, Overview |
.sp-group, .sp-group-head, .sp-group-sum | A group of services, its title and its sum. | all; sum: Overview |
.sp-svc | One service row. | all |
.sp-svc-name | The service name. | all |
.sp-svc-word | The state in words. | all (Overview hides it for services that are up) |
.sp-svc-uptime | The uptime figure, or the latest response time in the response-time view. | all |
.sp-svc-bar | The uptime bar. | all |
.sp-svc-note | Explanation, source and freshness of a row. | all |
.sp-svc-ext | The "External" chip. | all |
.sp-switch, .sp-range | The uptime and response-time switch, and the 30, 60 and 90 day switch. | all; Overview has no range switch |
.sp-past, .sp-cal | The history block, collapsed until opened, and its incident calendar. | all |
.sp-sub | The subscribe panel. | all |
.sp-foot | The footer. | all |
Variables you may override
All are custom properties on .sp. Defaults are given as light, then dark. Variables marked as set by the editor are replaced by the editor's choices. When you change a background, change the text on it too: nothing re-checks contrast for CSS.
| Variable | Meaning | Default | Set by the editor |
|---|---|---|---|
--sp-bg | Page ground. | Paper #FAF9F5 · #17181A; white #FFFFFF · #0F1011; cool #F3F4F6 · #14161A | No |
--sp-surface | Cards and panels. | #FFFFFF · #1F2023 | No |
--sp-ink | Text. | #141415 · #EEEBE3 | No |
--sp-ink-2, --sp-rule, --sp-rule-2, --sp-sunk | Secondary text, hairlines, strong hairlines and sunk areas. Each is a mix of the text colour into the ground and follows it automatically. | derived | No |
--sp-accent | Accent fill, used for buttons. | #28479E · #7A9BFF | Yes |
--sp-on-accent | Text on the accent. | #FFFFFF · #101112 | Yes |
--sp-accent-ink | Accent as link and focus text. | #28479E · #7A9BFF | Yes |
--sp-head | Header surface. | the page ground | Yes |
--sp-on-head | Text on the header. | the text colour | Yes |
--sp-on-head-2 | Secondary text on the header. | derived | Yes |
--sp-head-rule | Hairlines in the header. | derived | No |
You can read but not change --sp-ok, --sp-warn, --sp-warn-fill, --sp-down, --sp-idle. Status colours are fixed on purpose: green, amber and red mean the same on every page, and the layouts' contrast was checked only with the defaults.
When your variable seems to be ignored
- The editor sets some variables as an inline style on
.sp: the accent ones when an accent colour is set, the header ones when a header colour is set. A plain.sprule loses to an inline style. Either leave that colour unset in the editor, declare the variable on an inner element as in the first example, or add!important, which beats an inline value. - Dark mode redefines the colour variables with
.dark .sp, which is more specific than.sp. For a dark value write.dark .spor use!important. - Derived variables follow your change only when you declare the base variable on the same element where they are computed, which is
.sp. A variable you redeclare on an inner element does not re-derive the others: set them too. - The logo file follows the editor's header colour and the theme, not your CSS. If your CSS makes the header dark, upload a logo that works on it, or set the header colour in the editor, which also picks the right logo file.
.sp { --sp-accent: #B3261E !important; --sp-on-accent: #FFFFFF !important; --sp-accent-ink: #B3261E !important; }Examples
All three ran against the current stylesheet at 1440 and 375 px, light and dark, in all three layouts: header colours, no horizontal overflow.
A navy header in both themes
Declare the variables on the header itself: that beats both the inline style and the stylesheet. Text, secondary text and hairline colours are set with it, because they are not re-derived there.
.sp .sp-head { --sp-head: #14304F; --sp-on-head: #FFFFFF; --sp-on-head-2: #C5D0DE; --sp-head-rule: #3B5576; }
.dark .sp .sp-head { --sp-head: #0E2238; }Hide the uptime figure
The bars and words stay. In the response-time view the same element carries the latest response time, so that is hidden too.
.sp .sp-svc-uptime { display: none; }Tighter corners on the cards
Brand and Overview draw their radii as plain lengths, so override the card blocks.
.sp[data-surface="cards"] :is(.sp-group, .sp-msg, .sp-note, .sp-card, .sp-past, .sp-sub, .sp-state) { border-radius: 4px; }What is not a contract
- Element nesting and tag names inside the blocks above. A span may become a div.
- Any
sp-*class or--sp-*variable not listed, for example the layout width, the radius and shadow values, and every part of a service row, message, history, calendar or subscribe block not named above. - Pixel measures, spacing, radii and type sizes. There is no radius variable.
- The order and presence of blocks, and which layout shows which part.
- The thumbnails and sample data in the editor.
What up4 does not do here
- No script. Custom JavaScript is rejected, and the page's content security policy allows scripts from the page's own address only.
- up4 checks only the size (at most 64 KiB), valid UTF-8, no NUL byte and no closing style tag. It does not rewrite, strip or parse your CSS.
- The browser limits the rest. An
@importor@font-facefrom another host is blocked, so no web-font services: embed the font as a data address or skip it. Images load from secure addresses and data addresses. - The CSS applies to one status page only. It cannot reach the app, other pages or the banner on your own website.
- The password and e-mail-code gate, the subscription confirmed view and the unsubscribe view show the page's brand but never load your CSS: they are shown to people who may not be allowed to see the page.
- CSS cannot add, remove or reorder blocks, and cannot turn one layout into another. Hiding a block with
display: nonehides it for everyone, screen-reader users included.
/v1/status-pages/{pageID} | In the app | API field |
|---|---|
| Custom CSS | custom_css |
Was this page helpful?