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.

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 }
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: {
2 background-color: var(--color-primary);
5.text-tertiary {
6 color: var(--color-tertiary);
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 ]
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. It's currently not supported.

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

Creating a clipping mask hover effect with Tailwind CSS

  • Tailwind CSS