Active theme set to Nord LightNord Dark and saved in preferences.
Copied to clipboard.
Error submitting your feedback! Please try again.

Themes 6.0.0

Nord Design System’s parts are themable using CSS Custom Properties. We ship pre-made themes for dark and light mode in addition to providing a flexible theming system.

Nord Themes

Integrating Nord’s themes into your project is straightforward. To get started, add one of the following link tags to the <head> of your application:


<!-- Nordhealth light theme -->
<link rel="stylesheet" href="https://nordcdn.net/ds/themes/6.0.0/nord.css" integrity="sha384-cKcHNo8Tucp1ugLtwBoQQTi+s75YqjbYvQdRam6aDTZPUASykEbfd1NIazmV2LK3" crossorigin="anonymous" />
<!-- Nordhealth dark theme -->
<link rel="stylesheet" href="https://nordcdn.net/ds/themes/6.0.0/nord-dark.css" integrity="sha384-w/DlTgKpMRdSi47wP2OOHTntpFzP8UaDpFFNvsorIvHOv4WfidwcHkyfr17b2T1m" crossorigin="anonymous" />

When using Nord’s themes, it’s required to include our CSS Framework before the theme link tag to get access to properties such as margin, padding, font sizes, and similar which are not bundled into each theme:

<link rel="stylesheet" href="https://nordcdn.net/ds/css/1.2.1/nord.min.css" integrity="sha384-p92xkSmw+NPs+cABRe9ixFUkPNZiw3zDpQJ1kH+LyDaUEuejeNKbpF/d0QzFKu4J" crossorigin="anonymous" />

Please note that Nord Light theme is bundled into our CSS framework, meaning there is no need to add this theme if you already have the CSS Framework installed and it’s the only theme you wish to use.


Installation #

While usage through Nord CDN is the fastest way to get started, we also support installing any of the themes locally using npm. Before you move further with this approach, please make sure you have Node.js installed on your machine. You can install the latest version through their website.

If you’re planning on using Nord Themes in a project that doesn’t yet use npm, you’ll first need to create a package.json file. To do this, run npm init and follow the steps provided. Once finished, you can continue the Nord Themes installation by following the instructions below.

Install using npm #

Run in your project or website root directory (where package.json lives):

npm install @nordhealth/themes @nordhealth/css --save

Importing a theme locally #

Once you’ve installed our npm packages, you can then import any of Nord’s themes into your project as CSS, SCSS, Sass or Less:


/* Import Nord light theme (bundled into CSS Framework) */
@import "~@nordhealth/css/lib/nord.min.css";
/* Import Nord dark theme */
@import "~@nordhealth/css/lib/nord.min.css";
@import "~@nordhealth/themes/lib/nord-dark.css";

If you’re not using Webpack or a similar tool for your build process, you may have to provide the full paths to Node Modules:

@import "/node_modules/@nordhealth/css/lib/nord.min.css";
@import "/node_modules/@nordhealth/themes/lib/nord-dark.css";

Available themes #

Below you can find a list of available themes and paths to them inside our Node.js package:

Themes on Nord CDN #

<!-- Nordhealth light theme -->
<link rel="stylesheet" href="https://nordcdn.net/ds/themes/6.0.0/nord.css" integrity="sha384-cKcHNo8Tucp1ugLtwBoQQTi+s75YqjbYvQdRam6aDTZPUASykEbfd1NIazmV2LK3" crossorigin="anonymous" />

<!-- Nordhealth dark theme -->
<link rel="stylesheet" href="https://nordcdn.net/ds/themes/6.0.0/nord-dark.css" integrity="sha384-w/DlTgKpMRdSi47wP2OOHTntpFzP8UaDpFFNvsorIvHOv4WfidwcHkyfr17b2T1m" crossorigin="anonymous" />

Examples #

Nord Themes

Dark mode #

Dark mode is a user interface mode that displays light text on a dark background. Dark mode is helpful for those viewing device screens at night, in dark environments or find darker UI more accessible. The reduced brightness can reduce eye strain in low light conditions.

A typical scenario is that we already have a light theme in an application, and want to build support for a darker counterpart. When building this support, one of the themes has to be defined as the default that users get on their first visit. This should always be the light theme, although we can let the user’s browser make that choice for us.

When building dark mode support in an application, we should also always provide a manual way for the user to switch to the other theme in the platform’s settings. This setting should include at least the following options:

Changing mode based on user preference #

