Not Using Layers
Using layers in TailwindCSS is crucial for creating new utilities and component classes.
Layers in TailwindCSS are a powerful and often underutilized feature. Layers allow you to create custom utilities and component classes in a structured way, enhancing reusability and maintainability. This tip explains the purpose of layers, why they matter, and how to use them effectively in your TailwindCSS projects.
What Are Layers?
Layers in TailwindCSS are a way to organize and define custom styles in your CSS. TailwindCSS provides three layers for organizing your styles:
- Base: For global styles and resetting default browser styles.
- Components: For reusable component classes like buttons and cards.
- Utilities: For custom utility classes, extending Tailwind’s core utilities.
Using these layers ensures your custom styles integrate seamlessly with Tailwind’s utility-first approach while maintaining consistency and clarity in your project.
Why Use Layers?
- Work with Variants: Classes inside
@layer components
and@layer utilities
directives can use all Tailwind variants, like responsive (lg
), dark mode (dark
), and state-based (hover
,focus
). - Better Organization: By separating base styles, component styles, and utility classes, layers make your CSS more organized and maintainable.
How to Use Layers?
Base Layer
The base layer is used for defining global styles, such as resetting browser defaults or adding custom root styles.
@layer base {
:root {
color : var(--color-gray-600)
}
h1 {
@apply text-3xl font-bold;
}
p {
@apply text-base text-gray-600;
}
}
Components Layer
The components layer is ideal for creating reusable components like buttons, cards, or modals.
@layer components {
.btn {
@apply px-4 py-2 rounded-lg text-white bg-blue-500 hover:bg-blue-600;
}
.card {
@apply shadow-lg rounded-md p-6 bg-white;
}
}
These classes can now be used in your HTML to create consistent, reusable components across your project.
Utilities Layer
The utilities layer is used for defining utility classes that extend Tailwind’s existing utilities.
@layer utilities {
.text-shadow {
text-shadow: 2px 2px #888;
}
.safe-area-padding {
padding: env(safe-area-inset);
}
}
These utilities can be directly applied to HTML elements like regular Tailwind utilities.
New in TailwindCSS v4: @utility
Directive
TailwindCSS v4 introduces the @utility
directive, which simplifies the process of creating custom utilities.
@utility tls-shadow-md {
box-shadow:
0 0 0 1px var(--ui-border-color),
0 1px 1px -0.25px var(--tw-shadow-color),
0 2px 2px -0.5px var(--tw-shadow-color),
0 4px 4px -1px var(--tw-shadow-color),
0 8px 8px -2px var(--tw-shadow-color),
0 16px 16px -4px var(--tw-shadow-color);
}
This directive automatically places the custom utility in the appropriate layer, making it faster and easier to define new utilities.
Real-World Example
Here’s a the css code of Tailus UI HTML, a TailwindCSS UI library, that demonstrates the use of layers:
@import 'tailwindcss';
@theme {
--font-display : 'Geist', 'Inter', sans-serif;
--font-body : 'Geist', 'Inter', sans-serif;
--font-mono : 'Geist Mono', 'Fira Code', monospace;
--color-gray-50: var(--color-zinc-50);
--color-gray-100: var(--color-zinc-100);
--color-gray-200: var(--color-zinc-200);
--color-gray-300: var(--color-zinc-300);
--color-gray-400: var(--color-zinc-400);
--color-gray-500: var(--color-zinc-500);
--color-gray-600: var(--color-zinc-600);
--color-gray-700: var(--color-zinc-700);
--color-gray-800: var(--color-zinc-800);
--color-gray-900: var(--color-zinc-900);
--color-gray-950: var(--color-zinc-950);
--color-primary-50: var(--color-orange-50);
--color-primary-100: var(--color-orange-100);
--color-primary-200: var(--color-orange-200);
--color-primary-300: var(--color-orange-300);
--color-primary-400: var(--color-orange-400);
--color-primary-500: var(--color-orange-500);
--color-primary-600: var(--color-orange-600);
--color-primary-700: var(--color-orange-700);
--color-primary-800: var(--color-orange-800);
--color-primary-900: var(--color-orange-900);
--color-primary-925: var(--color-orange-950);
--color-primary-950: var(--color-orange-950);
--color-success-50: var(--color-lime-50);
--color-success-100: var(--color-lime-100);
--color-success-200: var(--color-lime-200);
--color-success-300: var(--color-lime-300);
--color-success-400: var(--color-lime-400);
--color-success-500: var(--color-lime-500);
--color-success-600: var(--color-lime-600);
--color-success-700: var(--color-lime-700);
--color-success-800: var(--color-lime-800);
--color-success-900: var(--color-lime-900);
--color-success-950: var(--color-lime-950);
--color-danger-50: var(--color-red-50);
--color-danger-100: var(--color-red-100);
--color-danger-200: var(--color-red-200);
--color-danger-300: var(--color-red-300);
--color-danger-400: var(--color-red-400);
--color-danger-500: var(--color-red-500);
--color-danger-600: var(--color-red-600);
--color-danger-700: var(--color-red-700);
--color-danger-800: var(--color-red-800);
--color-danger-900: var(--color-red-900);
--color-danger-950: var(--color-red-950);
--color-info-50: var(--color-blue-50);
--color-info-100: var(--color-blue-100);
--color-info-200: var(--color-blue-200);
--color-info-300: var(--color-blue-300);
--color-info-400: var(--color-blue-400);
--color-info-500: var(--color-blue-500);
--color-info-600: var(--color-blue-600);
--color-info-700: var(--color-blue-700);
--color-info-800: var(--color-blue-800);
--color-info-900: var(--color-blue-900);
--color-info-950: var(--color-blue-950);
--color-warning-50: var(--color-amber-50);
--color-warning-100: var(--color-amber-100);
--color-warning-200: var(--color-amber-200);
--color-warning-300: var(--color-amber-300);
--color-warning-400: var(--color-amber-400);
--color-warning-500: var(--color-amber-500);
--color-warning-600: var(--color-amber-600);
--color-warning-700: var(--color-amber-700);
--color-warning-800: var(--color-amber-800);
--color-warning-900: var(--color-amber-900);
--color-warning-950: var(--color-amber-950);
}
@layer base {
*,
::after,
::before,
::backdrop,
::file-selector-button {
border-color: var(--ui-border-color, currentColor);
}
:root {
/* Border Radius */
--card-radius: var(--radius-lg);
--btn-radius: var(--card-radius);
--badge-radius: var(--btn-radius);
--input-radius: var(--btn-radius);
--avatar-radius: var(--radius-3xl);
--annonce-radius: var(--avatar-radius);
/* Border Color */
--ui-border-color: var(--color-gray-200);
--btn-border: var(--color-gray-200);
--badge-border: var(--btn-border);
--input-border: var(--ui-border-color);
--ui-disabled-border: var(--color-gray-100);
--ui-error-border: var(--color-danger-600);
--ui-success-border: var(--color-success-600);
--input-outline: var(--color-primary-600);
/* Background */
--ui-bg: var(--color-white);
--ui-soft-bg: var(--color-gray-100);
--overlay-bg: var(--color-gray-950);
--input-bg: var(--ui-soft-bg);
--ui-disabled-bg: var(--color-gray-100);
/* Padding */
--card-padding: theme("spacing.6");
/* Typography */
--display-text-color: var(--color-gray-950);
--title-text-color: var(--display-text-color);
--body-text-color: var(--colors-gray-600);
--caption-text-color: var(--colors-gray-500);
--placeholder-text-color: var(--colors-gray-400);
/* Opacity */
--ui-bg-opacity: 1;
/* Btn */
--btn-color: var(--color-white);
--btn-bg-from: var(--color-primary-500);
--btn-bg-to: var(--color-primary-600);
--btn-border: var(--color-primary-700);
color: var(--body-text-color);
@apply dark:[--body-text-color:var(--color-gray-400)] dark:[--display-text-color:var(--color-white)] dark:[--placeholder-text-color:var(--colors-gray-600)] dark:[--ui-bg:var(--color-gray-900)] dark:[--ui-border-color:var(--color-gray-800)] dark:[--ui-disabled-bg:var(--color-gray-900)] dark:[--ui-soft-bg:var(--color-gray-800)];
}
button:disabled {
border: none;
background: var(--ui-disabled-bg);
background-image: none !important;
box-shadow: none;
color: var(--placeholder-text-color);
pointer-events: none;
@apply before:hidden;
}
a:focus-visible,
button:focus-visible {
@apply outline-2 outline-offset-2 outline-primary-600 focus-visible:outline;
}
input:user-invalid,
textarea:user-invalid,
select:user-invalid {
--input-border: var(--ui-error-border);
--ui-border-color: var(--ui-error-border);
--input-outline: var(--ui-error-border);
--title-text-color: var(--color-danger-600);
@apply dark:[--title-text-color:var(--colors-danger-400)];
}
/* Data attributes */
/* Rounded Data attributes */
[data-rounded="none"] {
--card-radius: var(--radius-none);
--avatar-radius: var(--radius-none);
}
[data-rounded="default"] {
--card-radius: var(--radius-default);
}
[data-rounded="small"] {
--card-radius: var(--radius-sm);
}
[data-rounded="medium"] {
--card-radius: var(--radius-md);
}
[data-rounded="large"] {
--card-radius: var(--radius-lg);
}
[data-rounded="xlarge"] {
--card-radius: var(--radius-xl);
}
[data-rounded="2xlarge"] {
--card-radius: var(--radius-2xl);
--input-radius: var(--radius-xl);
}
[data-rounded="3xlarge"] {
--card-radius: var(--radius-3xl);
--input-radius: var(--radius-xl);
}
[data-rounded="full"] {
--card-radius: var(--radius-3xl);
--btn-radius: var(--radius-3xl);
--input-radius: var(--radius-3xl);
}
/* Shade Data Attributes */
[data-shade="800"] {
@apply dark:[--ui-bg:var(--color-gray-800)] dark:[--ui-border-color:var(--color-gray-700)] dark:[--ui-soft-bg:var(--color-gray-900)];
}
[data-shade="900"] {
@apply dark:[--ui-bg:var(--color-gray-900)] dark:[--ui-border-color:var(--color-gray-800)] dark:[--ui-soft-bg:var(--color-gray-800)];
}
[data-shade="950"] {
@apply dark:[--ui-bg:var(--color-gray-950)] dark:[--ui-border-color:var(--color-gray-800)] dark:[--ui-soft-bg:var(--color-gray-800)];
}
[data-theme="dark"]{
--ui-border-color: var(--color-gray-800);
--input-border: var(--ui-border-color);
--ui-disabled-bg: var(--color-gray-900);
--ui-bg: var(--color-gray-950);
--ui-soft-bg: var(--color-gray-800);
--display-text-color: var(--color-white);
--title-text-color:var(--display-text-color);
--body-text-color:var(--color-gray-300);
--caption-text-color:var(--color-gray-500);
--placeholder-text-color:var(--color-gray-600);
--ui-shadow-border:var(--ui-border-color)
}
[data-theme="light"]{
--ui-border-color: var(--color-gray-200);
--input-border: var(--ui-border-color);
--ui-disabled-bg: var(--color-gray-100);
--ui-bg: var(--color-white);
--ui-soft-bg: var(--color-gray-200);
--display-text-color: var(--color-gray-950);
--title-text-color:var(--display-text-color);
--body-text-color:var(--color-gray-600);
--caption-text-color:var(--color-gray-500);
--placeholder-text-color:var(--color-gray-400);
--ui-shadow-border:var(--ui-border-color);
}
[data-theme="inverted"]{
--ui-border-color: var(--color-gray-800);
--input-border: var(--ui-border-color);
--ui-disabled-bg: var(--color-gray-900);
--ui-bg: var(--color-gray-950);
--ui-soft-bg: var(--color-gray-800);
--display-text-color: var(--color-white);
--title-text-color:var(--display-text-color);
--body-text-color:var(--color-gray-300);
--caption-text-color:var(--color-gray-500);
--placeholder-text-color:var(--color-gray-600);
--ui-shadow-border:var(--ui-border-color)
@apply dark:[--ui-border-color:var(--color-gray-200)] dark:[--ui-disabled-bg:var(--color-gray-100)] dark:[--ui-bg:var(--color-white)] dark:[--ui-soft-bg:var(--color-gray-200')] dark:[--display-text-color:var(--color-gray-950')] dark:[--body-text-color:var(--color-gray-700)] dark:[--placeholder-text-color:var(--color-gray-400)]
}
}
@utility avatar-mask {
-webkit-mask-image: url('/avatar-mask.svg');
mask-image: url('/avatar-mask.svg');
mask-size: cover;
-webkit-mask-size: cover;
mask-repeat: no-repeat;
-webkit-mask-repeat: no-repeat;
-webkit-mask-position: center;
mask-position: center;
}
@utility avatar-mask-none {
-webkit-mask-image: none;
mask-image: none;
}
/* Typography */
@utility text-display {
color: var(--display-text-color);
}
@utility text-title {
color: var(--title-text-color);
}
@utility text-body {
color: var(--body-text-color);
}
@utility text-caption {
color: var(--caption-text-color);
}
@utility text-placeholder {
color: var(--placeholder-text-color);
}
/* Border Radius */
@utility rounded-card {
border-radius: var(--card-radius);
}
@utility rounded-btn {
border-radius: var(--btn-radius);
}
@utility rounded-badge {
border-radius: var(--badge-radius);
}
@utility rounded-annonce {
border-radius: var(--annonce-radius);
}
@utility rounded-input {
border-radius: var(--input-radius);
}
@utility rounded-avatar {
border-radius: var(--avatar-radius);
}
/* Background */
@utility bg-ui {
background: var(--ui-bg);
}
@utility bg-ui-soft {
background: var(--ui-soft-bg);
}
@utility bg-overlay {
background: var(--overlay-bg);
}
@utility p-card {
padding: var(--card-padding);
}
.tls-shadow,
.tls-shadow-md,
.tls-shadow-lg {
--tw-shadow-color: theme(colors.gray.950/0.05);
}
/* Shadow */
@utility tls-shadow {
box-shadow:
0 0 0 1px var(--ui-border-color),
0 0.5px 0.5px -0.125px var(--tw-shadow-color),
0 1px 1px -0.5px var(--tw-shadow-color),
0 2px 2px -1px var(--tw-shadow-color),
0 4px 4px -2px var(--tw-shadow-color),
0 8px 8px -4px var(--tw-shadow-color);
}
@utility tls-shadow-md {
box-shadow:
0 0 0 1px var(--ui-border-color),
0 1px 1px -0.25px var(--tw-shadow-color),
0 2px 2px -0.5px var(--tw-shadow-color),
0 4px 4px -1px var(--tw-shadow-color),
0 8px 8px -2px var(--tw-shadow-color),
0 16px 16px -4px var(--tw-shadow-color);
}
@utility tls-shadow-lg {
box-shadow:
0 0 0 1px var(--ui-border-color),
0 2px 2px -0.5px var(--tw-shadow-color),
0 4px 4px -1px var(--tw-shadow-color),
0 8px 8px -2px var(--tw-shadow-color),
0 16px 16px -4px var(--tw-shadow-color),
0 32px 32px -8px var(--tw-shadow-color);
}
@layer components {
/* Typography */
.text-blockquote {
color: var(--body-text-color);
@apply border-l-2 pl-4 italic;
}
.text-quote {
color: var(--body-text-color);
@apply border-l-2 pl-4 italic;
}
/* Button */
.btn {
@apply flex items-center justify-center gap-2.5 rounded-btn *:relative;
&.variant-neutral,
&.variant-primary,
&.variant-destructive {
@apply text-(--btn-color) transition-[filter] duration-300 before:inset-0;
.btn-label {
@apply relative font-medium;
}
}
&.variant-neutral,
&.variant-primary,
&.variant-destructive,
&.variant-outlined {
@apply relative bg-linear-to-b shadow-sm before:absolute before:rounded-[calc(var(--btn-radius)-1px)] before:border-t;
}
&.variant-neutral,
&.variant-primary,
&.variant-destructive,
&.variant-soft {
@apply border;
}
&.variant-neutral {
@apply border-gray-800 from-gray-700 to-gray-900 shadow-gray-950/25 before:border-white/25 hover:brightness-125 active:brightness-75 dark:border-white dark:bg-white dark:from-transparent dark:to-transparent dark:text-gray-950 dark:shadow-gray-950/5 dark:hover:bg-white/75;
}
&.variant-primary {
@apply border-(--btn-border) from-(--btn-bg-from) to-(--btn-bg-to) shadow-primary-950/25 before:border-white/25 hover:brightness-110 active:brightness-95 dark:border-white/15 dark:from-(--btn-bg-to) dark:to-(--btn-bg-to) dark:shadow-primary-950/10 dark:before:border-transparent;
}
&.variant-destructive {
@apply border-danger-700 from-danger-500 to-danger-600 shadow-danger-950/25 before:border-white/25 hover:brightness-110 active:brightness-95 dark:border-white/15 dark:from-danger-600 dark:to-danger-600 dark:shadow-danger-950/10 dark:before:border-transparent;
}
&.variant-outlined {
@apply border-none from-gray-300/75 from-85% to-gray-400/50 text-gray-950 before:inset-px before:border-t before:border-white before:bg-white before:transition-[background,border-color] before:duration-300 hover:before:bg-gray-100 active:before:bg-gray-200 dark:from-transparent dark:to-transparent dark:text-white dark:before:inset-0 dark:before:border dark:before:border-white/10 dark:before:bg-white/5 dark:hover:before:bg-white/10 dark:active:before:bg-white/15;
}
&.variant-soft {
@apply border-transparent bg-gray-950/[0.07] text-body transition-[background,border-color] duration-300 hover:text-(--title-text-color) hover:border-gray-950/10 active:bg-gray-950/15 dark:bg-gray-500/15 dark:hover:border-white/10 dark:active:bg-gray-500/20;
}
&.variant-ghost {
@apply border-none bg-transparent text-body transition-[background] duration-300 hover:text-(--title-text-color) hover:bg-gray-950/[0.07] active:bg-gray-950/15 dark:hover:bg-gray-500/15 dark:active:bg-gray-500/20;
}
&.sz-xs {
@apply h-7 px-2.5 text-sm;
}
&.sz-sm {
@apply h-8 px-3 text-sm;
}
&.sz-md {
@apply h-9 px-3.5 text-sm;
}
&.sz-lg {
@apply h-10 px-4 text-base;
}
&.sz-xl {
@apply h-12 px-6 text-lg;
}
&.icon-only {
@apply px-0;
&.sz-xs {
@apply size-7;
}
&.sz-sm {
@apply size-8;
}
&.sz-md {
@apply size-9;
}
&.sz-lg {
@apply size-10;
}
&.sz-xl {
@apply size-12;
}
}
}
/* Badge */
.badge {
@apply flex size-fit items-center gap-1.5 rounded-badge border;
&.variant-neutral {
@apply border-gray-500/15 bg-gray-500/10 text-(--body-text-color) dark:border-gray-500/20 dark:bg-gray-500/15;
}
&.variant-info {
@apply border-info-500/15 bg-info-500/15 text-info-700 dark:border-info-500/20 dark:text-info-300;
}
&.variant-success {
@apply border-success-500/25 bg-success-500/15 text-success-800 dark:border-success-500/15 dark:text-success-300;
}
&.variant-warning {
@apply border-warning-500/25 bg-warning-500/15 text-warning-800 dark:border-warning-500/15 dark:text-warning-200;
}
&.variant-danger {
@apply border-danger-500/15 bg-danger-500/15 text-danger-700 dark:text-danger-300;
}
&.variant-urgent {
@apply border-danger-600 bg-danger-600 text-white;
}
&.sz-xs {
@apply px-1.5 py-0.5 text-xs;
}
&.sz-sm {
@apply px-2 py-0.5 text-sm;
}
&.sz-md {
@apply px-2.5 py-0.5 text-sm;
}
&.sz-lg {
@apply px-2.5 py-0.5 text-base;
}
}
/* Form field, input and textarea */
.field {
@apply relative space-y-2.5 has-disabled:*:pointer-events-none has-disabled:*:opacity-50 has-[:user-invalid]:[--caption-text-color:var(--color-danger-600)] dark:has-[:user-invalid]:[--caption-text-color:var(--color-danger-400)];
label {
display: block;
}
}
.input,
.textarea {
@apply outline-none text-title w-full rounded-input text-placeholder focus:border-transparent;
&.variant-outlined {
@apply border border-(--ui-border-color) bg-transparent ring-offset-[-1px] focus:ring-2 focus:ring-(--input-outline);
}
&.variant-mixed {
@apply border border-(--ui-border-color) shadow-sm shadow-gray-950/5 bg-ui focus:ring-2 focus:ring-(--input-outline) dark:shadow-gray-950/35;
}
&.variant-soft {
@apply border-none bg-ui-soft outline-hidden focus:brightness-95 dark:focus:brightness-105;
}
&.variant-plain {
@apply rounded-none border-none bg-transparent outline-hidden;
}
&.variant-bottomOutlined {
border-left: none;
border-right: none;
border-top: none;
@apply rounded-none border-b border-(--input-border) bg-transparent focus:border-b-2 focus:border-(--input-outline) focus:outline-hidden;
}
&.sz-sm {
@apply h-8 text-sm;
}
&.sz-md {
@apply h-9 text-sm;
}
&.sz-lg {
@apply h-10;
}
&.sz-xl {
@apply h-12;
}
&.variant-mixed.sz-sm,
&.variant-outlined.sz-sm,
&.variant-soft.sz-sm {
@apply px-2.5;
}
&.variant-mixed.sz-md,
&.variant-outlined.sz-md,
&.variant-soft.sz-md {
@apply px-3;
}
&.variant-mixed.sz-lg,
&.variant-outlined.sz-lg,
&.variant-soft.sz-lg {
@apply px-4;
}
&.variant-mixed.sz-xl,
&.variant-outlined.sz-xl,
&.variant-soft.sz-xl {
@apply px-5;
}
}
.textarea {
&.sz-sm {
@apply py-1.5 text-sm;
}
&.sz-md {
@apply py-2 text-sm;
}
&.sz-lg {
@apply py-3;
}
&.sz-xl {
@apply py-4;
}
}
.switch {
@apply relative block h-5 w-8 rounded-full border transition duration-300 bg-ui-soft has-checked:border-(--btn-border) dark:has-checked:border-white/5 dark:bg-ui;
.switch-thumb {
@apply absolute inset-x-[1px] inset-y-0 my-auto size-4 rounded-full bg-white shadow-sm shadow-gray-950/25 transition-[translate,width] duration-300 ease-in-out peer-checked:translate-x-3 peer-checked:bg-(--btn-color);
&.variant-neutral {
@apply absolute inset-x-[1px] inset-y-0 my-auto size-4 rounded-full bg-white shadow-sm shadow-gray-950/25 transition-[translate,width] duration-300 ease-in-out peer-checked:translate-x-3 dark:peer-checked:bg-gray-900;
}
}
&.variant-primary {
@apply has-checked:bg-(--btn-bg-to);
}
&.variant-neutral {
@apply has-checked:bg-gray-950 dark:has-checked:bg-white;
}
}
.checkbox,
.radio {
@apply relative block size-[1.125rem] rounded border border-gray-300 shadow-sm shadow-gray-950/5 transition duration-300 has-checked:border-(--btn-border) dark:has-checked:border-white/5 has-checked:bg-(--btn-bg-to) dark:border-(--ui-border-color) dark:bg-ui;
.checkbox-icon {
@apply absolute inset-0 m-auto size-3.5 scale-75 text-gray-950 opacity-0 transition duration-300 group-hover:opacity-25 peer-checked:scale-100 peer-checked:text-(--btn-color) peer-checked:opacity-100 dark:text-white;
}
.radio-indicator {
@apply absolute inset-0 m-auto size-2 scale-75 rounded-full bg-gray-950 opacity-0 transition duration-300 group-hover:opacity-25 peer-checked:scale-100 peer-checked:bg-(--btn-color) peer-checked:opacity-100 peer-checked:shadow-sm peer-checked:shadow-gray-950/25 dark:bg-white;
}
}
.checkbox,
.radio,
.switch {
@apply overflow-hidden has-focus-visible:outline-2 has-focus-visible:outline-offset-2 has-focus-visible:outline-primary-600;
}
.checkbox > input,
.radio > input,
.switch > input {
@apply absolute -left-6 size-2;
}
/* Card */
.card {
@apply rounded-card p-(--card-padding);
&.variant-outlined {
@apply border bg-ui;
}
&.variant-mixed {
@apply border shadow shadow-gray-950/5 bg-ui;
}
&.variant-soft {
@apply bg-ui-soft;
}
}
/* Kbd */
.kbd {
@apply inline-flex h-5 min-w-5 items-center justify-center rounded border-t border-b border-t-white border-b-gray-200 bg-gray-100 px-1.5 font-sans text-[11px] text-gray-800 ring-1 ring-gray-300 dark:border-t-transparent dark:border-b-gray-950 dark:bg-white/10 dark:text-white dark:ring-white/15;
}
/* Code */
.code {
@apply inline-block rounded-md px-1 py-px text-sm;
&.variant-primary {
@apply border border-primary-200 bg-primary-50 text-primary-600 dark:border-primary-500/20 dark:bg-primary-500/5 dark:text-primary-300;
}
&.variant-gray {
@apply text-body bg-ui-soft;
}
&.variant-neutral {
@apply border bg-gray-50 text-gray-950 dark:border-gray-500/20 dark:bg-gray-500/5 dark:text-white;
}
}
/* Link */
.link {
@apply text-primary-600 transition dark:text-primary-400;
}
.link.variant-ghost {
@apply hover:underline;
}
.link.variant-underlined {
@apply underline;
}
.link.variant-animated {
@apply relative before:absolute before:inset-x-0 before:bottom-0 before:h-px before:origin-right before:scale-x-0 before:transition before:duration-200 hover:before:origin-left hover:before:scale-x-100;
}
.link.intent-info {
@apply text-info-600 dark:text-info-400;
}
.link.intent-neutral {
@apply text-gray-950 dark:text-white;
}
.link.variant-animated.intent-neutral {
@apply before:bg-gray-950/50 dark:before:bg-white/50;
}
.link.variant-animated.intent-info {
@apply before:bg-info-300 dark:before:bg-info-600;
}
.link.variant-animated.intent-primary {
@apply before:bg-primary-300 dark:before:bg-primary-600;
}
.link.variant-underlined.intent-neutral,
.link.variant-ghost.intent-neutral {
@apply decoration-gray-950/50 dark:decoration-white/50;
}
/* Separator */
.separator {
@apply block h-px w-full bg-(--ui-border-color);
&separator.vertical {
@apply h-full w-px;
}
}
/* Annonce */
.annonce {
@apply flex w-fit items-center gap-3 rounded-annonce;
&.variant-outlined {
@apply border;
}
&.variant-soft {
@apply bg-ui-soft;
}
&.variant-mixed {
@apply border shadow-sm shadow-gray-950/5 bg-ui dark:shadow-gray-950/25;
}
&.sz-xs {
@apply py-0.5 pr-3 pl-0.5 [&>span]:rounded-[calc(var(--annonce-radius)-2px)];
}
&.sz-sm {
@apply py-1 pr-4 pl-1 [&>span]:rounded-[calc(var(--annonce-radius)-4px)];
}
&.sz-md {
@apply py-1.5 pr-5 pl-1.5 [&>span]:rounded-[calc(var(--annonce-radius)-6px)];
}
&.sz-lg {
@apply py-2 pr-6 pl-2 [&>span]:rounded-[calc(var(--annonce-radius)-8px)];
}
}
.annonce-concern {
@apply block px-2 py-0.5;
&.sz-xs {
@apply text-xs;
}
&.sz-sm {
@apply text-sm;
}
&.sz-md {
@apply px-2.5 text-sm;
}
&.sz-lg {
@apply px-3 py-1 text-base;
}
&.variant-primary {
@apply bg-(--btn-bg-to) text-(--btn-color);
}
&.variant-neutral {
@apply border border-gray-500/15 bg-gray-500/15 text-gray-950 dark:text-white;
}
}
/* Progress */
.progress {
@apply overflow-hidden rounded-full bg-ui-soft;
&.sz-xs {
@apply h-0.5;
}
&.sz-sm {
@apply h-1;
}
&.sz-md {
@apply h-1.5;
}
&.sz-lg {
@apply h-2.5;
}
&.sz-xl {
@apply h-3.5;
}
}
.progress-indicator {
@apply h-full rounded-full transition-transform duration-[660ms] ease-[cubic-bezier(0.65,0,0.35,1)];
&.variant-primary {
@apply bg-primary-600;
}
&.variant-danger {
@apply bg-danger-600;
}
&.variant-success {
@apply bg-success-600;
}
&.variant-warning {
@apply bg-warning-600;
}
&.variant-gray {
@apply bg-gray-600;
}
&.variant-neutral {
@apply bg-gray-950 dark:bg-white;
}
}
/* Avatar */
.avatar {
@apply relative block rounded-avatar border border-gray-950/5 *:rounded-avatar before:hidden dark:border-white/5;
img {
@apply size-full object-cover;
}
&.avatar-status {
@apply before:absolute before:right-px before:z-1 before:block before:rounded-full before:border-white dark:before:border-gray-950;
}
&.sz-xs,
&.sz-sm {
@apply before:size-2 before:border-[1px];
}
&.sz-xxs {
@apply size-6 text-xs before:size-1.5 before:border-[1px];
}
&.sz-xs {
@apply size-7 text-xs;
}
&.sz-sm {
@apply size-8 text-sm;
}
&.sz-md {
@apply size-9 text-sm before:right-px before:size-2.5 before:border-2;
}
&.sz-lg {
@apply size-10 text-base before:top-0.5 before:right-0.5 before:size-2.5 before:border-[2px];
}
&.sz-xl {
@apply size-12 text-lg before:top-[3px] before:right-[3px] before:size-2.5 before:border-2;
}
&.sz-xxl {
@apply size-16 text-sm before:top-1 before:right-1 before:size-3 before:border-2;
}
&.sz-xxxl {
@apply size-20 text-2xl before:top-1.5 before:right-1.5 before:size-3.5 before:border-2;
}
&.status-online {
@apply before:bg-success-600 dark:before:bg-success-400;
}
&.status-offline {
@apply before:bg-gray-600 dark:before:bg-gray-400;
}
&.status-away {
@apply before:bg-warning-600 dark:before:bg-warning-500;
}
&.status-busy {
@apply before:bg-danger-600 dark:before:bg-danger-400;
}
&.fallback-neutral,
&.fallback-primary {
@apply flex items-center justify-center border font-medium;
}
&.fallback-neutral {
@apply border-gray-500/15 bg-gray-500/15 text-gray-800 dark:text-gray-300;
}
&.fallback-primary {
@apply border-primary-500/15 bg-primary-500/15 text-primary-800 dark:text-primary-300;
}
}
.callout {
@apply rounded-card border p-5;
.callout-title {
@apply text-title font-medium;
}
.callout-description {
@apply mt-1 text-body;
}
.callout-link {
@apply text-title font-medium underline;
}
&.variant-warning {
@apply bg-warning-50 [--title-text-color:var(--color-warning-950)] dark:border-white/5 dark:bg-warning-500/5 dark:[--title-text-color:var(--color-white)];
}
&.variant-danger {
@apply bg-danger-50 [--title-text-color:var(--color-danger-950)] dark:border-white/5 dark:bg-danger-500/5 dark:[--title-text-color:var(--color-white)];
}
&.variant-neutral {
@apply bg-gray-50 [--title-text-color:var(--color-gray-950)] dark:bg-gray-500/5 dark:[--title-text-color:var(--color-white)];
}
}
}
This example shows how layers help organize different aspects of your styles.
Key Takeaways
- Leverage Variants: Classes inside layers can use all TailwindCSS variants like
dark
,hover
,lg
, etc. - Organized Structure: Separate your global styles, components, and utilities for better maintainability.
- Simplified Customization: Use the
@utility
directive in TailwindCSS v4 to define custom utilities with ease. - Reusability: Layers ensure that your custom styles remain consistent and reusable across your project.
By integrating layers into your workflow, you’ll make your TailwindCSS project cleaner, more efficient, and easier to scale.