Componentes con @apply y plugins

Intermedio
Tailwind CSS
Tailwind CSS
Actualizado: 27/03/2026

La directiva @apply

La directiva @apply permite extraer combinaciones de clases de utilidad repetidas en una única clase CSS personalizada. Esto resulta útil cuando un mismo patrón de clases aparece decenas de veces en el HTML y resulta difícil de mantener.

@import "tailwindcss";

.btn {
  @apply px-4 py-2 rounded-lg font-medium text-sm transition-colors;
}

.btn-primary {
  @apply btn bg-blue-600 text-white hover:bg-blue-700;
}

.btn-secondary {
  @apply btn bg-gray-200 text-gray-800 hover:bg-gray-300;
}
<button class="btn-primary">Guardar cambios</button>
<button class="btn-secondary">Cancelar</button>

Dentro del bloque @apply se puede utilizar cualquier clase de Tailwind, incluyendo variantes de estado como hover:, focus: y variantes responsive como md:.

.input-field {
  @apply w-full px-3 py-2 border border-gray-300 rounded-lg
         focus:border-blue-500 focus:ring-2 focus:ring-blue-200
         placeholder:text-gray-400;
}

La directiva @apply también funciona dentro de selectores anidados. Es posible combinar @apply con pseudo-clases y pseudo-elementos CSS estándar en la misma regla.

Cuándo utilizar @apply y cuándo evitarlo

El uso de @apply tiene un coste: se pierden las ventajas del enfoque utility-first, ya que el HTML deja de ser autodescriptivo. Los frameworks de componentes como React, Vue o Angular encapsulan las clases dentro del propio componente, haciendo innecesario extraerlas a CSS.

Situaciones donde @apply tiene sentido:

  • Proyectos que no utilizan un framework de componentes y trabajan con HTML plano o templates del servidor
  • Estilos base para elementos de formulario que aparecen en muchos puntos de la aplicación
  • Hojas de estilo para contenido editorial generado por un CMS donde no se controla el HTML

En frameworks de componentes como React o Vue, el enfoque preferido es aplicar las clases directamente en el template del componente, ya que cada componente encapsula su propia presentación.

Capas CSS con @layer

Tailwind CSS organiza los estilos en capas (layers) con un orden de especificidad definido. La directiva @layer permite insertar CSS personalizado en la capa adecuada.

Las tres capas principales son:

  • base: estilos de reinicio y valores por defecto para elementos HTML
  • components: clases de componentes reutilizables (tarjetas, botones, badges)
  • utilities: clases de utilidad con la mayor especificidad
@import "tailwindcss";

@layer base {
  h1 { @apply text-3xl font-bold text-gray-900; }
  h2 { @apply text-2xl font-semibold text-gray-800; }
  a { @apply text-blue-600 underline hover:text-blue-800; }
}

@layer components {
  .card {
    @apply bg-white rounded-xl shadow-md p-6;
  }
  .badge {
    @apply inline-flex items-center px-2.5 py-0.5 rounded-full
           text-xs font-medium;
  }
  .badge-success {
    @apply badge bg-green-100 text-green-800;
  }
  .badge-warning {
    @apply badge bg-yellow-100 text-yellow-800;
  }
}
<div class="card">
  <h2>Estado del pedido</h2>
  <p class="mt-2 text-gray-600">Pedido procesado correctamente.</p>
  <span class="badge-success mt-3">Completado</span>
</div>

Los estilos en @layer components pueden ser sobreescritos por clases de utilidad en el HTML. Esto permite usar .card como base y personalizar casos específicos: <div class="card p-10">.

La directiva @utility

Tailwind CSS 4 introduce la directiva @utility para crear utilidades personalizadas que se integran completamente con el sistema de variantes. A diferencia de @apply dentro de @layer utilities, las utilidades creadas con @utility soportan variantes como hover:, focus:, md: de forma automática.

Utilidades estaticas

Una utilidad estática define un conjunto fijo de propiedades CSS bajo un nombre de clase:

@import "tailwindcss";

@utility content-auto {
  content-visibility: auto;
}

@utility scrollbar-hidden {
  scrollbar-width: none;
  -ms-overflow-style: none;
}

@utility text-balance {
  text-wrap: balance;
}
<h1 class="text-balance text-4xl font-bold">
  Un título largo que se distribuye de forma equilibrada entre líneas
</h1>
<div class="scrollbar-hidden overflow-y-auto h-96">
  <!-- Contenido con scroll sin barra visible -->
</div>

Estas utilidades funcionan con todas las variantes de Tailwind: md:content-auto, hover:scrollbar-hidden.

