Coral UI

@reallygoodwork/style-to-tailwind

Convert CSS style objects to Tailwind CSS classes.

npm

Convert CSS style objects to Tailwind CSS classes. This utility package transforms CSS-in-JS style objects, Coral style objects, or inline styles into Tailwind utility classes, making it easy to migrate from CSS-in-JS to Tailwind or convert style objects programmatically.

Features

  • CSS to Tailwind Conversion - Convert CSS property-value pairs to Tailwind utility classes
  • Color Object Support - Handle color objects with hex, RGB, and HSL values
  • Spacing Scale Conversion - Automatically convert pixel values to Tailwind spacing scale
  • Font Size Mapping - Convert font sizes to Tailwind text size classes
  • Color Matching - Match colors to Tailwind color palette or use arbitrary values
  • Arbitrary Values - Fallback to Tailwind arbitrary value syntax for custom values
  • Reverse Mappings - Uses reverse mappings from @reallygoodwork/coral-tw2css for accurate conversions
  • TypeScript Support - Fully typed for TypeScript projects

Installation

npm install @reallygoodwork/style-to-tailwind
pnpm add @reallygoodwork/style-to-tailwind
yarn add @reallygoodwork/style-to-tailwind

API Reference

styleToTailwind

Converts a CSS style object to an array of Tailwind CSS class names. This is the primary function for converting styles to Tailwind classes.

Prop

Type

Returns: string[] - Array of Tailwind CSS class names

Basic Example

import { styleToTailwind } from '@reallygoodwork/style-to-tailwind';

const classes = styleToTailwind({
  padding: 16,
  margin: 8,
  fontSize: 14,
});
// Returns: ['p-4', 'm-2', 'text-sm']

With Color Objects

import { styleToTailwind } from '@reallygoodwork/style-to-tailwind';

const classes = styleToTailwind({
  backgroundColor: {
    hex: '#3b82f6',
    rgb: { r: 59, g: 130, b: 246, a: 1 },
    hsl: { h: 217, s: 91, l: 60, a: 1 },
  },
  color: {
    hex: '#ffffff',
    rgb: { r: 255, g: 255, b: 255, a: 1 },
    hsl: { h: 0, s: 0, l: 100, a: 1 },
  },
});
// Returns: ['bg-blue-500', 'text-white']

With String Values

const classes = styleToTailwind({
  padding: '16px',      // Converts to p-4
  padding: '1rem',      // Converts to p-4 (1rem = 16px)
  fontSize: '14px',     // Converts to text-sm
  backgroundColor: '#3b82f6', // Converts to bg-blue-500
});

With Hex Colors

const classes = styleToTailwind({
  backgroundColor: '#3b82f6', // Matches Tailwind blue-500
  color: '#ef4444',            // Matches Tailwind red-500
  borderColor: '#22c55e',      // Matches Tailwind green-500
});
// Returns: ['bg-blue-500', 'text-red-500', 'border-green-500']

Complex Styles

const classes = styleToTailwind({
  padding: 16,
  paddingTop: 8,
  paddingBottom: 8,
  backgroundColor: { hex: '#3b82f6' },
  color: { hex: '#ffffff' },
  borderRadius: 8,
  fontSize: 14,
  fontWeight: 600,
  gap: 16,
});
// Returns: ['p-4', 'pt-2', 'pb-2', 'bg-blue-500', 'text-white', 'rounded-lg', 'text-sm', 'font-semibold', 'gap-4']

Sizing Properties

const classes = styleToTailwind({
  width: 64,        // w-16
  height: 32,        // h-8
  minWidth: 16,     // min-w-4
  maxWidth: 96,     // max-w-24
  minHeight: 100,   // min-h-[100px] (arbitrary)
  maxHeight: 200,   // max-h-[200px] (arbitrary)
});

Nested Objects

Nested style objects (for responsive breakpoints or state styles) are skipped during conversion:

