12/05/2026 01:14am

EP 8: Customize Tailwind to Make It Yours: Professional Theme and Plugin Mastery
#design system
#theme variables
#Tailwind CSS
#custom colors
It's time to elevate your Tailwind CSS skills to a professional level! After learning the fundamentals and various techniques, today we'll explore how to customize Tailwind CSS to perfectly suit your project needs.
Tailwind CSS customization can be done in multiple ways, from using the tailwind.config.js file to creating Custom CSS and utilizing various plugins. Let's discover how to make Tailwind CSS truly yours.
Tailwind CSS Theme Customization
Using tailwind.config.js
The tailwind.config.js file is the heart of customizing Tailwind CSS for your project:
// tailwind.config.js
module.exports = {
content: [
'./src/**/*.{html,js,jsx,ts,tsx,vue}',
'./pages/**/*.{html,js,jsx,ts,tsx,vue}',
'./components/**/*.{html,js,jsx,ts,tsx,vue}'
],
theme: {
extend: {
// Custom Colors
colors: {
primary: {
50: '#eff6ff',
100: '#dbeafe',
200: '#bfdbfe',
300: '#93c5fd',
400: '#60a5fa',
500: '#3b82f6',
600: '#2563eb',
700: '#1d4ed8',
800: '#1e40af',
900: '#1e3a8a',
950: '#172554'
},
secondary: {
50: '#fdf4ff',
100: '#fae8ff',
200: '#f5d0fe',
300: '#f0abfc',
400: '#e879f9',
500: '#d946ef',
600: '#c026d3',
700: '#a21caf',
800: '#86198f',
900: '#701a75',
950: '#4a044e'
},
gray: {
50: '#f9fafb',
100: '#f3f4f6',
200: '#e5e7eb',
300: '#d1d5db',
400: '#9ca3af',
500: '#6b7280',
600: '#4b5563',
700: '#374151',
800: '#1f2937',
900: '#111827',
950: '#030712'
}
},
// Custom Fonts
fontFamily: {
sans: ['Inter Variable', 'Inter', 'ui-sans-serif', 'system-ui', 'sans-serif'],
serif: ['Playfair Display Variable', 'Playfair Display', 'ui-serif', 'serif'],
mono: ['JetBrains Mono Variable', 'JetBrains Mono', 'ui-monospace', 'monospace'],
display: ['Cal Sans', 'Inter Variable', 'Inter', 'ui-sans-serif', 'system-ui', 'sans-serif']
},
// Custom Spacing
spacing: {
'18': '4.5rem',
'88': '22rem',
'128': '32rem'
},
// Custom Shadows
boxShadow: {
'soft': '0 2px 15px rgba(0, 0, 0, 0.08)',
'medium': '0 4px 25px rgba(0, 0, 0, 0.15)',
'hard': '0 10px 40px rgba(0, 0, 0, 0.2)',
'glow': '0 0 20px rgba(59, 130, 246, 0.3)',
'glow-green': '0 0 20px rgba(34, 197, 94, 0.3)',
'glow-red': '0 0 20px rgba(239, 68, 68, 0.3)'
},
// Custom Border Radius
borderRadius: {
'xl': '1rem',
'2xl': '1.5rem',
'3xl': '2rem',
'4xl': '2.5rem'
},
// Custom Animations
animation: {
'fade-in': 'fadeIn 0.5s ease-out',
'slide-up': 'slideUp 0.5s ease-out',
'slide-down': 'slideDown 0.5s ease-out',
'slide-left': 'slideLeft 0.5s ease-out',
'slide-right': 'slideRight 0.5s ease-out',
'bounce-in': 'bounceIn 0.6s ease-out',
'float': 'float 3s ease-in-out infinite'
},
// Custom Keyframes
keyframes: {
fadeIn: {
'0%': { opacity: '0' },
'100%': { opacity: '1' }
},
slideUp: {
'0%': { opacity: '0', transform: 'translateY(30px)' },
'100%': { opacity: '1', transform: 'translateY(0)' }
},
slideDown: {
'0%': { opacity: '0', transform: 'translateY(-30px)' },
'100%': { opacity: '1', transform: 'translateY(0)' }
},
slideLeft: {
'0%': { opacity: '0', transform: 'translateX(30px)' },
'100%': { opacity: '1', transform: 'translateX(0)' }
},
slideRight: {
'0%': { opacity: '0', transform: 'translateX(-30px)' },
'100%': { opacity: '1', transform: 'translateX(0)' }
},
bounceIn: {
'0%': { opacity: '0', transform: 'scale(0.3)' },
'50%': { opacity: '1', transform: 'scale(1.05)' },
'70%': { transform: 'scale(0.9)' },
'100%': { opacity: '1', transform: 'scale(1)' }
},
float: {
'0%, 100%': { transform: 'translateY(0px)' },
'50%': { transform: 'translateY(-10px)' }
}
},
// Custom Breakpoints
screens: {
'xs': '475px',
'sm': '640px',
'md': '768px',
'lg': '1024px',
'xl': '1280px',
'2xl': '1536px',
'3xl': '1920px'
}
}
},
darkMode: 'class',
plugins: []
}
Using Custom Theme
<!-- Using custom colors -->
<div class="bg-primary-500 hover:bg-primary-600 text-white p-6 rounded-2xl shadow-soft">
<h3 class="font-display text-xl font-semibold mb-2">Custom Primary Color</h3>
<p class="text-primary-100">Using custom colors and fonts</p>
</div>
<!-- Using custom animations -->
<div class="animate-fade-in">
<h1 class="text-4xl font-display font-bold animate-slide-up">
Welcome Animation
</h1>
<p class="text-lg animate-slide-up animation-delay-200">
Text that slides up
</p>
</div>
<!-- Using custom spacing and shadows -->
<div class="p-18 m-88 shadow-glow rounded-3xl">
<div class="w-128 h-32 bg-gradient-to-r from-primary-500 to-secondary-500">
Custom spacing and shadows
</div>
</div>
Creating Professional Design Tokens
Professional Color System
// tailwind.config.js - Advanced Color System
module.exports = {
theme: {
extend: {
colors: {
// Brand Colors
brand: {
primary: '#3b82f6',
secondary: '#8b5cf6',
accent: '#f59e0b'
},
// Semantic Colors
success: {
50: '#f0fdf4',
100: '#dcfce7',
500: '#22c55e',
600: '#16a34a',
700: '#15803d'
},
warning: {
50: '#fffbeb',
100: '#fef3c7',
500: '#f59e0b',
600: '#d97706',
700: '#b45309'
},
error: {
50: '#fef2f2',
100: '#fee2e2',
500: '#ef4444',
600: '#dc2626',
700: '#b91c1c'
},
info: {
50: '#eff6ff',
100: '#dbeafe',
500: '#3b82f6',
600: '#2563eb',
700: '#1d4ed8'
},
// Neutral Colors
neutral: {
0: '#ffffff',
50: '#fafafa',
100: '#f4f4f5',
200: '#e4e4e7',
300: '#d4d4d8',
400: '#a1a1aa',
500: '#71717a',
600: '#52525b',
700: '#3f3f46',
800: '#27272a',
900: '#18181b',
1000: '#000000'
}
}
}
}
}
Typography System
// Typography Configuration
module.exports = {
theme: {
extend: {
fontFamily: {
// Primary Font Stack
sans: [
'Inter Variable',
'Inter',
'-apple-system',
'BlinkMacSystemFont',
'Segoe UI',
'Roboto',
'Helvetica Neue',
'Arial',
'sans-serif'
],
// Display Font
display: [
'Cal Sans',
'Inter Variable',
'Inter',
'ui-sans-serif',
'system-ui',
'sans-serif'
],
// Serif Font
serif: [
'Playfair Display Variable',
'Playfair Display',
'ui-serif',
'Georgia',
'Cambria',
'serif'
],
// Monospace Font
mono: [
'JetBrains Mono Variable',
'JetBrains Mono',
'SF Mono',
'Monaco',
'Inconsolata',
'Roboto Mono',
'monospace'
]
},
fontSize: {
// Custom Font Sizes
'xs': ['0.75rem', { lineHeight: '1rem' }],
'sm': ['0.875rem', { lineHeight: '1.25rem' }],
'base': ['1rem', { lineHeight: '1.5rem' }],
'lg': ['1.125rem', { lineHeight: '1.75rem' }],
'xl': ['1.25rem', { lineHeight: '1.75rem' }],
'2xl': ['1.5rem', { lineHeight: '2rem' }],
'3xl': ['1.875rem', { lineHeight: '2.25rem' }],
'4xl': ['2.25rem', { lineHeight: '2.5rem' }],
'5xl': ['3rem', { lineHeight: '1' }],
'6xl': ['3.75rem', { lineHeight: '1' }],
'7xl': ['4.5rem', { lineHeight: '1' }],
'8xl': ['6rem', { lineHeight: '1' }],
'9xl': ['8rem', { lineHeight: '1' }]
},
letterSpacing: {
tighter: '-0.05em',
tight: '-0.025em',
normal: '0em',
wide: '0.025em',
wider: '0.05em',
widest: '0.1em'
}
}
}
}
Creating Custom Utilities
Using @layer utilities
/* input.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer utilities {
/* Text Utilities */
.text-shadow {
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.text-shadow-lg {
text-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}
/* Scroll Utilities */
.scroll-smooth {
scroll-behavior: smooth;
}
.scroll-snap-x {
scroll-snap-type: x mandatory;
}
.scroll-snap-start {
scroll-snap-align: start;
}
/* Glass Morphism */
.glass {
backdrop-filter: blur(16px) saturate(180%);
background-color: rgba(255, 255, 255, 0.75);
border: 1px solid rgba(255, 255, 255, 0.125);
}
.glass-dark {
backdrop-filter: blur(16px) saturate(180%);
background-color: rgba(17, 24, 39, 0.75);
border: 1px solid rgba(255, 255, 255, 0.125);
}
/* Custom Aspect Ratios */
.aspect-golden {
aspect-ratio: 1.618 / 1;
}
.aspect-4-3 {
aspect-ratio: 4 / 3;
}
/* Background Patterns */
.bg-grid {
background-image:
linear-gradient(rgba(0, 0, 0, 0.1) 1px, transparent 1px),
linear-gradient(90deg, rgba(0, 0, 0, 0.1) 1px, transparent 1px);
background-size: 20px 20px;
}
.bg-dots {
background-image: radial-gradient(circle, rgba(0, 0, 0, 0.1) 1px, transparent 1px);
background-size: 20px 20px;
}
/* Animation Delays */
.animation-delay-75 {
animation-delay: 75ms;
}
.animation-delay-100 {
animation-delay: 100ms;
}
.animation-delay-150 {
animation-delay: 150ms;
}
.animation-delay-200 {
animation-delay: 200ms;
}
.animation-delay-300 {
animation-delay: 300ms;
}
.animation-delay-500 {
animation-delay: 500ms;
}
/* Focus Utilities */
.focus-ring {
@apply focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-offset-2;
}
.focus-ring-error {
@apply focus:outline-none focus:ring-2 focus:ring-error-500 focus:ring-offset-2;
}
/* Gradient Text */
.text-gradient {
background: linear-gradient(90deg, #3b82f6, #8b5cf6);
background-clip: text;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
}
Using Custom Utilities
<!-- Glass Morphism Effects -->
<div class="glass p-8 rounded-2xl backdrop-blur-sm">
<h3 class="text-xl font-semibold text-gray-800">Glass Card</h3>
<p class="text-gray-600 mt-2">Modern glassmorphism effect</p>
</div>
<!-- Text Effects -->
<h1 class="text-6xl font-bold text-gradient text-shadow-lg">
Gradient Text with Shadow
</h1>
<!-- Custom Animations with Delays -->
<div class="space-y-4">
<div class="animate-slide-up animation-delay-100">First Item</div>
<div class="animate-slide-up animation-delay-200">Second Item</div>
<div class="animate-slide-up animation-delay-300">Third Item</div>
</div>
<!-- Background Patterns -->
<div class="bg-grid bg-gray-50 p-8 rounded-lg">
<div class="bg-white p-6 rounded-lg shadow-soft">
Content on Grid Background
</div>
</div>
<!-- Custom Aspect Ratios -->
<div class="aspect-golden bg-gradient-to-br from-primary-500 to-secondary-500 rounded-lg">
Golden Ratio Container
</div>
Advanced Dark Mode Management
Dark Mode Configuration
// tailwind.config.js
module.exports = {
darkMode: 'class', // or 'media' for system preference
theme: {
extend: {
colors: {
// Colors that change based on mode
surface: {
DEFAULT: '#ffffff',
dark: '#1a1a1a'
},
'surface-elevated': {
DEFAULT: '#fafafa',
dark: '#2a2a2a'
},
'text-primary': {
DEFAULT: '#1a1a1a',
dark: '#fafafa'
},
'text-secondary': {
DEFAULT: '#6a6a6a',
dark: '#a0a0a0'
},
'border-default': {
DEFAULT: '#e0e0e0',
dark: '#404040'
}
}
}
}
}
Custom Dark Mode Utilities
@layer utilities {
.bg-surface {
@apply bg-white dark:bg-gray-900;
}
.bg-surface-elevated {
@apply bg-gray-50 dark:bg-gray-800;
}
.text-primary {
@apply text-gray-900 dark:text-gray-100;
}
.text-secondary {
@apply text-gray-600 dark:text-gray-400;
}
.border-default {
@apply border-gray-200 dark:border-gray-700;
}
.card-surface {
@apply bg-surface border-default shadow-sm;
}
}
Dark Mode Toggle Implementation
<!-- Dark Mode Toggle -->
<button id="theme-toggle" class="p-2 rounded-lg bg-gray-100 dark:bg-gray-800 text-gray-800 dark:text-gray-200 focus-ring">
<!-- Sun Icon (Light Mode) -->
<svg class="w-5 h-5 dark:hidden" fill="currentColor" viewBox="0 0 24 24">
<path d="M12 2.25a.75.75 0 01.75.75v2.25a.75.75 0 01-1.5 0V3a.75.75 0 01.75-.75zM7.5 12a4.5 4.5 0 119 0 4.5 4.5 0 01-9 0zM18.894 6.166a.75.75 0 00-1.06-1.06l-1.591 1.59a.75.75 0 101.06 1.061l1.591-1.59zM21.75 12a.75.75 0 01-.75.75h-2.25a.75.75 0 010-1.5H21a.75.75 0 01.75.75zM17.834 18.894a.75.75 0 001.06-1.06l-1.59-1.591a.75.75 0 10-1.061 1.06l1.59 1.591zM12 18a.75.75 0 01.75.75V21a.75.75 0 01-1.5 0v-2.25A.75.75 0 0112 18zM7.758 17.303a.75.75 0 00-1.061-1.06l-1.591 1.59a.75.75 0 001.06 1.061l1.591-1.59zM6 12a.75.75 0 01-.75.75H3a.75.75 0 010-1.5h2.25A.75.75 0 016 12zM6.697 7.757a.75.75 0 001.06-1.06l-1.59-1.591a.75.75 0 00-1.061 1.06l1.59 1.591z" />
</svg>
<!-- Moon Icon (Dark Mode) -->
<svg class="w-5 h-5 hidden dark:block" fill="currentColor" viewBox="0 0 24 24">
<path d="M9.528 1.718a.75.75 0 01.162.819A8.97 8.97 0 009 6a9 9 0 009 9 8.97 8.97 0 003.463-.69.75.75 0 01.981.98 10.503 10.503 0 01-9.694 6.46c-5.799 0-10.5-4.701-10.5-10.5 0-4.368 2.667-8.112 6.46-9.694a.75.75 0 01.818.162z" />
</svg>
</button>
<script>
// Dark Mode Toggle Script
const themeToggle = document.getElementById('theme-toggle');
const html = document.documentElement;
// Check for saved theme or default to system preference
const savedTheme = localStorage.getItem('theme');
const systemPrefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
if (savedTheme === 'dark' || (!savedTheme && systemPrefersDark)) {
html.classList.add('dark');
}
themeToggle.addEventListener('click', () => {
html.classList.toggle('dark');
// Save preference to localStorage
if (html.classList.contains('dark')) {
localStorage.setItem('theme', 'dark');
} else {
localStorage.setItem('theme', 'light');
}
});
// Listen for system preference changes
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {
if (!localStorage.getItem('theme')) {
if (e.matches) {
html.classList.add('dark');
} else {
html.classList.remove('dark');
}
}
});
</script>
Using Plugin Ecosystem
Recommended Official Plugins
// tailwind.config.js
module.exports = {
plugins: [
// Typography Plugin - for Rich Text Content
require('@tailwindcss/typography'),
// Forms Plugin - improves Form Elements
require('@tailwindcss/forms'),
// Aspect Ratio Plugin - manages aspect ratios
require('@tailwindcss/aspect-ratio'),
// Line Clamp Plugin - limits text lines
require('@tailwindcss/line-clamp'),
// Container Queries Plugin
require('@tailwindcss/container-queries')
]
}
Using Typography Plugin
<!-- Rich Text Content -->
<article class="prose prose-lg prose-blue max-w-none dark:prose-invert">
<h1>Article Title</h1>
<p class="lead">Prominent introductory text</p>
<h2>Subheading</h2>
<p>Article content with automatic formatting. Supports <strong>bold</strong>, <em>italic</em>, and <code>code</code></p>
<blockquote>
<p>Beautiful and prominent quotes</p>
</blockquote>
<ul>
<li>Automatically formatted lists</li>
<li>Easy to use</li>
<li>Supports Dark Mode</li>
</ul>
<pre><code class="language-javascript">
const message = "Hello, World!";
console.log(message);
</code></pre>
</article>
<!-- Custom Prose Variants -->
<div class="prose prose-primary max-w-4xl mx-auto">
<!-- Content will use primary color scheme -->
</div>
<!-- Small Prose -->
<div class="prose prose-sm max-w-2xl">
<!-- Smaller text for compact content -->
</div>
Using Container Queries
<!-- Container that adapts to its own size -->
<div class="@container max-w-4xl mx-auto">
<div class="grid grid-cols-1 @sm:grid-cols-2 @lg:grid-cols-3 @xl:grid-cols-4 gap-4">
<div class="bg-white p-4 rounded-lg shadow-sm">
<img class="w-full aspect-square @sm:aspect-video object-cover rounded mb-3"
src="https://images.unsplash.com/photo-1518837695005-2083093ee35b?w=400"
alt="Product Image"
loading="lazy">
<h3 class="font-semibold text-sm @sm:text-base @lg:text-lg">Product Name</h3>
<p class="text-gray-600 text-xs @sm:text-sm mt-1">Product description</p>
<div class="mt-3">
<button class="w-full @sm:w-auto px-4 py-2 bg-primary-500 text-white rounded text-sm hover:bg-primary-600 transition-colors">
Add to Cart
</button>
</div>
</div>
</div>
</div>
<!-- Named Container Queries -->
<div class="@container/sidebar w-64">
<nav class="space-y-1">
<a href="#" class="block p-2 @lg/sidebar:p-3 rounded hover:bg-gray-100 transition-colors">
<div class="flex items-center space-x-2 @lg/sidebar:space-x-3">
<svg class="w-4 h-4 @lg/sidebar:w-5 @lg/sidebar:h-5" fill="currentColor" viewBox="0 0 24 24">
<path d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2H5a2 2 0 00-2-2z"/>
</svg>
<span class="text-sm @lg/sidebar:text-base">Navigation Item</span>
</div>
</a>
</nav>
</div>
Interesting Third-Party Plugins
// tailwind.config.js
module.exports = {
plugins: [
// Tailwind CSS Animate - Animation utilities
require('tailwindcss-animate'),
// Tailwind CSS Radix - Radix UI integration
require('tailwindcss-radix'),
// Headless UI - Integration with Headless UI
require('@headlessui/tailwindcss'),
// Custom Plugin for Scrollbar
require('tailwind-scrollbar'),
// Custom Plugin Example
function({ addUtilities, theme }) {
const newUtilities = {
'.text-stroke': {
'-webkit-text-stroke': '1px currentColor',
},
'.text-stroke-2': {
'-webkit-text-stroke': '2px currentColor',
},
'.backdrop-blur-xs': {
'backdrop-filter': 'blur(2px)',
},
}
addUtilities(newUtilities)
}
]
}
Creating Advanced Component Systems
Advanced Component Architecture
/* components.css */
@layer components {
/* Button System */
.btn {
@apply inline-flex items-center justify-center font-medium rounded-lg transition-all duration-200;
@apply focus:outline-none focus:ring-2 focus:ring-offset-2;
@apply disabled:opacity-50 disabled:cursor-not-allowed;
}
.btn-primary {
@apply bg-primary-500 text-white shadow-sm;
@apply hover:bg-primary-600 hover:shadow-md hover:-translate-y-0.5;
@apply focus:ring-primary-500;
@apply active:bg-primary-700 active:translate-y-0;
}
.btn-secondary {
@apply bg-secondary-500 text-white shadow-sm;
@apply hover:bg-secondary-600 hover:shadow-md hover:-translate-y-0.5;
@apply focus:ring-secondary-500;
}
.btn-outline {
@apply border-2 bg-transparent shadow-sm;
@apply hover:shadow-md hover:-translate-y-0.5;
}
.btn-outline-primary {
@apply border-primary-500 text-primary-500;
@apply hover:bg-primary-500 hover:text-white;
@apply focus:ring-primary-500;
}
.btn-ghost {
@apply bg-transparent shadow-none;
@apply hover:bg-gray-100 dark:hover:bg-gray-800;
@apply focus:ring-gray-500;
}
/* Button Sizes */
.btn-xs {
@apply px-2 py-1 text-xs;
}
.btn-sm {
@apply px-3 py-1.5 text-sm;
}
.btn-md {
@apply px-4 py-2 text-base;
}
.btn-lg {
@apply px-6 py-3 text-lg;
}
.btn-xl {
@apply px-8 py-4 text-xl;
}
/* Card System */
.card {
@apply bg-white dark:bg-gray-800 rounded-xl shadow-sm border border-gray-200 dark:border-gray-700;
@apply overflow-hidden transition-all duration-300;
}
.card-hover {
@apply hover:shadow-lg hover:-translate-y-1;
}
.card-interactive {
@apply cursor-pointer;
@apply hover:shadow-xl hover:-translate-y-2;
@apply active:translate-y-0 active:shadow-md;
}
.card-glass {
@apply glass border-white/20 dark:border-gray-700/30;
}
.card-header {
@apply px-6 py-4 border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-700/50;
}
.card-body {
@apply px-6 py-4;
}
.card-footer {
@apply px-6 py-4 border-t border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-700/50;
}
/* Input System */
.input {
@apply w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg;
@apply bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100;
@apply focus:ring-2 focus:ring-primary-500 focus:border-primary-500;
@apply transition-colors duration-200;
@apply placeholder:text-gray-400 dark:placeholder:text-gray-500;
}
.input-error {
@apply border-error-500 focus:ring-error-500 focus:border-error-500;
}
.input-success {
@apply border-success-500 focus:ring-success-500 focus:border-success-500;
}
/* Alert System */
.alert {
@apply p-4 rounded-lg border flex items-start space-x-3;
}
.alert-success {
@apply bg-success-50 dark:bg-success-900/20 border-success-200 dark:border-success-800 text-success-800 dark:text-success-200;
}
.alert-warning {
@apply bg-warning-50 dark:bg-warning-900/20 border-warning-200 dark:border-warning-800 text-warning-800 dark:text-warning-200;
}
.alert-error {
@apply bg-error-50 dark:bg-error-900/20 border-error-200 dark:border-error-800 text-error-800 dark:text-error-200;
}
.alert-info {
@apply bg-info-50 dark:bg-info-900/20 border-info-200 dark:border-info-800 text-info-800 dark:text-info-200;
}
/* Badge System */
.badge {
@apply inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium;
}
.badge-primary {
@apply bg-primary-100 dark:bg-primary-900/30 text-primary-800 dark:text-primary-200;
}
.badge-success {
@apply bg-success-100 dark:bg-success-900/30 text-success-800 dark:text-success-200;
}
.badge-warning {
@apply bg-warning-100 dark:bg-warning-900/30 text-warning-800 dark:text-warning-200;
}
.badge-error {
@apply bg-error-100 dark:bg-error-900/30 text-error-800 dark:text-error-200;
}
/* Navigation */
.nav-link {
@apply px-3 py-2 rounded-md text-sm font-medium;
@apply text-gray-600 dark:text-gray-300 hover:text-gray-900 dark:hover:text-gray-100;
@apply hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors;
}
.nav-link-active {
@apply text-primary-600 dark:text-primary-400 bg-primary-50 dark:bg-primary-900/30;
@apply hover:text-primary-700 dark:hover:text-primary-300 hover:bg-primary-100 dark:hover:bg-primary-900/50;
}
}
Creating a Complete Design System
Project Structure
project/
├── src/
│ ├── styles/
│ │ ├── tailwind.css # Main Tailwind file
│ │ ├── components/
│ │ │ ├── buttons.css # Button components
│ │ │ ├── cards.css # Card components
│ │ │ ├── forms.css # Form components
│ │ │ └── navigation.css # Navigation components
│ │ ├── utilities/
│ │ │ ├── animations.css # Custom animations
│ │ │ ├── effects.css # Visual effects
│ │ │ └── helpers.css # Helper utilities
│ │ └── tokens/
│ │ ├── colors.css # Color tokens
│ │ ├── typography.css # Typography tokens
│ │ └── spacing.css # Spacing tokens
│ ├── components/ # Framework components
│ └── pages/ # Application pages
├── docs/
│ ├── design-system.html # Design system documentation
│ └── style-guide.html # Style guide
├── tailwind.config.js # Tailwind configuration
└── package.json
Main Tailwind File
/* src/styles/tailwind.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
/* Import Design Tokens */
@import './tokens/colors.css';
@import './tokens/typography.css';
@import './tokens/spacing.css';
/* Import Components */
@import './components/buttons.css';
@import './components/cards.css';
@import './components/forms.css';
@import './components/navigation.css';
/* Import Custom Utilities */
@import './utilities/animations.css';
@import './utilities/effects.css';
@import './utilities/helpers.css';
@layer base {
/* Global Base Styles */
html {
@apply scroll-smooth antialiased;
}
body {
@apply font-sans text-gray-900 dark:text-gray-100 bg-white dark:bg-gray-900;
@apply transition-colors duration-300;
}
/* Focus Styles */
*:focus {
@apply outline-none;
}
/* Selection Styles */
::selection {
@apply bg-primary-500 text-white;
}
/* Scrollbar Styles */
::-webkit-scrollbar {
@apply w-2;
}
::-webkit-scrollbar-track {
@apply bg-gray-100 dark:bg-gray-800;
}
::-webkit-scrollbar-thumb {
@apply bg-gray-300 dark:bg-gray-600 rounded-full;
}
::-webkit-scrollbar-thumb:hover {
@apply bg-gray-400 dark:bg-gray-500;
}
}
Performance Optimization
Production-Optimized Tailwind Configuration
// tailwind.config.js - Production Optimized
module.exports = {
content: [
'./src/**/*.{html,js,jsx,ts,tsx,vue}',
'./pages/**/*.{html,js,jsx,ts,tsx,vue}',
'./components/**/*.{html,js,jsx,ts,tsx,vue}',
// Add any other paths where you use Tailwind classes
],
// Safelist for dynamic classes
safelist: [
'bg-primary-500',
'bg-secondary-500',
'text-error-500',
// Add classes that are generated dynamically
],
// Disable unused features for smaller build
corePlugins: {
// Disable if not used
preflight: true,
container: true,
accessibility: true,
appearance: true,
backgroundAttachment: false, // Disable if not used
backgroundClip: true,
backgroundImage: true,
backgroundOpacity: true,
backgroundPosition: true,
backgroundRepeat: true,
backgroundSize: true,
// ... configure based on usage
},
theme: {
// Use extend to add, not replace
extend: {
// Your custom theme here
}
},
plugins: [
// Only include plugins you actually use
require('@tailwindcss/typography'),
require('@tailwindcss/forms'),
]
}
Build Script Optimization
{
"scripts": {
"dev": "tailwindcss -i ./src/styles/tailwind.css -o ./dist/styles.css --watch",
"build": "NODE_ENV=production tailwindcss -i ./src/styles/tailwind.css -o ./dist/styles.css --minify",
"build:analyze": "tailwindcss -i ./src/styles/tailwind.css -o ./dist/styles.css --minify --verbose"
}
}
Component Documentation System
Style Guide Template
<!DOCTYPE html>
<html lang="en" class="scroll-smooth">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Design System Style Guide</title>
<link href="./dist/styles.css" rel="stylesheet">
</head>
<body class="bg-gray-50 dark:bg-gray-900">
<!-- Header -->
<header class="sticky top-0 z-50 bg-white/95 dark:bg-gray-900/95 backdrop-blur-sm border-b border-gray-200 dark:border-gray-700">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex items-center justify-between h-16">
<h1 class="text-xl font-bold text-gray-900 dark:text-gray-100">Design System</h1>
<div class="flex items-center space-x-4">
<!-- Theme Toggle -->
<button id="theme-toggle" class="p-2 rounded-lg bg-gray-100 dark:bg-gray-800 text-gray-800 dark:text-gray-200 hover:bg-gray-200 dark:hover:bg-gray-700 transition-colors focus-ring">
<svg class="w-5 h-5 dark:hidden" fill="currentColor" viewBox="0 0 24 24">
<path d="M12 2.25a.75.75 0 01.75.75v2.25a.75.75 0 01-1.5 0V3a.75.75 0 01.75-.75zM7.5 12a4.5 4.5 0 119 0 4.5 4.5 0 01-9 0zM18.894 6.166a.75.75 0 00-1.06-1.06l-1.591 1.59a.75.75 0 101.06 1.061l1.591-1.59zM21.75 12a.75.75 0 01-.75.75h-2.25a.75.75 0 010-1.5H21a.75.75 0 01.75.75zM17.834 18.894a.75.75 0 001.06-1.06l-1.59-1.591a.75.75 0 10-1.061 1.06l1.59 1.591zM12 18a.75.75 0 01.75.75V21a.75.75 0 01-1.5 0v-2.25A.75.75 0 0112 18zM7.758 17.303a.75.75 0 00-1.061-1.06l-1.591 1.59a.75.75 0 001.06 1.061l1.591-1.59zM6 12a.75.75 0 01-.75.75H3a.75.75 0 010-1.5h2.25A.75.75 0 016 12zM6.697 7.757a.75.75 0 001.06-1.06l-1.59-1.591a.75.75 0 00-1.061 1.06l1.59 1.591z" />
</svg>
<svg class="w-5 h-5 hidden dark:block" fill="currentColor" viewBox="0 0 24 24">
<path d="M9.528 1.718a.75.75 0 01.162.819A8.97 8.97 0 009 6a9 9 0 009 9 8.97 8.97 0 003.463-.69.75.75 0 01.981.98 10.503 10.503 0 01-9.694 6.46c-5.799 0-10.5-4.701-10.5-10.5 0-4.368 2.667-8.112 6.46-9.694a.75.75 0 01.818.162z" />
</svg>
</button>
</div>
</div>
</div>
</header>
<!-- Main Content -->
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
<div class="grid grid-cols-1 lg:grid-cols-4 gap-8">
<!-- Sidebar Navigation -->
<nav class="lg:col-span-1">
<div class="sticky top-24 space-y-2">
<a href="#colors" class="nav-link block">Colors</a>
<a href="#typography" class="nav-link block">Typography</a>
<a href="#buttons" class="nav-link block">Buttons</a>
<a href="#cards" class="nav-link block">Cards</a>
<a href="#forms" class="nav-link block">Forms</a>
<a href="#alerts" class="nav-link block">Alerts</a>
<a href="#badges" class="nav-link block">Badges</a>
</div>
</nav>
<!-- Content -->
<main class="lg:col-span-3 space-y-16">
<!-- Colors Section -->
<section id="colors" class="animate-fade-in">
<h2 class="text-3xl font-bold text-gray-900 dark:text-gray-100 mb-8">Colors</h2>
<!-- Primary Colors -->
<div class="mb-8">
<h3 class="text-xl font-semibold text-gray-900 dark:text-gray-100 mb-4">Primary Colors</h3>
<div class="grid grid-cols-5 md:grid-cols-10 gap-3">
<div class="text-center">
<div class="w-full h-16 bg-primary-50 rounded-lg border border-gray-200 dark:border-gray-700 mb-2"></div>
<div class="text-xs text-gray-600 dark:text-gray-400">50</div>
</div>
<div class="text-center">
<div class="w-full h-16 bg-primary-100 rounded-lg mb-2"></div>
<div class="text-xs text-gray-600 dark:text-gray-400">100</div>
</div>
<div class="text-center">
<div class="w-full h-16 bg-primary-200 rounded-lg mb-2"></div>
<div class="text-xs text-gray-600 dark:text-gray-400">200</div>
</div>
<div class="text-center">
<div class="w-full h-16 bg-primary-300 rounded-lg mb-2"></div>
<div class="text-xs text-gray-600 dark:text-gray-400">300</div>
</div>
<div class="text-center">
<div class="w-full h-16 bg-primary-400 rounded-lg mb-2"></div>
<div class="text-xs text-gray-600 dark:text-gray-400">400</div>
</div>
<div class="text-center">
<div class="w-full h-16 bg-primary-500 rounded-lg mb-2"></div>
<div class="text-xs text-gray-600 dark:text-gray-400 font-semibold">500</div>
</div>
<div class="text-center">
<div class="w-full h-16 bg-primary-600 rounded-lg mb-2"></div>
<div class="text-xs text-gray-600 dark:text-gray-400">600</div>
</div>
<div class="text-center">
<div class="w-full h-16 bg-primary-700 rounded-lg mb-2"></div>
<div class="text-xs text-gray-600 dark:text-gray-400">700</div>
</div>
<div class="text-center">
<div class="w-full h-16 bg-primary-800 rounded-lg mb-2"></div>
<div class="text-xs text-gray-600 dark:text-gray-400">800</div>
</div>
<div class="text-center">
<div class="w-full h-16 bg-primary-900 rounded-lg mb-2"></div>
<div class="text-xs text-gray-600 dark:text-gray-400">900</div>
</div>
</div>
</div>
</section>
<!-- Typography Section -->
<section id="typography" class="animate-fade-in">
<h2 class="text-3xl font-bold text-gray-900 dark:text-gray-100 mb-8">Typography</h2>
<div class="space-y-6">
<div class="flex items-center space-x-6">
<div class="w-16 text-sm text-gray-500 dark:text-gray-400">9xl</div>
<div class="text-9xl font-bold text-gray-900 dark:text-gray-100">Aa</div>
</div>
<div class="flex items-center space-x-6">
<div class="w-16 text-sm text-gray-500 dark:text-gray-400">6xl</div>
<div class="text-6xl font-bold text-gray-900 dark:text-gray-100">Aa</div>
</div>
<div class="flex items-center space-x-6">
<div class="w-16 text-sm text-gray-500 dark:text-gray-400">4xl</div>
<div class="text-4xl font-bold text-gray-900 dark:text-gray-100">Aa</div>
</div>
<div class="flex items-center space-x-6">
<div class="w-16 text-sm text-gray-500 dark:text-gray-400">2xl</div>
<div class="text-2xl font-bold text-gray-900 dark:text-gray-100">Aa</div>
</div>
<div class="flex items-center space-x-6">
<div class="w-16 text-sm text-gray-500 dark:text-gray-400">xl</div>
<div class="text-xl font-bold text-gray-900 dark:text-gray-100">Aa</div>
</div>
<div class="flex items-center space-x-6">
<div class="w-16 text-sm text-gray-500 dark:text-gray-400">base</div>
<div class="text-base font-medium text-gray-900 dark:text-gray-100">Aa</div>
</div>
<div class="flex items-center space-x-6">
<div class="w-16 text-sm text-gray-500 dark:text-gray-400">sm</div>
<div class="text-sm text-gray-900 dark:text-gray-100">Aa</div>
</div>
<div class="flex items-center space-x-6">
<div class="w-16 text-sm text-gray-500 dark:text-gray-400">xs</div>
<div class="text-xs text-gray-900 dark:text-gray-100">Aa</div>
</div>
</div>
</section>
<!-- Buttons Section -->
<section id="buttons" class="animate-fade-in">
<h2 class="text-3xl font-bold text-gray-900 dark:text-gray-100 mb-8">Buttons</h2>
<div class="space-y-8">
<!-- Primary Buttons -->
<div>
<h3 class="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-4">Primary Buttons</h3>
<div class="flex flex-wrap gap-4">
<button class="btn btn-primary btn-xs">Extra Small</button>
<button class="btn btn-primary btn-sm">Small</button>
<button class="btn btn-primary btn-md">Medium</button>
<button class="btn btn-primary btn-lg">Large</button>
<button class="btn btn-primary btn-xl">Extra Large</button>
</div>
</div>
<!-- Secondary Buttons -->
<div>
<h3 class="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-4">Secondary Buttons</h3>
<div class="flex flex-wrap gap-4">
<button class="btn btn-secondary btn-sm">Small</button>
<button class="btn btn-secondary btn-md">Medium</button>
<button class="btn btn-secondary btn-lg">Large</button>
</div>
</div>
<!-- Outline Buttons -->
<div>
<h3 class="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-4">Outline Buttons</h3>
<div class="flex flex-wrap gap-4">
<button class="btn btn-outline btn-outline-primary btn-sm">Primary Outline</button>
<button class="btn btn-outline btn-outline-primary btn-md">Medium Outline</button>
<button class="btn btn-outline btn-outline-primary btn-lg">Large Outline</button>
</div>
</div>
<!-- Ghost Buttons -->
<div>
<h3 class="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-4">Ghost Buttons</h3>
<div class="flex flex-wrap gap-4">
<button class="btn btn-ghost btn-sm">Small Ghost</button>
<button class="btn btn-ghost btn-md">Medium Ghost</button>
<button class="btn btn-ghost btn-lg">Large Ghost</button>
</div>
</div>
<!-- Button States -->
<div>
<h3 class="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-4">Button States</h3>
<div class="flex flex-wrap gap-4">
<button class="btn btn-primary btn-md">Normal</button>
<button class="btn btn-primary btn-md hover:bg-primary-600" style="background-color: rgb(37 99 235);">Hover</button>
<button class="btn btn-primary btn-md" disabled>Disabled</button>
</div>
</div>
</div>
</section>
<!-- Cards Section -->
<section id="cards" class="animate-fade-in">
<h2 class="text-3xl font-bold text-gray-900 dark:text-gray-100 mb-8">Cards</h2>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<!-- Basic Card -->
<div class="card">
<div class="card-body">
<h3 class="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-2">Basic Card</h3>
<p class="text-gray-600 dark:text-gray-400 mb-4">Easy-to-use basic card</p>
<button class="btn btn-primary btn-sm">Action</button>
</div>
</div>
<!-- Hover Card -->
<div class="card card-hover">
<div class="card-body">
<h3 class="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-2">Hover Card</h3>
<p class="text-gray-600 dark:text-gray-400 mb-4">Card with hover effects</p>
<button class="btn btn-primary btn-sm">Action</button>
</div>
</div>
<!-- Interactive Card -->
<div class="card card-interactive">
<div class="card-body">
<h3 class="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-2">Interactive Card</h3>
<p class="text-gray-600 dark:text-gray-400 mb-4">Clickable card</p>
<button class="btn btn-primary btn-sm">Action</button>
</div>
</div>
<!-- Card with Header/Footer -->
<div class="card md:col-span-2 lg:col-span-3">
<div class="card-header">
<h3 class="text-lg font-semibold text-gray-900 dark:text-gray-100">Card with Header & Footer</h3>
</div>
<div class="card-body">
<p class="text-gray-600 dark:text-gray-400">Card with separate header, body, and footer</p>
</div>
<div class="card-footer">
<div class="flex space-x-2">
<button class="btn btn-primary btn-sm">Primary</button>
<button class="btn btn-ghost btn-sm">Secondary</button>
</div>
</div>
</div>
</div>
</section>
<!-- Forms Section -->
<section id="forms" class="animate-fade-in">
<h2 class="text-3xl font-bold text-gray-900 dark:text-gray-100 mb-8">Forms</h2>
<div class="max-w-lg">
<form class="space-y-6">
<div>
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2" for="name">Name</label>
<input class="input" type="text" id="name" placeholder="Enter your name">
<p class="text-sm text-gray-500 dark:text-gray-400 mt-1">Please enter your real name</p>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2" for="email">Email</label>
<input class="input" type="email" id="email" placeholder="your@email.com">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2" for="email-error">Email (Error State)</label>
<input class="input input-error" type="email" id="email-error" value="invalid-email">
<p class="text-sm text-error-600 dark:text-error-400 mt-1">Invalid email format</p>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2" for="email-success">Email (Success State)</label>
<input class="input input-success" type="email" id="email-success" value="valid@email.com">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2" for="message">Message</label>
<textarea class="input min-h-[100px] resize-vertical" id="message" rows="4" placeholder="Write your message..."></textarea>
</div>
<button type="submit" class="btn btn-primary btn-lg w-full">Submit</button>
</form>
</div>
</section>
<!-- Alerts Section -->
<section id="alerts" class="animate-fade-in">
<h2 class="text-3xl font-bold text-gray-900 dark:text-gray-100 mb-8">Alerts</h2>
<div class="space-y-4 max-w-2xl">
<div class="alert alert-success">
<svg class="w-5 h-5 text-success-500 flex-shrink-0" fill="currentColor" viewBox="0 0 24 24">
<path d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
<div>
<div class="font-medium">Success</div>
<div class="text-sm opacity-75">Unable to save data. Please try again</div>
</div>
</div>
<div class="alert alert-info">
<svg class="w-5 h-5 text-info-500 flex-shrink-0" fill="currentColor" viewBox="0 0 24 24">
<path d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
<div>
<div class="font-medium">Information</div>
<div class="text-sm opacity-75">This feature will be available in 30 days</div>
</div>
</div>
</div>
</section>
<!-- Badges Section -->
<section id="badges" class="animate-fade-in">
<h2 class="text-3xl font-bold text-gray-900 dark:text-gray-100 mb-8">Badges</h2>
<div class="space-y-4">
<div>
<h3 class="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-2">Default Badges</h3>
<div class="flex flex-wrap gap-2">
<span class="badge badge-primary">Primary</span>
<span class="badge badge-success">Success</span>
<span class="badge badge-warning">Warning</span>
<span class="badge badge-error">Error</span>
</div>
</div>
<div>
<h3 class="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-2">With Icons</h3>
<div class="flex flex-wrap gap-2">
<span class="badge badge-success inline-flex items-center">
<svg class="w-3 h-3 mr-1" fill="currentColor" viewBox="0 0 24 24">
<path d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
Verified
</span>
<span class="badge badge-warning inline-flex items-center">
<svg class="w-3 h-3 mr-1" fill="currentColor" viewBox="0 0 24 24">
<path d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/>
</svg>
Pending
</span>
<span class="badge badge-error inline-flex items-center">
<svg class="w-3 h-3 mr-1" fill="currentColor" viewBox="0 0 24 24">
<path d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
Error
</span>
</div>
</div>
</div>
</section>
</main>
</div>
</div>
<!-- Footer -->
<footer class="mt-16 bg-white dark:bg-gray-800 border-t border-gray-200 dark:border-gray-700">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
<div class="text-center text-gray-600 dark:text-gray-400">
<p>© 2025 Design System. Built with Tailwind CSS</p>
</div>
</div>
</footer>
<script>
// Theme toggle functionality
const themeToggle = document.getElementById('theme-toggle');
const html = document.documentElement;
// Check for saved theme or default to system preference
const savedTheme = localStorage.getItem('theme');
const systemPrefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
if (savedTheme === 'dark' || (!savedTheme && systemPrefersDark)) {
html.classList.add('dark');
}
themeToggle.addEventListener('click', () => {
html.classList.toggle('dark');
// Save preference to localStorage
if (html.classList.contains('dark')) {
localStorage.setItem('theme', 'dark');
} else {
localStorage.setItem('theme', 'light');
}
});
// Listen for system preference changes
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {
if (!localStorage.getItem('theme')) {
if (e.matches) {
html.classList.add('dark');
} else {
html.classList.remove('dark');
}
}
});
// Smooth scroll for navigation links
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function (e) {
e.preventDefault();
const target = document.querySelector(this.getAttribute('href'));
if (target) {
target.scrollIntoView({
behavior: 'smooth',
block: 'start'
});
}
});
});
// Add active state to navigation
const navLinks = document.querySelectorAll('nav a[href^="#"]');
const sections = document.querySelectorAll('section[id]');
function updateActiveNav() {
let current = '';
sections.forEach(section => {
const sectionTop = section.offsetTop - 100;
if (window.pageYOffset >= sectionTop) {
current = section.getAttribute('id');
}
});
navLinks.forEach(link => {
link.classList.remove('nav-link-active');
if (link.getAttribute('href') === `#${current}`) {
link.classList.add('nav-link-active');
}
});
}
window.addEventListener('scroll', updateActiveNav);
updateActiveNav(); // Initial call
</script>
</body>
</html>
Managing Multi-Brand Design Systems
Brand Configuration
// tailwind.config.js - Multi-Brand Support
const brandConfig = {
default: {
primary: '#3b82f6',
secondary: '#8b5cf6',
accent: '#f59e0b'
},
brand1: {
primary: '#dc2626',
secondary: '#7c3aed',
accent: '#059669'
},
brand2: {
primary: '#059669',
secondary: '#dc2626',
accent: '#d97706'
}
};
module.exports = {
theme: {
extend: {
colors: {
// Default brand colors
primary: brandConfig.default.primary,
secondary: brandConfig.default.secondary,
accent: brandConfig.default.accent,
// Brand specific colors
'brand-1': {
primary: brandConfig.brand1.primary,
secondary: brandConfig.brand1.secondary,
accent: brandConfig.brand1.accent
},
'brand-2': {
primary: brandConfig.brand2.primary,
secondary: brandConfig.brand2.secondary,
accent: brandConfig.brand2.accent
}
}
}
}
}
Brand Switching with CSS Variables
/* Brand theming with CSS Variables */
:root {
--color-brand-primary: 59 130 246; /* RGB values for alpha support */
--color-brand-secondary: 139 92 246;
--color-brand-accent: 245 158 11;
}
[data-brand="brand1"] {
--color-brand-primary: 220 38 38;
--color-brand-secondary: 124 58 237;
--color-brand-accent: 5 150 105;
}
[data-brand="brand2"] {
--color-brand-primary: 5 150 105;
--color-brand-secondary: 220 38 38;
--color-brand-accent: 217 119 6;
}
/* Use CSS variables in components */
.brand-button {
background-color: rgb(var(--color-brand-primary));
color: white;
transition: all 0.2s;
}
.brand-button:hover {
background-color: rgb(var(--color-brand-primary) / 0.9);
}
Best Practices and Performance Tips
1. Optimization Strategies
// tailwind.config.js - Production Optimization
module.exports = {
content: [
'./src/**/*.{html,js,jsx,ts,tsx,vue}',
// Be specific with content paths
],
// Use safelist sparingly - only for dynamic classes
safelist: [
{
pattern: /bg-(red|green|blue)-(100|500|900)/,
variants: ['hover', 'focus']
}
],
// Disable unused core plugins
corePlugins: {
float: false,
clear: false,
skew: false,
// Disable features you don't use
},
theme: {
// Remove unused default colors
colors: {
transparent: 'transparent',
current: 'currentColor',
white: '#ffffff',
black: '#000000',
// Only include colors you actually use
primary: {
// Your primary color scale
}
}
}
}
2. Development Workflow
{
"scripts": {
"dev": "tailwindcss -i ./src/styles/tailwind.css -o ./dist/styles.css --watch",
"build": "NODE_ENV=production tailwindcss -i ./src/styles/tailwind.css -o ./dist/styles.css --minify",
"build:analyze": "tailwindcss -i ./src/styles/tailwind.css -o ./dist/styles.css --minify --verbose",
"purge": "purgecss --css ./dist/styles.css --content ./src/**/*.html --output ./dist/",
"lint:css": "stylelint ./src/**/*.css"
},
"devDependencies": {
"tailwindcss": "^3.4.0",
"@tailwindcss/typography": "^0.5.10",
"@tailwindcss/forms": "^0.5.7",
"autoprefixer": "^10.4.16",
"postcss": "^8.4.32"
}
}
3. Maintenance Tips
/* Organize your CSS files logically */
/* 1. Import Tailwind */
@tailwind base;
@tailwind components;
@tailwind utilities;
/* 2. Base customizations */
@layer base {
/* Global styles */
}
/* 3. Component styles */
@layer components {
/* Reusable components */
}
/* 4. Utility overrides */
@layer utilities {
/* Custom utilities */
}
/* 5. Third-party overrides (if needed) */
/* Keep these minimal and well-documented */
Summary
Advanced Tailwind CSS customization helps us create comprehensive Design Systems that perfectly meet our project requirements. Here are the key points:
Main Benefits:
- Consistency: Cohesive Design System throughout the entire project
- Maintainability: Easy to maintain and update
- Scalability: Can be extended and applied to large-scale projects
- Performance: Optimized for production
- Developer Experience: Great tools and workflow
Important Principles:
- Start with Design Tokens: Establish colors, fonts, spacing systematically
- Component-Driven: Create reusable components
- Performance-First: Consider bundle size and loading speed
- Documentation: Create comprehensive documentation and style guides
- Team Collaboration: Establish standards that the entire team understands and can use
Recommended Tools:
- Official Plugins: Typography, Forms, Aspect Ratio
- Build Tools: PostCSS, AutoPrefixer, PurgeCSS
- Development: Live reload, CSS analysis tools
- Documentation: Style guide, component library
Next Steps:
- Analyze Your Project: Determine what kind of customization you need
- Create Design Tokens: Start with colors and typography
- Develop Component System: Create reusable components
- Create Documentation: Write style guides and usage examples
- Optimize Performance: Fine-tune for speed and efficiency
When to Use Component System:
- Large Projects: When you have many repeated patterns
- Team Development: When multiple developers need consistency
- Design Systems: When building a comprehensive UI library
- Maintenance: When you need to update styles across many elements
In the next episode (EP 9), we'll learn various tips and quick techniques that will make using Tailwind CSS easier and faster, including various helper tools that will enhance development efficiency.
Ready to create a professional-level Design System? Follow Superdev School to learn more advanced techniques and don't forget to try customizing Tailwind CSS to make it your own!
Read more
🔵 Facebook: Superdev School (Superdev)
📸 Instagram: superdevschool
🎬 TikTok: superdevschool
🌐 Website: www.superdev.school