Since Nord offers its themes as separate stylesheets, we can toggle between these stylesheets for each mode. By default, we should have the light stylesheet in the <head> section of the application:

<!DOCTYPE html>
<html lang="en">
<head>
<!-- Nord dark theme -->
<link rel="stylesheet" href="https://nordcdn.net/ds/css/1.2.1/nord.min.css" integrity="sha384-p92xkSmw+NPs+cABRe9ixFUkPNZiw3zDpQJ1kH+LyDaUEuejeNKbpF/d0QzFKu4J" crossorigin="anonymous" />
<link rel="stylesheet" href="https://nordcdn.net/ds/themes/6.0.0/nord-dark.css" integrity="sha384-w/DlTgKpMRdSi47wP2OOHTntpFzP8UaDpFFNvsorIvHOv4WfidwcHkyfr17b2T1m" crossorigin="anonymous" />
</head>
<body>
<nord-select label="Interface theme">
<option value="light">Light theme</option>
<option value="dark">Dark theme</option>
<option value="auto">Auto (system preference)</option>
</nord-select>
</body>
</html>

When the user switches the mode, we can toggle between these stylesheets:

// Select the menu
const menu = document.querySelector("nord-select")

// Listen for a change event on the menu
menu.addEventListener("change", (event) => {

// If the selected mode is dark, change to dark theme
if (event.target.value === "dark") {
alert("Change theme to dark")

// Otherwise, change to light theme
} else {
alert("Change theme to light")
}
})

Building support for OS dark mode #

Many operating systems let users choose between light and dark mode directly in the system settings. The goal of 'Auto (system preference)' is to allow this type of usage. To support this, we can use a little bit of JavaScript to detect the user’s preference:

// Detect operating system dark mode
const darkMode = window.matchMedia("(prefers-color-scheme: dark)")

// If the OS uses dark mode currently, change to dark theme
if (darkMode.matches) {
alert("Change theme to dark")

// Otherwise, change to light theme
} else {
alert("Change theme to light")
}

Storing user’s preference #

Ultimately, we also need to carry over this functionality when the user either visits another view in your application or reloads the current view.

To achieve this, we need to save the user’s preference so that it will be applied consistently throughout the application and on subsequent visits. To do that, we can save the preference to localStorage:

// Get current mode from localStorage
const currentMode = localStorage.getItem("mode")

// If current mode is "dark", change to dark theme
if (currentMode === "dark") {
alert("Change theme to dark")
}

// Listen for a change event on the mode menu
menu.addEventListener("change", (event) => {
let mode = "light"

// If the selected mode is dark, change to dark theme
if (event.target.value === "dark") {
alert("Change theme to dark")
mode = "dark"

// Otherwise, change to light theme
} else {
alert("Change theme to light")
}

// Finally, save the choice into localStorage
localStorage.setItem("mode", mode)
})

Creating themes #

Nord uses CSS Custom Properties (sometimes referred to as CSS variables) to make its parts themable. CSS Custom Properties allow us to have our values stored in one place, then referenced in multiple other places.

While we could argue that you shouldn’t create new themes yourself as you lose the built-in accessibility, break the connection with the underlying brand architecture, and lose backwards compatibility, you could still technically do so. Hence our thinking is that it’s better to document this than leave it up for our users to guess.

To create a complete theme, you need a new CSS file with a :root CSS pseudo-class which declares global colors, gradients, box-shadows, and color aliases for the theme. This file needs to be referenced after our CSS Framework in the <head> of your app:

:root {
/* ACCENT COLOR */
--n-color-accent: {color};

/* TEXT COLORS */
--n-color-text: {color};
--n-color-text-link: {color};
--n-color-text-weak: {color};
--n-color-text-weaker: {color};
--n-color-text-weakest: {color};
--n-color-text-on-accent: {color};
--n-color-text-error: {color};
--n-color-text-success: {color};

/* NAVIGATION COLORS */
--n-color-nav-surface: {color};
--n-color-nav-heading: {color};
--n-color-nav-hover: {color};

/* BORDER COLORS */
--n-color-border: {color};
--n-color-border-strong: {color};

/* SKIN COLORS */
--n-color-surface: {color};
--n-color-background: {color};
--n-color-surface-raised: {color};

/* STATUS COLORS */
--n-color-status-warning: {color};
--n-color-status-highlight: {color};
--n-color-status-danger: {color};
--n-color-status-success: {color};
--n-color-status-info: {color};

/* STATUS WEAK COLORS */
--n-color-status-warning-weak: {color};
--n-color-status-danger-weak: {color};
--n-color-status-success-weak: {color};
--n-color-status-info-weak: {color};

/* SKELETON COLORS */
--n-color-skeleton: {gradient};

/* BOX SHADOW COLORS */
--n-box-shadow: {box-shadow};
--n-box-shadow-card: {box-shadow};
--n-box-shadow-header: {box-shadow};
--n-box-shadow-modal: {box-shadow};
--n-box-shadow-popout: {box-shadow};
--n-box-shadow-nav: {box-shadow};

/* ALIASES (DO NOT EDIT BELOW) */
--n-color-button: var(--n-color-surface);
--n-color-button-hover: var(--n-color-nav-surface);
--n-color-border-hover: var(--n-color-text-weaker);
--n-color-icon: var(--n-color-text-weaker);
--n-color-icon-hover: var(--n-color-text);
--n-color-active: var(--n-color-nav-surface);
}

