Doorgaan naar content

Using P3 colors in Tailwind CSS

P3 is an RGB color space that has a broader range of colors than regular RGB does. To display those colors users need a wide-gamut monitor. Most screens on modern Apple devices support this color space so it could be interesting to tap into this for your websites and make your colors pop. In this article you will learn how and where you can use P3 and how to setup a fallback.

Update November 3rd 2022
I found a way in TailwindCSS 3.2 to use P3 colors with the opacity shorthand. I added this at the bottom of the article.

CSS supports p3 colors using the color() function. This function is currently only supported in Safari and will come to other browsers this year. If you visit this very site in Safari on P3 supported monitor you'll see big color differences compared to other browsers. The green in light mode and pink in dark mode are way more vibrant than what used to be possible in the RGB color space.

Tailwind CSS configuration

To work with P3 colors in Tailwind CSS we need to define our colors as CSS custom properties.

1module.exports = {
2 theme: {
3 colors: {
4 primary: 'var(--color-primary)',
5 secondary: 'var(--color-secondary)',
6 tertiary: 'var(--color-tertiary)',
7 },
8 }
9}
Three colors defined as custom properties in tailwind.config.js.

This way Tailwind CSS will compile all color utilities like bg-primary or text-tertiary using the following CSS:

1.bg-primary {
2 background-color: var(--color-primary);
3}
4 
5.text-tertiary {
6 color: var(--color-tertiary);
7}
The generated utilities.

Makes sense right? However we still need to define the actual values of those custom properties. The values should either be a good ol' rgb value (or whatever you prefer), or the css color() function for browsers that actually support this.

The way you write P3 color values is as follows.

1color(display-p3 1 1 1);
The color function syntax.

The color function takes three arguments:

  1. The color space

  2. The red value on a scale of 0 to 1

  3. The green value on a scale of 0 to 1

  4. The blue value on a scale of 0 to 1

The P3 channel values lie between 0 and 1 and the RGB color values lie between 1 and 255. So in order to translate an RGB color to P3 you have to divide each color channel value by 255. For our primary color (rgb(18, 181, 74)) this would get the following P3 notation.

1--color-primary: color(display-p3 0.07058823529 0.7098039216 0.2901960784);
The primary color in P3. Each color channel is divided by 255.

Now let's combine all this and use the @supports query in CSS to provide a fallback. Within this query we can define the custom property value using the color() function.

1module.exports = {
2 plugins: [
3 plugin(function({ addBase }) {
4 addBase({
5 ':root': {
6 '--color-primary': 'rgb(18, 181, 74)',
7 '--color-secondary': 'rgb(255, 2, 116)',
8 '--color-tertiary': 'rgb(0, 152, 241)',
9 },
10 '@supports (color: color(display-p3 1 1 1))': {
11 ':root': {
12 '--color-primary': 'color(display-p3 0.07058823529 0.7098039216 0.2901960784)',
13 '--color-secondary': 'color(display-p3 1 0.007843137255 0.4549019608)',
14 '--color-tertiary': 'color(display-p3 0 0.5960784314 0.9450980392)'
15 }
16 },
17 })
18 ]
19}
Defining the custom property values in tailwind.config.js.

And that's it. This snippet will generate the base CSS that all of our color utilities will take their values from. It's important to know however that using this technique you won't be able to use the Tailwind CSS opacity shorthand notation; bg-primary/50 for example. With TailwindCSS 3.2 however there is a way.

Using P3, RGB fallback and opacity shorthand

TailwindCSS 3.2 shipped with a `@supports` variant. Until TailwindCSS adds full p3 color support you can use full P3 support with opacity modifiers using a little trick. Configure your colors like this:

1module.exports = {
2 presets: [],
3 theme: {
4 colors: {
5 primary: {
6 DEFAULT: 'rgb(79 124 74 / <alpha-value>)',
7 'p3': 'color(display-p3 0.31 0.49 0.29 / <alpha-value>)'
8 },
9 },
10 },
11}
Add a P3 shade for the primary color.

Now you can give any element a bg-primary class to give it the normal RGB background color. Whenever you want to reach for a P3 color add the class supports-[background-color:color(display-p3)]:bg-primary-p3. In your compiled CSS this class will be wrapped in a @supports (background-color:color(display-p3)) media query so it'll only work on supported browsers.

Using this technique you can also use the opacity shorthand: bg-primary/80 supports-[background-color:color(display-p3)]:bg-primary-p3/80.

Did you like this article or do you have any questions? Please reach out on Twitter.

A rendered code example with Statamic, Tailwind and Alpine

  • Statamic
  • Peak
  • Tailwind CSS
  • Alpine JS