const classes = styleToTailwind({
  padding: 16,
  sm: {
    padding: 24,
  },
  hover: {
    backgroundColor: { hex: '#2563eb' },
  },
});
// Returns: ['p-4']
// Note: Responsive and state styles are skipped - convert them separately

styleToTailwindString

Converts a CSS style object to a space-separated string of Tailwind CSS classes. This is a convenience function that calls styleToTailwind and joins the results.

Prop

Type

Returns: string - Space-separated Tailwind CSS class string

Example

import { styleToTailwindString } from '@reallygoodwork/style-to-tailwind';

const className = styleToTailwindString({
  padding: 16,
  margin: 8,
  fontSize: 14,
});
// Returns: 'p-4 m-2 text-sm'

// Use in JSX
<div className={className}>Content</div>

Utility Functions

colorToTailwind

Converts a color object to a Tailwind color class for a specific property.

Prop

Type

Returns: string | null - Tailwind color class or null if no match found

Example

import { colorToTailwind } from '@reallygoodwork/style-to-tailwind';

const bgClass = colorToTailwind('backgroundColor', {
  hex: '#3b82f6',
  rgb: { r: 59, g: 130, b: 246, a: 1 },
  hsl: { h: 217, s: 91, l: 60, a: 1 },
});
// Returns: 'bg-blue-500'

const textClass = colorToTailwind('color', {
  hex: '#ef4444',
});
// Returns: 'text-red-500'

hexToTailwindColor

Converts a hex color string to the closest Tailwind color name and shade.

Prop

Type

Returns: string | null - Tailwind color name and shade (e.g., 'blue-500') or null if no close match

Example

import { hexToTailwindColor } from '@reallygoodwork/style-to-tailwind';

hexToTailwindColor('#3b82f6');  // Returns: 'blue-500'
hexToTailwindColor('#ef4444');  // Returns: 'red-500'
hexToTailwindColor('#22c55e');  // Returns: 'green-500'
hexToTailwindColor('#123456');  // Returns: null (no close match)

convertToTailwindScale

Converts a numeric value (in pixels) to a Tailwind scale value.

Prop

Type

Returns: string | null - Tailwind scale value or null if no match

Example

import { convertToTailwindScale } from '@reallygoodwork/style-to-tailwind';

convertToTailwindScale('padding', 16);      // Returns: '4'
convertToTailwindScale('fontSize', 14);     // Returns: 'sm'
convertToTailwindScale('margin', 32);       // Returns: '8'
convertToTailwindScale('padding', '1rem');  // Returns: '4' (1rem = 16px)

buildScaleClass

Builds a Tailwind class from a property and scale value.

Prop

Type

Returns: string | null - Tailwind class or null if property has no prefix

Example

import { buildScaleClass } from '@reallygoodwork/style-to-tailwind';

buildScaleClass('padding', '4');        // Returns: 'p-4'
buildScaleClass('fontSize', 'sm');      // Returns: 'text-sm'
buildScaleClass('borderRadius', '8');   // Returns: 'rounded-lg'
buildScaleClass('gap', '16');           // Returns: 'gap-4'

reverseMappings

Exports the reverse mappings used for converting CSS property-value pairs to Tailwind classes. This is generated from @reallygoodwork/coral-tw2css mappings.

import { reverseMappings } from '@reallygoodwork/style-to-tailwind';

// Access mappings for a property
console.log(reverseMappings['padding']?.['16']);
// Returns: 'p-4'

console.log(reverseMappings['fontSize']?.['14']);
// Returns: 'text-sm'

Type Definitions

StyleObject

Represents a CSS style object that can be converted to Tailwind classes.

Prop

Type

Example:

const styles: StyleObject = {
  padding: 16,
  backgroundColor: { hex: '#3b82f6' },
  fontSize: 14,
  sm: {
    padding: 24,
  },
};

ColorObject

Represents a color with multiple format representations.

Prop

Type

Example:

const color: ColorObject = {
  hex: '#3b82f6',
  rgb: { r: 59, g: 130, b: 246, a: 1 },
  hsl: { h: 217, s: 91, l: 60, a: 1 },
};

Supported Properties

Spacing Properties

The following properties use Tailwind's spacing scale (multiplied by 4px):

  • padding, paddingTop, paddingRight, paddingBottom, paddingLeft
  • paddingInlineStart, paddingInlineEnd, paddingBlockStart, paddingBlockEnd
  • margin, marginTop, marginRight, marginBottom, marginLeft
  • marginInlineStart, marginInlineEnd, marginBlockStart, marginBlockEnd
  • gap, rowGap, columnGap
  • top, right, bottom, left, inset
  • width, height, minWidth, minHeight, maxWidth, maxHeight

Spacing Scale Examples:

  • 00px
  • 0.52px
  • 14px
  • 416px (1rem)
  • 832px (2rem)
  • 1664px (4rem)
  • 2496px (6rem)

Typography Properties

  • fontSize - Converts to Tailwind text size classes:

    • 12pxtext-xs
    • 14pxtext-sm
    • 16pxtext-base
    • 18pxtext-lg
    • 20pxtext-xl
    • 24pxtext-2xl
    • And more...
  • fontWeight - Converts to Tailwind font weight classes:

    • 400font-normal
    • 500font-medium
    • 600font-semibold
    • 700font-bold
    • And more...

Color Properties

The following properties support color objects and hex strings:

  • colortext-{color}
  • backgroundColorbg-{color}
  • borderColorborder-{color}
  • outlineColoroutline-{color}
  • ringColorring-{color}
  • fillfill-{color}
  • strokestroke-{color}

Supported Tailwind Colors:

  • Base: black, white
  • Grays: slate, gray, zinc
  • Colors: red, blue, green, yellow, and more
  • Each color includes shades from 50 to 950

Border Properties

  • borderRadius - Converts to Tailwind rounded classes:

    • 0rounded-none
    • 2pxrounded-sm
    • 4pxrounded
    • 6pxrounded-md
    • 8pxrounded-lg
    • 12pxrounded-xl
    • 16pxrounded-2xl
    • 24pxrounded-3xl
    • 9999pxrounded-full
  • borderWidth - Converts to Tailwind border width classes

Other Properties

Many other CSS properties are supported through reverse mappings from @reallygoodwork/coral-tw2css. If a property-value pair doesn't have an exact match, the function will fall back to Tailwind's arbitrary value syntax.


Conversion Strategy

The package uses a multi-step conversion strategy:

  1. Exact Reverse Mapping - Checks if the property-value pair has an exact match in reverse mappings
  2. Color Object Matching - For color properties, matches hex values to Tailwind color palette
  3. Scale Conversion - Converts numeric values to Tailwind spacing or font size scale
  4. Arbitrary Values - Falls back to Tailwind arbitrary value syntax ([value]) for unmatched values

Example Conversion Flow

// Input: { padding: 16 }
// Step 1: Check reverse mappings → Found: 'p-4'
// Result: 'p-4'

// Input: { backgroundColor: { hex: '#3b82f6' } }
// Step 1: Check reverse mappings → No match
// Step 2: Match color → Found: 'blue-500'
// Step 3: Build class → 'bg-blue-500'
// Result: 'bg-blue-500'

// Input: { padding: 13 }
// Step 1: Check reverse mappings → No match
// Step 2: Scale conversion → Closest: 12px (scale 3) or 16px (scale 4)
// Step 3: If close enough (within 2px), use closest match
// Step 4: Otherwise, use arbitrary → 'p-[13px]'
// Result: 'p-3' or 'p-[13px]' (depending on threshold)

Usage Examples

Basic Button Styles

import { styleToTailwindString } from '@reallygoodwork/style-to-tailwind';

