Skip to content

Tailwind CSS - Functions & Directives

While Tailwind’s philosophy is utility-first, there are times when you need to write custom CSS. Tailwind provides powerful directives and functions to use within your CSS files, allowing you to seamlessly integrate your own styles with the Tailwind ecosystem.

To use these features, you must have a build step. They are special instructions for the Tailwind CSS compiler and are not valid, standard CSS. A minimal setup involves tailwindcss CLI, postcss, and a package.json file.

# Project Setup (if not already done)
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
# Your main CSS file (e.g., src/input.css)
/* ... your directives will go here ... */
# Build command
npx tailwindcss -i ./src/input.css -o ./dist/output.css --watch

The @tailwind directive is your main entry point for injecting Tailwind’s generated styles into your CSS. It injects the base, components, and utilities layers.

src/input.css
/* Injects Tailwind's base styles (like Preflight) and reset rules. */
@tailwind base;
/* Injects Tailwind's component classes (e.g., for plugins). */
@tailwind components;
/* Injects all of Tailwind's utility classes. */
@tailwind utilities;

The @layer directive allows you to tell Tailwind which ‘bucket’ your custom styles belong to. This is crucial for managing CSS specificity and ensuring your custom styles can be overridden by utilities when needed. You can also apply variants like hover: and md: to styles within a layer.

src/input.css
@tailwind base;
@tailwind components;
@tailwind utilities;
/* Define custom component styles within the 'components' layer */
@layer components {
.card {
background-color: white;
border-radius: theme('borderRadius.lg');
padding: theme('spacing.6');
box-shadow: theme('boxShadow.md');
}
/* You can even add variants! */
.card:hover {
box-shadow: theme('boxShadow.xl');
}
}

By placing .card in the components layer, it will have lower specificity than utility classes, meaning you can still use utilities like p-8 or bg-blue-100 on a .card element to override its base styles.

The @apply directive lets you inline existing utility classes directly into your own custom CSS rules. This is useful for abstracting repeated utility patterns into a single component class.

src/input.css
@layer components {
.btn-primary {
@apply py-2 px-4 bg-blue-600 text-white font-semibold rounded-lg shadow-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-400 focus:ring-opacity-75;
}
}

Now you can use <button class="btn-primary">Click Me</button> instead of that long string of utilities every time.

While @apply is tempting, it can lead to problems if overused, especially in modern JavaScript frameworks (like Vue or Svelte) that use scoped styles. You cannot @apply a class defined in a global CSS file inside a component’s scoped <style> block. This is because the files are processed independently. For truly reusable, framework-agnostic components, it’s often better to create a plugin using addComponents.

The theme() function allows you to access values from your tailwind.config.js file directly in your custom CSS. This is essential for maintaining consistency with your design system.

.content-area {
/* Accessing spacing values */
padding: theme('spacing.8');
/* Accessing nested color values (use dot notation) */
background-color: theme('colors.gray.100');
border: 1px solid theme('colors.gray.300');
/* Accessing opacity modifiers */
color: theme('colors.blue.800 / 75%'); /* 75% opacity */
}

The screen() function lets you create media queries that reference your project’s breakpoints from your tailwind.config.js file, ensuring your custom CSS and utility classes share the same responsive behavior.

.hero-title {
font-size: 2rem;
}
/* Use screen() to reference breakpoints from your config */
@media screen(md) {
.hero-title {
font-size: 4rem;
}
}
/* This will compile to something like: */
/*
@media (min-width: 768px) {
.hero-title {
font-size: 4rem;
}
}
*/

The @config directive allows you to specify a different Tailwind config file for a specific CSS entry point. This is an advanced feature, typically used in complex projects with multiple themes, like a public site and an admin panel that have different design systems.

/* in admin-styles.css */
@config "./tailwind.admin.config.js";
@tailwind base;
@tailwind components;
@tailwind utilities;