The above example assumes that you will replace any instance of {color}, {gradient} and {box-shadow} with your own values.

Please reach out to Nord team before creating a custom theme to discuss about the use case and better understand the limitations. We recommend the usage of “accent color” instead. For more details, continue reading.

Example theme #

Below is an example theme that is based on our old Healthcare green theme that you can use as the foundation for building your own custom themes:

:root {
/* ACCENT COLOR */
--n-color-accent: #078856;

/* TEXT COLORS */
--n-color-text: #23211d;
--n-color-text-link: #078856;
--n-color-text-weak: #41413e;
--n-color-text-weaker: #75746f;
--n-color-text-weakest: #bab9b7;
--n-color-text-on-accent: white;
--n-color-text-error: #ce3b47;
--n-color-text-success: #108457;

/* NAVIGATION COLORS */
--n-color-nav-surface: #f7f6f3;
--n-color-nav-heading: #9e9d98;
--n-color-nav-hover: #edeae3;

/* BORDER COLORS */
--n-color-border: #dfdedd;
--n-color-border-strong: #c7c6c2;

/* SKIN COLORS */
--n-color-surface: white;
--n-color-background: white;
--n-color-surface-raised: #fafaf8;

/* STATUS COLORS */
--n-color-status-warning: #e68947;
--n-color-status-highlight: #f2c642;
--n-color-status-danger: #ce3b47;
--n-color-status-success: #108457;
--n-color-status-info: #8130b0;

/* STATUS WEAK COLORS */
--n-color-status-warning-weak: #fdf6f0;
--n-color-status-danger-weak: #fbeff0;
--n-color-status-success-weak: #ecf5f2;
--n-color-status-info-weak: #eef3f9;

/* SKELETON COLORS */
--n-color-skeleton: linear-gradient(90deg, rgba(255, 255, 255, 0) 0, rgba(255, 255, 255, 0.2) 20%, rgba(255, 255, 255, 0.5) 60%, rgba(255, 255, 255, 0));

/* BOX SHADOW COLORS */
--n-box-shadow: 0 1px 3px rgba(12, 12, 12, 0.09);
--n-box-shadow-card: 0 0 0 1px var(--n-color-border), 0 1px 5px rgba(12, 12, 12, 0.05), 0 0 40px rgba(12, 12, 12, 0.015);
--n-box-shadow-header: 0 1px 5px rgba(12, 12, 12, 0.05);
--n-box-shadow-modal: 0 24px 38px 3px rgba(12, 12, 12, 0.16), 0 9px 86px 8px rgba(12, 12, 12, 0.1), 0 11px 15px -7px rgba(12, 12, 12, 0.1), 0 0 0 1px rgba(0, 0, 0, 0.05);
--n-box-shadow-popout: 0 4px 12px rgba(12, 12, 12, 0.15), 0 0 0 1px rgba(0, 0, 0, 0.05);
--n-box-shadow-nav: 0 0 0 1px var(--n-color-border), 0 5px 17px rgba(12, 12, 12, 0.14);

/* ALIASES (DO NOT EDIT BELOW) */
--n-color-button: var(--n-color-surface);
--n-color-button-hover: var(--n-color-nav-surface);
--n-color-border-hover: var(--n-color-text-weaker);
--n-color-icon: var(--n-color-text-weaker);
--n-color-icon-hover: var(--n-color-text);
--n-color-active: var(--n-color-nav-surface);
}

Accent color #

Most of the time you shouldn’t create a complete theme, but instead provide a slightly branded experience for your users. This can be helpful when offering for example customer portals that our client’s client would have access to.