const buttonStyles = {
  padding: 12,
  fontSize: 14,
  fontWeight: 600,
  backgroundColor: { hex: '#3b82f6' },
  color: { hex: '#ffffff' },
  borderRadius: 6,
};

const className = styleToTailwindString(buttonStyles);
// Returns: 'p-3 text-sm font-semibold bg-blue-500 text-white rounded-md'

<button className={className}>Click me</button>

Card Component Styles

const cardStyles = {
  padding: 24,
  backgroundColor: { hex: '#ffffff' },
  borderRadius: 12,
  boxShadow: '0 4px 6px rgba(0,0,0,0.1)',
};

const className = styleToTailwindString(cardStyles);
// Returns: 'p-6 bg-white rounded-xl [box-shadow:0_4px_6px_rgba(0,0,0,0.1)]'

Layout Styles

const layoutStyles = {
  display: 'flex',
  gap: 16,
  padding: 32,
  alignItems: 'center',
  justifyContent: 'space-between',
};

const className = styleToTailwindString(layoutStyles);
// Returns: 'flex gap-4 p-8 items-center justify-between'

Converting from Inline Styles

// Convert React inline styles to Tailwind
const inlineStyles = {
  padding: '16px',
  backgroundColor: '#3b82f6',
  color: '#ffffff',
  borderRadius: '8px',
};

const className = styleToTailwindString(inlineStyles);
// Returns: 'p-4 bg-blue-500 text-white rounded-lg'

Converting Coral Styles

import { styleToTailwind } from '@reallygoodwork/style-to-tailwind';
import type { CoralStyleType } from '@reallygoodwork/coral-core';

const coralStyles: CoralStyleType = {
  paddingInlineStart: 16,
  paddingInlineEnd: 16,
  paddingBlockStart: 16,
  paddingBlockEnd: 16,
  backgroundColor: {
    hex: '#3b82f6',
    rgb: { r: 59, g: 130, b: 246, a: 1 },
    hsl: { h: 217, s: 91, l: 60, a: 1 },
  },
};

const classes = styleToTailwind(coralStyles);
// Returns: ['p-4', 'bg-blue-500']

Handling Custom Colors

const customColorStyles = {
  backgroundColor: { hex: '#123456' }, // Custom color not in Tailwind palette
};

const className = styleToTailwindString(customColorStyles);
// Returns: 'bg-[#123456]' (arbitrary value)

Converting Responsive Styles

// Convert base styles
const baseClasses = styleToTailwindString({
  padding: 16,
  fontSize: 14,
});

// Convert responsive styles separately
const smClasses = styleToTailwindString({
  padding: 24,
  fontSize: 16,
});

// Combine with Tailwind responsive prefixes
const className = `${baseClasses} sm:${smClasses.split(' ').join(' sm:')}`;

Integration Examples

With React Components

import { styleToTailwindString } from '@reallygoodwork/style-to-tailwind';

function Button({ variant = 'primary' }) {
  const baseStyles = {
    padding: 12,
    fontSize: 14,
    fontWeight: 600,
    borderRadius: 6,
  };

  const variantStyles = {
    primary: {
      backgroundColor: { hex: '#3b82f6' },
      color: { hex: '#ffffff' },
    },
    secondary: {
      backgroundColor: { hex: '#6b7280' },
      color: { hex: '#ffffff' },
    },
  };

  const className = styleToTailwindString({
    ...baseStyles,
    ...variantStyles[variant],
  });

  return <button className={className}>Click me</button>;
}

Converting from CSS-in-JS Libraries

import { styleToTailwindString } from '@reallygoodwork/style-to-tailwind';

// Convert styled-components styles
const styledButtonStyles = {
  padding: '12px 24px',
  backgroundColor: '#3b82f6',
  color: '#ffffff',
  borderRadius: '6px',
  fontSize: '14px',
  fontWeight: 600,
};

const tailwindClasses = styleToTailwindString(styledButtonStyles);
// Use with Tailwind instead of styled-components

Migrating from Inline Styles

