Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Expose Tailwind colors as CSS custom properties (variables)

This is a simple Tailwind plugin to expose all of Tailwind's colors, including any custom ones, as custom css properties on the :root element.

There are a couple of main reasons this is helpful:

  • You can reference all of Tailwind's colors—including any custom ones you define—from handwritten CSS code.
  • You can define all of your colors within the Tailwind configuration, and access the final values programmatically, which isn't possible if you did it the other way around: referencing custom CSS variables (defined in CSS code) from your Tailwind config.

See the Tailwind Plugins for more info on plugins.

module.exports = {
  theme: {
    extend: {
      colors: {
        gray: {
          '100': '#f5f5f5',
          '200': '#eeeeee',
          '300': '#e0e0e0',
          '400': '#bdbdbd',
          '500': '#9e9e9e',
          '600': '#757575',
          '700': '#616161',
          '800': '#424242',
          '900': '#212121',
        },
      },
    },
  },
  plugins: [
    function({ addBase, theme }) {
      function extractColorVars(colorObj, colorGroup = '') {
        return Object.keys(colorObj).reduce((vars, colorKey) => {
          const value = colorObj[colorKey];

          const newVars =
            typeof value === 'string'
              ? { [`--color${colorGroup}-${colorKey}`]: value }
              : extractColorVars(value, `-${colorKey}`);

          return { ...vars, ...newVars };
        }, {});
      }

      addBase({
        ':root': extractColorVars(theme('colors')),
      });
    },
  ],
};
@emigdio821
Copy link

Is there a way to expose only the custom colors?
These ones:

extend: {
  colors: {
    customblue: '#0274b6',
    custombluehover: '#015483',
  },
},

Thanks!

@benwinding
Copy link

Thank you for this!
Side note: an AI-driven search engine led me to this solution here! 😅
Phind -> Source link

@jbasoo
Copy link

jbasoo commented May 18, 2023

I further modified @Maybach91's modification and abstracted a bit for any theme config, not just colors (theoretically, havent tested every type 😬).

Also I switched from addBase to addUtilites as my project isn't using the base styles, only utilities.

  plugins: [
    plugin(function({ addUtilities, theme }) {    
      function extractVars (obj, group = '', prefix) {
        return Object.keys(obj).reduce((vars, key) => {
          const value = obj[key];
          const cssVariable = key === "DEFAULT" ? `--${prefix}${group}` : `--${prefix}${group}-${key}`;
          
          const newVars =
          typeof value === 'string'
          ? { [cssVariable]: value }
          : extractVars(value, `-${key}`, prefix);
          
          return { ...vars, ...newVars };
        }, {});
      }
      
      addUtilities({
        ':root': {
          ...extractVars(theme('colors'), '', 'color'),
          ...extractVars(theme('boxShadow'), '', 'box-shadow')
        }
      })
    })
  ],

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment