Conceptos básicos
Mejores prácticas para agregar tus propios estilos personalizados en proyectos de Tailwind.
A menudo, el mayor desafío al trabajar con un framework es descubrir qué se supone que debes hacer cuando hay algo que necesitas que el framework no maneja por ti.
Tailwind ha sido diseñado desde cero para ser extensible y personalizable, de modo que no importa lo que estés construyendo, nunca sientas que estás luchando contra el framework.
Esta guía cubre temas como la personalización de tus tokens de diseño, cómo salir de esas restricciones cuando sea necesario, agregar tu propio CSS personalizado y extender el framework con plugins.
Si deseas cambiar cosas como tu paleta de colores, escala de espaciado, escala de tipografía o breakpoints, agrega tus personalizaciones usando la directiva @theme
en tu CSS:
@theme { --font-display: "Satoshi", "sans-serif"; --breakpoint-3xl: 120rem; --color-avocado-100: oklch(0.99 0 0); --color-avocado-200: oklch(0.98 0.04 113.22); --color-avocado-300: oklch(0.94 0.11 115.03); --color-avocado-400: oklch(0.92 0.19 114.08); --color-avocado-500: oklch(0.84 0.18 117.33); --color-avocado-600: oklch(0.53 0.12 118.34); --ease-fluid: cubic-bezier(0.3, 0, 0, 1); --ease-snappy: cubic-bezier(0.2, 0, 0, 1); /* ... */}
Obtén más información sobre cómo personalizar tu tema en la documentación de variables de tema.
Si bien generalmente puedes construir la mayor parte de un diseño bien elaborado utilizando un conjunto restringido de tokens de diseño, de vez en cuando necesitas salir de esas restricciones para que las cosas queden perfectas al píxel.
Cuando realmente necesites algo como top: 117px
para colocar una imagen de fondo en el lugar exacto, usa la notación de corchetes de Tailwind para generar una clase sobre la marcha con cualquier valor arbitrario:
<div class="top-[117px]"> <!-- ... --></div>
Esto es básicamente como estilos en línea, con el gran beneficio de que puedes combinarlo con modificadores interactivos como hover
y modificadores responsive como lg
:
<div class="top-[117px] lg:top-[344px]"> <!-- ... --></div>
Esto funciona para todo en el framework, incluidas cosas como colores de fondo, tamaños de fuente, contenido de pseudo-elementos y más:
<div class="bg-[#bada55] text-[22px] before:content-['Festivus']"> <!-- ... --></div>
Si estás haciendo referencia a una variable CSS como un valor arbitrario, puedes usar la sintaxis de propiedad personalizada:
<div class="fill-(--my-brand-color) ..."> <!-- ... --></div>
Esto es solo un atajo para fill-[var(--my-brand-color)]
que agrega la función var()
automáticamente.
Si alguna vez necesitas usar una propiedad CSS para la que Tailwind no incluye una utilidad lista para usar, también puedes usar la notación de corchetes para escribir CSS completamente arbitrario:
<div class="[mask-type:luminance]"> <!-- ... --></div>
Esto es realmente como estilos en línea, pero nuevamente con el beneficio de que puedes usar modificadores:
<div class="[mask-type:luminance] hover:[mask-type:alpha]"> <!-- ... --></div>
Esto también puede ser útil para cosas como variables CSS, especialmente cuando necesitan cambiar bajo diferentes condiciones:
<div class="[--scroll-offset:56px] lg:[--scroll-offset:44px]"> <!-- ... --></div>
Las variantes arbitrarias son como valores arbitrarios pero para hacer modificaciones de selector sobre la marcha, como puedes hacer con variantes de pseudo-clases incorporadas como hover:{utility}
o variantes responsive como md:{utility}
pero usando la notación de corchetes directamente en tu HTML.
<ul role="list"> {#each items as item} <li class="lg:[&:nth-child(-n+3)]:hover:underline">{item}</li> {/each}</ul>
Obtén más información en la documentación de variantes arbitrarias.
Cuando un valor arbitrario necesita contener un espacio, usa un guion bajo (_
) en su lugar y Tailwind lo convertirá automáticamente en un espacio en tiempo de compilación:
<div class="grid grid-cols-[1fr_500px_2fr]"> <!-- ... --></div>
En situaciones donde los guiones bajos son comunes pero los espacios no son válidos, Tailwind preservará el guion bajo en lugar de convertirlo en un espacio, por ejemplo, en URLs:
<div class="bg-[url('/what_a_rush.png')]"> <!-- ... --></div>
En el raro caso de que realmente necesites usar un guion bajo pero sea ambiguo porque un espacio también es válido, escapa el guion bajo con una barra invertida y Tailwind no lo convertirá en un espacio:
<div class="before:content-['hello\_world']"> <!-- ... --></div>
Si estás usando algo como JSX donde la barra invertida se elimina del HTML renderizado, usa String.raw() para que la barra invertida no se trate como un carácter de escape de JavaScript:
<div className={String.raw`before:content-['hello\_world']`}> <!-- ... --></div>
Muchas utilidades en Tailwind comparten un espacio de nombres común pero se asignan a diferentes propiedades CSS. Por ejemplo, text-lg
y text-black
comparten el espacio de nombres text-
, pero uno es para font-size
y el otro es para color
.
Al usar valores arbitrarios, Tailwind generalmente puede manejar esta ambigüedad automáticamente basándose en el valor que le pases:
<!-- Generará una utilidad de font-size --><div class="text-[22px]">...</div><!-- Generará una utilidad de color --><div class="text-[#bada55]">...</div>
Sin embargo, a veces es realmente ambiguo, por ejemplo, al usar variables CSS:
<div class="text-(--my-var)">...</div>
En estas situaciones, puedes "sugerir" el tipo subyacente a Tailwind agregando un tipo de datos CSS antes del valor:
<!-- Generará una utilidad de font-size --><div class="text-(length:--my-var)">...</div><!-- Generará una utilidad de color --><div class="text-(color:--my-var)">...</div>
Si bien Tailwind está diseñado para manejar la mayor parte de tus necesidades de estilo, no hay nada que te impida simplemente escribir CSS plano cuando lo necesites:
@import "tailwindcss";.my-custom-style { /* ... */}
Si solo quieres establecer algunos valores predeterminados para la página (como el color del texto, el color de fondo o la familia de fuentes), la opción más fácil es simplemente agregar algunas clases a los elementos html
o body
:
<!doctype html><html lang="en" class="bg-gray-100 font-serif text-gray-900"> <!-- ... --></html>
Esto mantiene tus decisiones de estilo base en tu marcado junto con todos tus otros estilos, en lugar de ocultarlas en un archivo separado.
Si deseas agregar tus propios estilos base predeterminados para elementos HTML específicos, usa la directiva @layer
para agregar esos estilos a la capa base
de Tailwind:
@layer base { h1 { font-size: var(--text-2xl); } h2 { font-size: var(--text-xl); }}
Usa la capa components
para cualquier clase más complicada que quieras agregar a tu proyecto y que aún quieras poder sobrescribir con clases de utilidad.
Tradicionalmente, estas serían clases como card
, btn
, badge
, ese tipo de cosas.
@layer components { .card { background-color: var(--color-white); border-radius: var(--rounded-lg); padding: var(--spacing-6); box-shadow: var(--shadow-xl); }}
Al definir clases de componentes en la capa components
, aún puedes usar clases de utilidad para sobrescribirlas cuando sea necesario:
<!-- Se verá como una tarjeta, pero con esquinas cuadradas --><div class="card rounded-none"> <!-- ... --></div>
Usando Tailwind, probablemente no necesites este tipo de clases tan a menudo como crees. Lee nuestra guía sobre gestión de la duplicación para nuestras recomendaciones.
La capa components
también es un buen lugar para poner estilos personalizados para cualquier componente de terceros que estés usando:
@layer components { .select2-dropdown { /* ... */ }}
Usa la directiva @variant
para aplicar una variante de Tailwind dentro de CSS personalizado:
.my-element { background: white; @variant dark { background: black; }}
.my-element { background: white; @media (prefers-color-scheme: dark) { background: black; }}
Si necesitas aplicar múltiples variantes al mismo tiempo, usa anidamiento:
.my-element { background: white; @variant dark { @variant hover { background: black; } }}
.my-element { background: white; @media (prefers-color-scheme: dark) { &:hover { @media (hover: hover) { background: black; } } }}
Además de usar las utilidades que vienen con Tailwind, también puedes agregar tus propias utilidades personalizadas. Esto puede ser útil cuando hay una característica de CSS que te gustaría usar en tu proyecto para la cual Tailwind no incluye utilidades listas para usar.
Usa la directiva @utility
para agregar una utilidad personalizada a tu proyecto:
@utility content-auto { content-visibility: auto;}
Puedes usar esta utilidad en tu HTML ahora:
<div class="content-auto"> <!-- ... --></div>
También funcionará con variantes como hover
, focus
y lg
:
<div class="hover:content-auto"> <!-- ... --></div>
Las utilidades personalizadas se insertan automáticamente en la capa utilities
junto con todas las utilidades incorporadas en el framework.
Si tu utilidad personalizada es más compleja que un solo nombre de clase, usa anidamiento para definir la utilidad:
@utility scrollbar-hidden { &::-webkit-scrollbar { display: none; }}
Además de registrar utilidades simples con la directiva @utility
, también puedes registrar utilidades funcionales que aceptan un argumento:
@utility tab-* { tab-size: --value(--tab-size-*);}
La función especial --value()
se utiliza para resolver el valor de la utilidad.
Usa la sintaxis --value(--theme-key-*)
para resolver el valor de la utilidad contra un conjunto de claves del tema:
@theme { --tab-size-2: 2; --tab-size-4: 4; --tab-size-github: 8;}@utility tab-* { tab-size: --value(--tab-size-*);}
Esto coincidirá con utilidades como tab-2
, tab-4
y tab-github
.
Para resolver el valor como un valor básico, usa la sintaxis --value({type})
, donde {type}
es el tipo de datos con el que deseas validar el valor básico:
@utility tab-* { tab-size: --value(integer);}
Esto coincidirá con utilidades como tab-1
y tab-76
.
Para admitir valores literales, usa la sintaxis --value('literal')
(observa las comillas):
@utility tab-* { tab-size: --value('inherit', 'initial', 'unset');}
Esto coincidirá con utilidades como tab-inherit
, tab-initial
y tab-unset
.
Para admitir valores arbitrarios, usa la sintaxis --value([{type}])
(observa los corchetes) para indicarle a Tailwind qué tipos son compatibles como valor arbitrario:
@utility tab-* { tab-size: --value([integer]);}
Esto coincidirá con utilidades como tab-[1]
y tab-[76]
. Si deseas admitir cualquier tipo de datos, puedes usar --value([*])
.
Las tres formas de la función --value()
se pueden usar dentro de una regla como múltiples declaraciones, y cualquier declaración que no se resuelva se omitirá en la salida:
@theme { --tab-size-github: 8;}@utility tab-* { tab-size: --value([integer]); tab-size: --value(integer); tab-size: --value(--tab-size-*);}
Esto permite tratar el valor de manera diferente en cada caso si es necesario, por ejemplo, traduciendo un entero básico a un porcentaje:
@utility opacity-* { opacity: --value([percentage]); opacity: calc(--value(integer) * 1%); opacity: --value(--opacity-*);}
La función --value()
también puede tomar múltiples argumentos y resolverlos de izquierda a derecha si no necesitas tratar el valor de retorno de manera diferente en distintos casos:
@theme { --tab-size-github: 8;}@utility tab-* { tab-size: --value(--tab-size-*, integer, [integer]);}@utility opacity-* { opacity: calc(--value(integer) * 1%); opacity: --value(--opacity-*, [percentage]);}
Para admitir valores negativos, registra utilidades positivas y negativas separadas en declaraciones distintas:
@utility inset-* { inset: calc(var(--spacing) * --value([percentage], [length]));}@utility -inset-* { inset: calc(var(--spacing) * --value([percentage], [length]) * -1);}
Los modificadores se manejan usando la función --modifier()
, que funciona exactamente igual que la función --value()
pero opera sobre un modificador si está presente:
@utility text-* { font-size: --value(--text-*, [length]); line-height: --modifier(--leading-*, [length], [*]);}
Si no hay un modificador presente, cualquier declaración que dependa de un modificador simplemente no se incluye en la salida.
Para manejar fracciones, dependemos del tipo de datos CSS ratio
. Si se usa con --value()
, es una señal para Tailwind para tratar el valor y el modificador como un solo valor:
@utility aspect-* { aspect-ratio: --value(--aspect-ratio-*, ratio, [ratio]);}
Esto coincidirá con utilidades como aspect-square
, aspect-3/4
y aspect-[7/9]
.
Además de usar las variantes que vienen con Tailwind, también puedes agregar tus propias variantes personalizadas usando la directiva @custom-variant
:
@custom-variant theme-midnight { &:where([data-theme="midnight"] *) { @slot; }}
Ahora puedes usar la variante theme-midnight:<utility>
en tu HTML:
<html data-theme="midnight"> <button class="theme-midnight:bg-black ..."></button></html>
Puedes crear variantes usando la sintaxis abreviada cuando no se requiere anidamiento:
@custom-variant theme-midnight (&:where([data-theme="midnight"] *));
Cuando una variante personalizada tiene múltiples reglas, se pueden anidar una dentro de la otra:
@custom-variant any-hover { @media (any-hover: hover) { &:hover { @slot; } }}