Utilidades funcionales

Las utilidades funcionales generan valores dinámicos basados en el nombre de la clase. Se definen con un comodín * y la función --value():

@utility tab-* {
  tab-size: --value(integer);
}

@utility gutter-* {
  padding-inline: --value(--spacing);
}

Con esta definición, las clases tab-2, tab-4, tab-8 quedan disponibles. La utilidad gutter-* toma valores del namespace --spacing del tema, habilitando clases como gutter-4, gutter-8.

Creacion de plugins con @plugin

La directiva @plugin carga un archivo JavaScript que extiende Tailwind CSS con nuevas utilidades, variantes o estilos base. Los plugins se registran directamente desde el CSS:

@import "tailwindcss";

@plugin "./plugins/custom-forms.js";

El archivo del plugin exporta una función que recibe la API de Tailwind con métodos como addComponents, addUtilities y matchUtilities:

// plugins/text-shadow.js
export default function ({ matchUtilities }) {
  matchUtilities(
    {
      'text-shadow': (value) => ({ textShadow: value }),
    },
    {
      values: {
        sm: '0 1px 2px rgba(0, 0, 0, 0.15)',
        DEFAULT: '0 2px 4px rgba(0, 0, 0, 0.15)',
        lg: '0 4px 8px rgba(0, 0, 0, 0.2)',
        none: 'none',
      },
    }
  );
}
<h1 class="text-shadow-lg text-4xl font-bold text-white">
  Título con sombra de texto
</h1>

Ejemplo práctico: sistema de botones

Un sistema de botones utilizando @layer components con @apply:

@import "tailwindcss";

@layer components {
  .btn {
    @apply inline-flex items-center justify-center gap-2
           px-4 py-2 rounded-lg font-medium text-sm transition-all
           focus-visible:outline-2 focus-visible:outline-offset-2
           disabled:opacity-50 disabled:cursor-not-allowed;
  }
  .btn-primary {
    @apply btn bg-blue-600 text-white hover:bg-blue-700
           focus-visible:outline-blue-600;
  }
  .btn-outline {
    @apply btn border-2 border-gray-300 text-gray-700
           hover:bg-gray-50 active:bg-gray-100;
  }
}
<div class="flex gap-3">
  <button class="btn-primary">Guardar</button>
  <button class="btn-outline">Cancelar</button>
  <button class="btn-primary" disabled>Deshabilitado</button>
</div>

Ejemplo práctico: tarjetas con @utility

Este ejemplo combina @layer components para la estructura de la tarjeta con @utility para una utilidad personalizada:

@import "tailwindcss";

@utility line-clamp-* {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: --value(integer);
  overflow: hidden;
}

@layer components {
  .card {
    @apply bg-white rounded-xl shadow-md overflow-hidden
           transition-shadow duration-200 hover:shadow-lg;
  }
  .card-body { @apply p-5; }
  .card-title { @apply text-lg font-semibold text-gray-900; }
}
<article class="card">
  <img src="imagen.jpg" alt="Artículo" class="w-full h-48 object-cover">
  <div class="card-body">
    <h3 class="card-title">Título del artículo</h3>
    <p class="text-sm text-gray-600 mt-2 line-clamp-3">
      Descripción larga que se trunca automáticamente a tres líneas
      gracias a la utilidad personalizada line-clamp.
    </p>
  </div>
</article>

La utilidad line-clamp-3 creada con @utility funciona con variantes como md:line-clamp-4, integrándose de forma natural con el sistema de Tailwind CSS.

Alan Sastre - Autor del tutorial

Alan Sastre

Ingeniero de Software y formador, CEO en CertiDevs

Ingeniero de software especializado en Full Stack y en Inteligencia Artificial. Como CEO de CertiDevs, Tailwind CSS es una de sus áreas de expertise. Con más de 15 años programando, 6K seguidores en LinkedIn y experiencia como formador, Alan se dedica a crear contenido educativo de calidad para desarrolladores de todos los niveles.

Más tutoriales de Tailwind CSS

Explora más contenido relacionado con Tailwind CSS y continúa aprendiendo con nuestros tutoriales gratuitos.

Aprendizajes de esta lección

  • Utilizar la directiva @apply para crear clases de componentes reutilizables
  • Organizar estilos personalizados en las capas base, components y utilities con @layer
  • Crear utilidades estáticas y funcionales con la directiva @utility
  • Extender Tailwind CSS con plugins mediante la directiva @plugin

Cursos que incluyen esta lección

Esta lección forma parte de los siguientes cursos estructurados con rutas de aprendizaje