Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---
id: Theming
section: design-foundations
source: dark-theme-handbook
---

# Dark theme developer handbook

## Enabling dark theme

Dark theme is available with PatternFly by default. To enable dark theme, add the class `pf-[version]-theme-dark` (for example, `pf-v6-theme-dark`) to your application's `<html>` tag. This class can be added dynamically to toggle dark theme on and off in your application.

Dark theme can also be applied based on the browser’s `prefers-color-scheme` media query. When using this method, we recommend using JavaScript to detect the media query and apply the `pf-[version]-theme-dark` class. This allows you to manipulate a single class in order to toggle dark theme based on user preference. [Adam Argyle wrote a great article](https://web.dev/building-a-theme-switch-component/#javascript) on using JavaScript to manage dark theme preference, using the `prefers-color-scheme` media query alongside a manual button that toggles dark theme.

[Our token resources](https://github.com/patternfly/patternfly/tree/v6/src/patternfly/base/tokens) include styles for both light and dark themes. When dark theme is enabled, your product will automatically pull dark theme tokens in order to adapt visual styles appropriately.

The only features which will require additional work in order to support dark theme are charts and images.

### Charts

To use charts with dark themes, refer to our guidance for [developing with charts](/charts/about-charts#develop-with-charts).

### Images

To create images that adapt to light and dark themes, there are a few approaches you can take:

- Use inline SVG's with fill colors set to [PatternFly color tokens](/tokens/all-patternfly-tokens), which inherently adapt to light and dark themes.
- Create images with colors that work well with both light and dark themes. These colors should meet [WCAG AA contrast requirements](https://webaim.org/resources/contrastchecker/).
- Utilize background color, border color, border-radius, and padding/spacing to create a container that can hold dynamic/user-supplied images.
- Write CSS and dynamically swap between 2 image variations:

```
<img src="/light-theme.jpg" class="show-in-light">
<img src="/dark-theme.jpg" class="show-in-dark">

<style>
.show-in-dark,
.pf-v6-theme-dark .show-in-light {
display: none;
}

.pf-v6-theme-dark .show-in-dark {
display: revert;
}
</style>
```

## Best practices

The most important step to ensure your application supports dark theme is to follow our [general theming best practices](/design-foundations/theming#best-practices). Adhering to these guidelines, especially by using design tokens instead of hard-coded values, will resolve most adoption challenges.

Additionally, keep these key points in mind:

- **Plan for static images:** If you can't use SVGs that are compatible with both light and dark backgrounds, you will need to create two versions of you image and swap them based on the active theme.
- **Test custom components in both themes:** When building custom components, always check your work in both light and dark themes. This helps you catch issues early, like hard-coded colors or styles that don't adapt as expected.
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
---
id: Theming
section: design-foundations
source: high-contrast-handbook
---

# High contrast mode developer handbook

## High contrast mode vs. forced colors mode

Our high contrast mode increases the contrast of PatternFly components, often introducing additional borders to distinguish between elements, states, and interactions that otherwise rely on subtle background colors. High contrast mode is enabled by applying styles that are meant to target the [`prefers-contrast: more`](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-contrast) media query, which is the mode triggered on MacOS via **System Settings** > **Accessibility** > **Display** > **Increase contrast**.

This is different from [`forced-colors: active`](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/forced-colors), which is a more aggressive contrast mode where the browser enforces a limited, user-chosen color palette on a webpage, often by replacing author-defined colors with CSS system colors and removing styles like background colors and box shadows. Common triggers for forced colors mode are enabling Windows High Contrast Mode and Firefox High Contrast Mode. As outlined in [“Automatic high contrast”](#automatic-high-contrast), we recommend applying high contrast mode when `forced-colors: active` is `true`.

## Enabling high contrast mode

High contrast mode is designed to work with both our standard light and dark themes, and it's available with PatternFly by default. To enable high contrast mode, add the class `.pf-v6-theme-high-contrast` to your application’s `<html>` tag. This class can be added dynamically to toggle high contrast mode on and off in your application.

[Adam Argyle's "Building a theme switch" article](https://web.dev/articles/building/a-theme-switch-component) outlines principles that should be applied to a high contrast mode theme switcher.

### Automatic high contrast

To apply high contrast mode automatically, based off of a user’s OS and browser contrast preferences, you can use `window.matchMedia()` to detect the browser’s `prefers-contrast` and `forced-colors` media queries. Because our high contrast mode often introduces additional borders, we recommend detecting `forced-colors` and applying high contrast styles when the value is `active`.

Even when high contrast mode is enabled automatically, it’s important to also add a manual toggle that allows users to toggle the theme on and off. A user's manual toggle of high contrast should always override the OS and browser preference.

### Dynamic high contrast

To allow your users to apply high contrast mode dynamically, independent of their OS and browser preferences, you can place an interactive toggle in a prominent location of your application. It is best practice store a user’s most recent toggle selection by storing their preference in `localStorage`, and using it enable or disable high contrast mode automatically when they return.

## High contrast design tokens

The following tokens have been introduced specifically for use in high contrast mode.

| **Token** | **Default theme value** | **High contrast mode value** |
| :---: | :---: | :---: |
| `--pf-t--global--border--color--high-contrast` | `transparent` | `--pf-t--global--border--color--default` <br /><br/>Light mode value: #4D4D4D<br />Dark mode value: #C7C7C7 |
| `--pf-t--global--border--width--high-contrast--regular` | 0px | `--pf-t--global--border--width--regular` <br /><br/>Value: 1px |
| `--pf-t--global--border--width--high-contrast--strong` | 0px | `--pf-t--global--border--width--strong` <br /><br/>Value: 2px |
| `--pf-t--global--border--width--high-contrast--extra-strong`| 0px | `--pf-t--global--border--width--extra-strong` <br /><br/>Value: 3px|

**Note:** The `--pf-t--global--border--color--high-contrast` token can be used strategically to support styles in `forced-colors` mode, as transparent borders will become visible when this mode is active.

### Plain action tokens

We also added the following tokens for plain actions (actions with a transparent background). These are now used in PatternFly anywhere where an action has a transparent background, such as plain buttons or navigation items.

| **Token** | **Default theme value** | **High contrast mode value** |
| :---: | :---: | :---: |
| `--pf-t--global--border--width--action--plain--default` | 0px| 0px|
| `--pf-t--global--border--width--action--plain--hover` | 0px | `--pf-t--global--border--width--100` <br /><br/>Value: 1px |
| `--pf-t--global--border--width--action--plain--clicked` | 0px | `--pf-t--global--border--width--200` <br /><br/>Value: 2px |

## Best practices

In addition to the [general theming best practices](/design-foundations/theming#best-practices), ensure that you adhere to the following guidelines when working in high contrast mode.

### Color and contrast

- **Meet text contrast ratios:** All normal text must meet a minimum contrast ratio of 7:1 against its background. While WCAG allows a 4.5:1 ratio for large text (18px or larger), it is best to aim for a 7:1 ratio for all text sizes to ensure maximum readability.
- **Meet non-text contrast ratios:** All other UI elements, like icons and borders must meet a minimum contrast ratio of 4.5:1 against their background.

### Boundaries

- **Add borders for clarity:** If an element's background color doesn't have a 4.5:1 contrast ratio, add a visible border. For example, add borders to elements with a secondary background color that are placed on top of a primary background.
- **Replace shadows with borders:** To properly separate elements from the background, add a border to any elements that rely on a shadow in default themes.
- **Thicken borders on interaction:** Use border width to provide clear feedback for interactive states. An element's border should become progressively thicker on hover, focus, and click.
- Example: An element with no default border should have a 1px border on hover and a 2px border when clicked.
Loading