For this, Nord provides a concept called accent color that supports both Nord light and Nord dark themes. We’ve created a tool called Theme Builder that shows how this works.

To get started with using accent color, first remove all themes from the <head> section of the application and only leave CSS Framework which includes the base Nord light theme that we’ll use as a basis:

<!-- CSS Framework that comes with Nord light theme -->
<link rel="stylesheet" href="https://nordcdn.net/ds/css/1.2.1/nord.min.css" integrity="sha384-p92xkSmw+NPs+cABRe9ixFUkPNZiw3zDpQJ1kH+LyDaUEuejeNKbpF/d0QzFKu4J" crossorigin="anonymous" />

Next, after the CSS Framework, add the following styles and replace {accent-color} with a custom hex value and {text-on-accent-color} with a hex value that offers the necessary 4.5:1 contrast ratio for text that sits on top of the accent color:

<style>
:root {
/* CUSTOM ACCENT COLORS */
--n-color-accent: {accent-color};
--n-color-text-on-accent:
{text-on-accent-color};
}
</style>

We recommend you to set the text as #0c1a3d for light accent colors and #fff for dark accent colors so that they match the default Nord light and dark themes.

If you’re working on an interface that allows the user to pick the accent color themselves, we recommend programmatically picking the right text color, instead of leaving this to the user. You can use the following function to get the correct text color:

/*!
* Get Nord text color for chosen accent color.
* Derived from work by Brian Suda and Chris Ferdinandi.
* MIT License.
*
* @param {String} A hex color value
* @return {String} The contrasting color (#0c1a3d or #fff)
*/

function getTextColor(color) {
// If a leading # is provided, remove it
if (color.slice(0, 1) === "#") {
color = color.slice(1)
}

// If 3 character hex, convert to 6 character
if (color.length === 3) {
color = color.split("").map((hex) => {
return hex + hex
}).join("")
}

// Convert to RGB value
const r = parseInt(color.substr(0, 2), 16)
const g = parseInt(color.substr(2, 2), 16)
const b = parseInt(color.substr(4, 2), 16)

// Get YIQ color space ratio
const yiq = (r * 299 + g * 587 + b * 114) / 1000

// Finally return contrasting text color
return yiq >= 160 ? "#0c1a3d" : "#fff"
}

The above function can be utilized with a color input. When input value changes, we can set the new theme colors into :root CSS pseudo-class:

<label for="color">Accent color</label>
<input id="color" type="color" value="#3559c7" />

<script>
const input = document.querySelector("#color")
const root = document.documentElement

input.addEventListener("input", () => {
const color = input.value
const textColor = getTextColor(color)

root.style.setProperty("--n-color-accent", color)
root.style.setProperty("--n-color-text-on-accent", textColor)
})
</script>

You can try the above example in our theme builder.

Try in theme builder


Logo usage #

Showing a custom logo can be helpful when you want to provide more ways for your users to customize their experience in addition to accent color. We support two different styles for displaying a logo in the header of an application.

The primary style is to display a logo in a square format inside the clinic switcher in the top left corner of the app. The required minimum size for the image is 64×64px. We call this style unambiguously the square logo:

Square logo

The secondary style replaces the clinic switcher completely and shows only the logo. We call this style the standalone logo:

Standalone logo

This style can be helpful when offering customer portals that our client’s client would have access to. We don’t recommend this style for any other use case. The required minimum width for an image in this case is 360px and you should aim to use a horizontal logo given the limited space.

You can try both of these styles by uploading a logo in a correct format using our theme builder which provides a setting for changing between these two logo styles.

Try in theme builder


Theming in Figma #

Nord Figma Toolkit supports theming natively in Figma using Figma Libraries. To get started with theming, follow the below instructions.

  1. Open the Libraries Window.
  2. Select the current color Library in use.
  3. Select the new library you would like to swap to.
  4. Check the box next to "Swap default styles in instances". This will allow you to accept Nord Figma updates and preserve your theming.
  5. Click swap library.
Please note that theming will only work with Nord Figma Toolkit if you have enabled the Nord Light Theme and Nord Dark Theme libraries earlier.

Can I use themes in my own project? #

Nord Design System is solely meant for building digital products and experiences for Nordhealth. Please see the terms of use for full license details.


Getting support #

Need help with our themes? Please head over to the Support page for more guidelines and ways to contact us.


Was this page helpful?

YesNo
Send feedback

We use this feedback to improve our documentation.

 
Edit page