Tailwind is rendering both custom properties and corresponding values

Tailwind is rendering both, the css custom properties and hard coded values. I expected only the css variables to be included in production. Does anyone know why?

I have a very similar setup with my Astro project, and it wasn’t an issue.

Rendered:

body {
  background: #f3f3f3;
  background: var(--color-light);
  color: #404040;
  color: var(--color-dark);
  font-family: Inter, Segoe UI, Roboto, Helvetica Neue, Arial, sans-serif;
  font-family: var(--font-base);
  font-size: clamp(1.1875rem, 1.01rem + 0.87vw, 1.75rem);
  font-size: var(--size-step-1);
  letter-spacing: -0.05ch;
  letter-spacing: var(--tracking);
  line-height: 1.4;
}

Expected:

body {
  background: var(--color-light);
  color: var(--color-dark);
  font-family: var(--font-base);
  font-size: var(--size-step-1);
  letter-spacing: var(--tracking);
  line-height: 1.4;
}

Tailwind config:

const plugin = require('tailwindcss/plugin')
const postcss = require('postcss')
const postcssJs = require('postcss-js')

const clampGenerator = require('./resources/css-utils/clamp-generator.cjs')
const tokensToTailwind = require('./resources/css-utils/tokens-to-tailwind.cjs')

// Raw design tokens
const colorTokens = require('./resources/design-tokens/colors.json')
const fontTokens = require('./resources/design-tokens/fonts.json')
const spacingTokens = require('./resources/design-tokens/spacing.json')
const textSizeTokens = require('./resources/design-tokens/text-sizes.json')

// Process design tokens
const colors = tokensToTailwind(colorTokens.items)
const fontFamily = tokensToTailwind(fontTokens.items)
const fontSize = tokensToTailwind(clampGenerator(textSizeTokens.items))
const spacing = tokensToTailwind(clampGenerator(spacingTokens.items))

module.exports = {
  content: ['./index.php', './app/**/*.php', './resources/**/*.{php,vue,js}'],
  experimental: {
    optimizeUniversalDefaults: true,
  },
  presets: [],
  theme: {
    screens: {
      md: '50em',
      lg: '80em',
    },
    colors,
    spacing,
    fontSize,
    fontFamily,
    fontWeight: {
      normal: 400,
      bold: 700,
      black: 800,
    },
    backgroundColor: ({ theme }) => theme('colors'),
    textColor: ({ theme }) => theme('colors'),
    margin: ({ theme }) => ({
      auto: 'auto',
      ...theme('spacing'),
    }),
    padding: ({ theme }) => theme('spacing'),
  },
  variantOrder: [
    'first',
    'last',
    'odd',
    'even',
    'visited',
    'checked',
    'empty',
    'read-only',
    'group-hover',
    'group-focus',
    'focus-within',
    'hover',
    'focus',
    'focus-visible',
    'active',
    'disabled',
  ],

  // Disables Tailwind's reset etc
  corePlugins: {
    preflight: false,
  },
  plugins: [
    // Generates custom property values from tailwind config
    plugin(function ({ addComponents, config }) {
      let result = ''

      const currentConfig = config()

      const groups = [
        { key: 'colors', prefix: 'color' },
        { key: 'spacing', prefix: 'space' },
        { key: 'fontSize', prefix: 'size' },
        { key: 'fontFamily', prefix: 'font' },
      ]

      groups.forEach(({ key, prefix }) => {
        const group = currentConfig.theme[key]

        if (!group) {
          return
        }

        Object.keys(group).forEach(key => {
          result += `--${prefix}-${key}: ${group[key]};`
        })
      })

      addComponents({
        ':root': postcssJs.objectify(postcss.parse(result)),
      })
    }),

    // Generates custom utility classes
    plugin(function ({ addUtilities, config }) {
      const currentConfig = config()
      const customUtilities = [
        { key: 'spacing', prefix: 'flow-space', property: '--flow-space' },
        { key: 'colors', prefix: 'surface-color', property: '--surface-color' },
        { key: 'colors', prefix: 'text-color', property: '--text-color' },
        { key: 'fontSize', prefix: 'size', property: '--size' },
      ]

      customUtilities.forEach(({ key, prefix, property }) => {
        const group = currentConfig.theme[key]

        if (!group) {
          return
        }

        Object.keys(group).forEach(key => {
          addUtilities({
            [`.${prefix}-${key}`]: postcssJs.objectify(postcss.parse(`${property}: ${group[key]}`)),
          })
        })
      })
    }),
  ],
}

In the package.json, changing the browser support settings to something else like…

  "browserslist": [
    "extends @roots/browserslist-config/current"
  ],

Other @roots browser configurations: @roots/browserslist-config - npm

Unfortunately, I still needed to provide my own browserlist config because @roots current profile was still providing fallbacks for every css variable.

Is mine is too aggressive even for 2023?

  "browserslist": [
    "> 2%",
    "last 2 Chrome versions",
    "last 2 ChromeAndroid versions",
    "last 2 Safari versions",
    "last 2 Edge versions",
    "last 2 Opera versions",
    "last 2 Firefox versions"
  ]
1 Like

Check out your analytics and make your decision based on the devices/browsers you see on there?