import { styleToTailwindString } from '@reallygoodwork/style-to-tailwind';

// Before: Inline styles
function OldComponent() {
  return (
    <div style={{
      padding: '16px',
      backgroundColor: '#f3f4f6',
      borderRadius: '8px',
    }}>
      Content
    </div>
  );
}

// After: Tailwind classes
function NewComponent() {
  const className = styleToTailwindString({
    padding: 16,
    backgroundColor: '#f3f4f6',
    borderRadius: 8,
  });

  return <div className={className}>Content</div>;
}

Converting Coral Components to Tailwind

import { styleToTailwindString } from '@reallygoodwork/style-to-tailwind';
import type { CoralRootNode } from '@reallygoodwork/coral-core';

function convertCoralToTailwind(spec: CoralRootNode) {
  if (!spec.styles) return '';

  return styleToTailwindString(spec.styles);
}

// Use in component generation
const coralSpec: CoralRootNode = {
  name: 'Button',
  elementType: 'button',
  styles: {
    padding: 16,
    backgroundColor: { hex: '#3b82f6' },
    color: { hex: '#ffffff' },
    borderRadius: 8,
  },
};

const className = convertCoralToTailwind(coralSpec);
// Returns: 'p-4 bg-blue-500 text-white rounded-lg'

Batch Conversion

import { styleToTailwind } from '@reallygoodwork/style-to-tailwind';

const styleObjects = [
  { padding: 16, backgroundColor: { hex: '#3b82f6' } },
  { padding: 24, backgroundColor: { hex: '#ef4444' } },
  { padding: 32, backgroundColor: { hex: '#22c55e' } },
];

const classArrays = styleObjects.map(styleToTailwind);
// [
//   ['p-4', 'bg-blue-500'],
//   ['p-6', 'bg-red-500'],
//   ['p-8', 'bg-green-500'],
// ]

Color Matching Algorithm

The package uses a color matching algorithm to find the closest Tailwind color:

  1. Exact Match - First checks for exact hex matches in Tailwind color palette
  2. Closest Match - Calculates Euclidean distance in RGB space to find closest color
  3. Threshold - Only returns a match if distance is less than 50 (prevents poor matches)
  4. Fallback - Uses arbitrary value syntax if no close match found

Color Distance Calculation

// Euclidean distance in RGB space
const distance = Math.sqrt(
  Math.pow(r1 - r2, 2) +
  Math.pow(g1 - g2, 2) +
  Math.pow(b1 - b2, 2)
);

Limitations

Not Fully Supported

  • Responsive Styles - Nested responsive breakpoint objects are skipped (convert separately)
  • State Styles - Nested pseudo-class objects (hover, focus, etc.) are skipped
  • Complex Values - Some complex CSS values may not convert perfectly
  • Custom Tailwind Config - Uses default Tailwind configuration
  • Dynamic Values - Values calculated at runtime may not convert correctly

Best Results With

  • Standard CSS properties with standard values
  • Tailwind spacing scale values (multiples of 4px)
  • Tailwind color palette colors
  • Standard font sizes
  • Numeric values or simple string values with units

Arbitrary Values

When a property-value pair cannot be matched to a Tailwind class, the package falls back to Tailwind's arbitrary value syntax:

// Custom padding
{ padding: 13 } → 'p-[13px]'

// Custom color
{ backgroundColor: { hex: '#123456' } } → 'bg-[#123456]'

// Custom property
{ customProperty: 'value' } → '[custom-property:value]'

Performance Considerations

Optimization Tips:

// Cache converted classes for repeated use
const buttonClasses = styleToTailwindString(buttonStyles);
// Reuse buttonClasses instead of converting multiple times

// Convert in batches
const classArrays = styleObjects.map(styleToTailwind);

// Use utility functions directly for specific conversions
const colorClass = colorToTailwind('backgroundColor', colorObject);


Additional Resources

External Documentation

Coral Documentation

On this page