Theming
The default theme provides simple, elegant styles with support for light and dark modes and 21 built-in color presets. A number of design tokens are exposed, giving you an easy way to make high-level changes to the library.
Using the default theme Jump to heading
To import the default theme from the CDN, add the following code to the <head>
section of
each page.
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@quietui/quiet-browser@1.0.0/dist/themes/quiet.css">
Activating dark mode Jump to heading
Light mode "just works" once you import the default theme. To switch to dark mode, add the
quiet-dark
class to the <html>
element as shown below. Removing the class
will switch back to light mode.
<html class="quiet-dark"> ... </html>
If you're using Quiet Restyle, the entire page will enter dark mode. If you're not using Restyle, only the components will change and it's up to you to style the rest of your app accordingly.
Using light and dark on the same page Jump to heading
Sometimes, it's desirable to have a contrasting theme for certain sections of the page. For example, a
light-themed page might have a dark-themed sidebar or footer. You can achieve this by applying the
quiet-light
or quiet-dark
class to any element on the page.
<quiet-card class="quiet-light" style="text-align: center;"> <p>This is a light card.</p> <quiet-button> Light button </quiet-button> </quiet-card> <quiet-card class="quiet-dark" style="text-align: center;"> <p>This is a dark card.</p> <quiet-button> Dark button </quiet-button> </quiet-card>
When using quiet-light
and quiet-dark
, you may want to set the background color
to an appropriate value. You can use --quiet-background-color
for an adaptive background.
Learn more about design tokens
Theme concepts Jump to heading
Quiet's default theme is designed to be highly customizable with minimal effort. The following seed colors are used to generate color palettes with pure CSS — one for each variant.
:root { --quiet-primary-seed: #989cff; --quiet-neutral-seed: #a4a6b0; --quiet-constructive-seed: #7db664; --quiet-destructive-seed: #f86565; }
This means you can customize an entire palette by setting a single custom property in your stylesheet. For example, this will change the primary color palette to orange.
:root { --quiet-primary-seed: #e98d61; }
For best results, use midtone colors to seed palettes. Any of the 500-level colors from color.surf or similar palettes will work well.
Built-in presets Jump to heading
For convenience, Quiet's default theme ships with 21 color presets to alter the library's primary color. The theme picker at the top of the page allows you to preview them.
To use a preset in your app, add the quiet-{preset}
class to the
<html>
element, where {preset}
is one of the following values: default, red,
orange, amber, yellow, lime, green, emerald, teal, cyan, sky, blue, indigo, violet, purple, fuchsia, pink,
rose, slate, zinc, or stone.
<html class="quiet-blue"> ... </html>
Adapting to existing brands Jump to heading
Using a preset is an easy way to change the library's overall appearance, but it probably won't be a perfect
match if you already have brand guidelines to follow. In that case, it might be tempting to set
--quiet-primary-seed
to whatever your brand color is.
However, that will only work well if your brand color happens to be a midtone, otherwise the generated color tokens may not have enough contrast. A better approach is to use the nearest midtone color that fits with your brand.
"But my buttons don't match my brand color exactly…"
Components should absolutely be on brand, but that doesn't mean buttons have to be the exact hex color as your logo! However, if you insist on such a style, the correct way to achieve it is by overriding the generated palettes and/or component styles with CSS and ensuring proper contrast manually.
Color primitives Jump to heading
Four primitive color palettes are generated based on the aforementioned seed colors. These palettes correspond with the four variants used throughout the library and remain static in light and dark mode.
You should only use color primitives when you want a color that doesn't change in dark mode. For most styles, you probably want to use adaptive colors instead.
Syntax: --quiet-{variant}-{number}
Primary Jump to heading
This is your brand color. Use it for brand recognition and guiding attention through calls to action.
Neutral Jump to heading
Neutral is usually gray, representing surfaces, borders, and secondary objects.
Constructive Jump to heading
Constructive is often green, indicating creation or success.
Destructive Jump to heading
Destructive is often red, indicating deletion or danger.
You can tap on any swatch on this page to copy the corresponding custom property.
Adaptive colors Jump to heading
Adaptive colors automatically change between light and dark modes. Instead of numeric values, they use a scale that indicates their "volume" relative to the the app's background. Thus, "softer" colors have less contrast than "louder" ones. This approach lets you style things once, but have them look great in light and dark modes.
Fill colors Jump to heading
Fill colors are primarily used for backgrounds and surfaces. For example, certain buttons use midtone fills for their backgrounds.
Syntax: --quiet-{variant}-fill-{volume}
Primary fill colors Jump to heading
Used for calls to action and brand accents.
Neutral fill colors Jump to heading
Used for secondary elements and UI chrome.
Constructive fill colors Jump to heading
Used for successful operations such as creations.
Destructive fill colors Jump to heading
Used for dangerous operations such as deletions.
Text-on colors Jump to heading
Text-on colors provide adequate contrast when used on top of their respective fill colors. Soft works on soft and softer fills whereas loud works on loud and louder fills.
Syntax: --quiet-{variant}-text-on-{volume}
Primary text-on colors Jump to heading
Used for text that sits on top of primary fills.
Neutral text-on colors Jump to heading
Used for text that sits on top of neutral fills.
Constructive text-on colors Jump to heading
Used for text that sits on top of constructive fills.
Destructive text-on colors Jump to heading
Used for text that sits on top of destructive fills.
A note about WCAG 2
You might discover that some elements are reported to have insufficient contrast, according to WCAG 2. This occurs due to the standard not accounting for perceptual contrast and only affects Quiet's text-on midtone colors.
Technically,
Refer to this article to learn more about why WCAG 2 isn't a great standard for measuring perceptual contrast.
Stroke colors Jump to heading
Stroke colors are used to draw borders and outlines around elements and UI chrome.
Syntax: --quiet-{variant}-stroke-{volume}
Primary stroke colors Jump to heading
Used for outlining primary elements.
Neutral stroke colors Jump to heading
Used for outlining secondary elements.
Constructive stroke colors Jump to heading
Used for outlining constructive elements.
Destructive stroke colors Jump to heading
Used for outlining destructive elements.
Tinting & shading Jump to heading
These tokens represent pure black and white, but their values invert in dark mode. They're most commonly
used to tint and shade existing colors with
color-mix()
.
Syntax: --quiet-silent
, --quiet-strident
Design tokens Jump to heading
Quiet uses a relatively small set of design tokens to create a consistent look and feel throughout the library. Design tokens are provided in the form of CSS custom properties. The tokens are used internally by many components, and you can customize them to make the library better match your brand.
To customize design tokens, reassign them in CSS as shown below.
/* Light theme Design token overrides */ :root, .quiet-light { --quiet-background-color: white; --quiet-text-body: black; } /* Dark theme design token overrides */ .quiet-dark { --quiet-background-color: black; --quiet-text-body: white; }
Always scope design token overrides to the root node (i.e. the <html>
element),
otherwise calculated values may not propagate as expected.
Surface tokens Jump to heading
These tokens control various types of backgrounds, or "surfaces."
Custom property | Description |
---|---|
--quiet-background-color |
The application's background color. |
--quiet-paper-color |
An alternative background color for slightly lifted surfaces such as a card. |
Typography tokens Jump to heading
These tokens control text and content.
Custom property | Description |
---|---|
--quiet-text-body |
The default text color of the app. |
--quiet-text-muted |
The color to use for muted text such as form control descriptions. |
--quiet-font-family |
The default font. |
--quiet-font-family-heading |
The font used for headings. |
--quiet-font-family-code |
The font used for code and code blocks. |
--quiet-font-size |
The base font size for the application. (The default theme is optimized for a 16px font size.) |
--quiet-font-weight-normal |
The font weight for normal text. |
--quiet-font-weight-semibold |
The font weight for semibold text. |
--quiet-font-weight-bold |
The font weight for bold text. |
--quiet-line-height |
The default line height for text. |
--quiet-content-spacing |
The spacing between blocks of content. Used primarily in Restyle to space content consistently. |
--quiet-focus-color |
The color of the focus ring. |
--quiet-focus-ring |
The outline-friendly property used to show focus rings. |
--quiet-focus-width |
The width of the focus ring's border. |
--quiet-focus-offset |
The outline offset of the focus ring. |
--quiet-selection-background-color |
The background color of selected text. |
--quiet-selection-color |
The color of selected text. |
Border tokens Jump to heading
These tokens control borders and edges.
Custom property | Description |
---|---|
--quiet-border-style |
The default border style for most elements. |
--quiet-border-width |
The default border width for most elements. |
--quiet-border-radius |
The base border radius for elements. Often used with calc() to scale to smaller and
larger elements.
|
Shadow tokens Jump to heading
These tokens controls shadows and can be used with the box-shadow
property.
Custom property | Description |
---|---|
--quiet-shadow-color |
The base color used in all shadows. |
--quiet-shadow-softer |
The softest shadow, for subtle elevation effects. |
--quiet-shadow-soft |
A gentle shadow, for light elevation effects. |
--quiet-shadow-mid |
A moderate shadow, for clear elevation effects. |
--quiet-shadow-loud |
A strong shadow, for prominent elevation effects. |
--quiet-shadow-louder |
The strongest shadow, for maximum elevation effects. |
--quiet-inset-shadow-softer |
The softest inset shadow, for subtle depression effects. |
--quiet-inset-shadow-soft |
A gentle inset shadow, for light depression effects. |
--quiet-inset-shadow-mid |
A moderate inset shadow, for clear depression effects. |
--quiet-inset-shadow-loud |
A strong inset shadow, for prominent depression effects. |
--quiet-inset-shadow-louder |
The strongest inset shadow, for maximum depression effects. |
Form controls Jump to heading
These tokens control form control styles.
Custom property | Description |
---|---|
--quiet-form-control-height-xs |
The height of extra small form controls. |
--quiet-form-control-height-sm |
The height of small form controls. |
--quiet-form-control-height-md |
The height of medium form controls. |
--quiet-form-control-height-lg |
The height of large form controls. |
--quiet-form-control-height-xl |
The height of extra large form controls. |
--quiet-form-control-font-size-xs |
The font size of extra small form controls. |
--quiet-form-control-font-size-sm |
The font size of small form controls. |
--quiet-form-control-font-size-md |
The font size of medium form controls. |
--quiet-form-control-font-size-lg |
The font size of large form controls. |
--quiet-form-control-font-size-xl |
The font size of extra large form controls. |
--quiet-form-control-required-content |
The content to show next to the label when the form control is required. |
--quiet-form-control-placeholder-color |
The color of placeholder text |
--quiet-button-active-offset |
The amount of vertical shift to apply to buttons when they're pressed. |
Miscellaneous tokens Jump to heading
Here are some additional tokens you can use and customize for various purposes.
Custom property | Description |
---|---|
--quiet-backdrop-color |
The color of backdrops for modal components such as dialog. |
--quiet-backdrop-filter |
The filter to apply to dialog backdrops and similar overlays. |
Creating your own theme Jump to heading
Quiet uses
CSS layers
to manage specificity. This means your custom styles will automatically take precedence over the library's
styles without needing to use !important
or increase selector specificity.
If you just want to change a few things here and there, it's usually better to leave the default theme intact and extend it by adding your own stylesheet with the specific rules you want. Use design tokens, CSS custom properties, CSS parts, and custom states to customize virtually anything on any component.
This is the recommended approach. 👆
If you really want to create an entirely new theme, the most efficient way is to fork ("copy") the default theme's CSS and modify it instead of writing everything from scratch. This is faster, easier, and less prone to mistakes.