Основные концепции
Лучшие практики добавления собственных стилей в проекты Tailwind.
Часто самая большая проблема при работе с фреймворком заключается в том, чтобы понять, что делать, когда вам нужно что-то, чего фреймворк не обрабатывает для вас.
Tailwind был разработан с нуля для того, чтобы быть расширяемым и настраиваемым, чтобы вы никогда не чувствовали, что боретесь с фреймворком, независимо от того, что вы строите.
В этом руководстве рассматриваются такие темы, как настройка ваших токенов дизайна, как выходить за рамки этих ограничений при необходимости, добавление своего собственного пользовательского CSS и расширение фреймворка с помощью плагинов.
Если вы хотите изменить такие вещи, как цветовая палитра, масштаб отступов, масштаб типографики или контрольные точки, добавьте свои настройки с помощью директивы @theme
в вашем 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); /* ... */}
Узнайте больше о настройке вашей темы в документации по переменным темы.
Хотя обычно вы можете создать большую часть хорошо продуманного дизайна, используя ограниченный набор токенов дизайна, иногда вам нужно выйти за рамки этих ограничений, чтобы получить пиксель-идеальное расположение элементов.
Когда вы действительно нуждаетесь в чем-то вроде top: 117px
, чтобы разместить фоновое изображение в нужном месте, используйте квадратные скобки Tailwind, чтобы сгенерировать класс на лету с любым произвольным значением:
<div class="top-[117px]"> <!-- ... --></div>
Это похоже на встроенные стили, с основным преимуществом, что вы можете комбинировать его с интерактивными модификаторами, такими как hover
, и адаптивными модификаторами, такими как lg
:
<div class="top-[117px] lg:top-[344px]"> <!-- ... --></div>
Это работает для всего в фреймворке, включая такие вещи, как цвета фона, размеры шрифта, содержимое псевдоэлементов и многое другое:
<div class="bg-[#bada55] text-[22px] before:content-['Festivus']"> <!-- ... --></div>
Если вы ссылаетесь на переменную CSS в качестве произвольного значения, вы можете использовать синтаксис пользовательского свойства:
<div class="fill-(--my-brand-color) ..."> <!-- ... --></div>
Это просто сокращение для fill-[var(--my-brand-color)]
, которое автоматически добавляет функцию var()
.
Если вам когда-либо понадобится использовать свойство CSS, для которого Tailwind не включает утилиту, вы также можете использовать квадратные скобки, чтобы написать полностью произвольный CSS:
<div class="[mask-type:luminance]"> <!-- ... --></div>
Это на самом деле похоже на встроенные стили, но снова с преимуществом, что вы можете использовать модификаторы:
<div class="[mask-type:luminance] hover:[mask-type:alpha]"> <!-- ... --></div>
Это может быть полезно и для таких вещей, как переменные CSS, особенно когда они должны изменяться в зависимости от разных условий:
<div class="[--scroll-offset:56px] lg:[--scroll-offset:44px]"> <!-- ... --></div>
Произвольные варианты похожи на произвольные значения, но для модификации селектора на лету, как вы можете это делать с встроенными псевдоклассовыми вариантами, такими как hover:{utility}
или адаптивными вариантами, такими как md:{utility}
, но с использованием квадратных скобок непосредственно в вашем HTML.
<ul role="list"> {#each items as item} <li class="lg:[&:nth-child(-n+3)]:hover:underline">{item}</li> {/each}</ul>
Узнайте больше в документации по произвольным вариантам.
Когда произвольное значение должно содержать пробел, используйте подчеркивание (_
) вместо него, и Tailwind автоматически преобразует его в пробел во время сборки
<div class="grid grid-cols-[1fr_500px_2fr]"> <!-- ... --></div>
В ситуациях, когда подчеркивания являются общими, но пробелы недопустимы, Tailwind сохранит подчеркивание вместо преобразования его в пробел, например, в URL-адресах:
<div class="bg-[url('/what_a_rush.png')]"> <!-- ... --></div>
В редких случаях, когда вам действительно нужно использовать подчеркивание, но это вызывает неоднозначность, потому что пробел также допустим, экранируйте подчеркивание обратной косой чертой, и Tailwind не преобразует его в пробел:
<div class="before:content-['hello\_world']"> <!-- ... --></div>
Если вы используете что-то вроде JSX, где обратная косая черта удаляется из отображаемого HTML, используйте String.raw(), чтобы обратная косая черта не рассматривалась как символ экранирования JavaScript:
<div className={String.raw`before:content-['hello\_world']`}> <!-- ... --></div>
Многие утилиты в Tailwind разделяют общее пространство имен, но отображаются на разные свойства CSS. Например, text-lg
и text-black
оба используют пространство имен text-
, но один предназначен для font-size
, а другой - для color
.
При использовании произвольных значений Tailwind обычно может автоматически разрешить эту неоднозначность на основе переданного вами значения:
<!-- Will generate a font-size utility --><div class="text-[22px]">...</div><!-- Will generate a color utility --><div class="text-[#bada55]">...</div>
Иногда это действительно вызывает неоднозначность, например, при использовании переменных CSS:
<div class="text-(--my-var)">...</div>
В этих ситуациях вы можете "подсказать" базовый тип Tailwind, добавив тип данных CSS перед значением:
<!-- Will generate a font-size utility --><div class="text-(length:--my-var)">...</div><!-- Will generate a color utility --><div class="text-(color:--my-var)">...</div>
Хотя Tailwind предназначен для обработки большей части ваших потребностей в стилизации, ничто не мешает вам просто писать обычный CSS, когда это необходимо:
@import "tailwindcss";.my-custom-style { /* ... */}
Если вы просто хотите установить некоторые значения по умолчанию для страницы (например, цвет текста, цвет фона или семейство шрифтов), самым простым вариантом будет добавление некоторых классов к элементам html
или body
:
<!doctype html><html lang="en" class="bg-gray-100 font-serif text-gray-900"> <!-- ... --></html>
Это позволяет сохранить ваши базовые стили в разметке вместе со всеми остальными стилями, вместо того чтобы скрывать их в отдельном файле.
Если вы хотите добавить свои собственные базовые стили по умолчанию для конкретных HTML-элементов, используйте директиву @layer
, чтобы добавить эти стили в слой base
Tailwind:
@layer base { h1 { font-size: var(--text-2xl); } h2 { font-size: var(--text-xl); }}
Используйте слой components
для любых более сложных классов, которые вы хотите добавить в свой проект и которые все еще можно переопределить с помощью утилитарных классов.
Традиционно это были классы, такие как card
, btn
, badge
— такого рода вещи.
@layer components { .card { background-color: var(--color-white); border-radius: var(--rounded-lg); padding: var(--spacing-6); box-shadow: var(--shadow-xl); }}
Определяя классы компонентов в слое components
, вы все равно можете использовать утилитарные классы для их переопределения при необходимости:
<!-- Will look like a card, but with square corners --><div class="card rounded-none"> <!-- ... --></div>
Используя Tailwind, вы, вероятно, не так часто используете эти типы классов, как вы думаете. Ознакомьтесь с нашим руководством по управлению дублированием для наших рекомендаций.
Слой components
также является хорошим местом для размещения пользовательских стилей для любых сторонних компонентов, которые вы используете:
@layer components { .select2-dropdown { /* ... */ }}
Используйте директиву @variant
, чтобы применить вариант Tailwind в пользовательском CSS:
.my-element { background: white; @variant dark { background: black; }}
.my-element { background: white; @media (prefers-color-scheme: dark) { background: black; }}
Если вам необходимо применить несколько вариантов одновременно, используйте вложение:
.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; } } }}
Помимо использования утилит, которые поставляются с Tailwind, вы также можете добавить свои собственные пользовательские утилиты. Это может быть полезно, когда вы хотите использовать функцию CSS в своем проекте, для которой Tailwind не включает утилиты по умолчанию.
Используйте директиву @utility
, чтобы добавить пользовательскую утилиту в ваш проект:
@utility content-auto { content-visibility: auto;}
Теперь вы можете использовать эту утилиту в вашем HTML:
<div class="content-auto"> <!-- ... --></div>
Она также будет работать с вариантами, такими как hover
, focus
и lg
:
<div class="hover:content-auto"> <!-- ... --></div>
Пользовательские утилиты автоматически вставляются в слой utilities
вместе со всеми встроенными утилитами в фреймворке.
Если ваша пользовательская утилита сложнее, чем одно имя класса, используйте вложенность для определения утилиты:
@utility scrollbar-hidden { &::-webkit-scrollbar { display: none; }}
Помимо регистрации простых утилит с помощью директивы @utility
, вы также можете регистрировать функциональные утилиты, которые принимают аргумент:
@utility tab-* { tab-size: --value(--tab-size-*);}
Специальная функция --value()
используется для разрешения значения утилиты.
Используйте синтаксис --value(--theme-key-*)
, чтобы разрешить значение утилиты по набору ключей темы:
@theme { --tab-size-2: 2; --tab-size-4: 4; --tab-size-github: 8;}@utility tab-* { tab-size: --value(--tab-size-*);}
Это будет соответствовать утилитам, таким как tab-2
, tab-4
и tab-github
.
Чтобы разрешить значение как чистое значение, используйте синтаксис --value({type})
, где {type}
- это тип данных, который вы хотите проверить чистое значение на:
@utility tab-* { tab-size: --value(integer);}
Это будет соответствовать утилитам, таким как tab-1
и tab-76
.
Для поддержки литеральных значений используйте синтаксис --value('literal')
(обратите внимание на кавычки):
@utility tab-* { tab-size: --value("inherit", "initial", "unset");}
Это будет соответствовать утилитам, таким как tab-inherit
, tab-initial
и tab-unset
.
Чтобы поддерживать произвольные значения, используйте синтаксис --value([{type}])
(обратите внимание на квадратные скобки), чтобы сообщить Tailwind, какие типы поддерживаются в качестве произвольного значения:
@utility tab-* { tab-size: --value([integer]);}
Это будет соответствовать утилитам, таким как tab-[1]
и tab-[76]
. Если вы хотите поддерживать любой тип данных, вы можете использовать --value([*])
.
Все три формы функции --value()
могут использоваться в правиле в качестве нескольких объявлений, и любые объявления, которые не могут быть разрешены, будут опущены в выводе:
@theme { --tab-size-github: 8;}@utility tab-* { tab-size: --value([integer]); tab-size: --value(integer); tab-size: --value(--tab-size-*);}
Это позволяет обрабатывать значение по-разному в каждом случае, если это необходимо, например, преобразуя целое число в процент:
@utility opacity-* { opacity: --value([percentage]); opacity: calc(--value(integer) * 1%); opacity: --value(--opacity-*);}
Функция --value()
также может принимать несколько аргументов и разрешать их слева направо, если вам не нужно обрабатывать возвращаемое значение по-разному в разных случаях:
@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]);}
Чтобы поддерживать отрицательные значения, зарегистрируйте отдельные положительные и отрицательные утилиты в отдельных объявлениях:
@utility inset-* { inset: --spacing(--value(integer)); inset: --value([percentage], [length]);}@utility -inset-* { inset: --spacing(--value(integer) * -1); inset: calc(--value([percentage], [length]) * -1);}
Модификаторы обрабатываются с помощью функции --modifier()
, которая работает точно так же, как функция --value()
, но оперирует модификатором, если он присутствует:
@utility text-* { font-size: --value(--text-*, [length]); line-height: --modifier(--leading-*, [length], [*]);}
Если модификатор не указан, любое объявление, зависящее от модификатора, просто не включается в вывод.
Для обработки дробей мы полагаемся на тип данных CSS ratio
. Если это используется с --value()
, это сигнал Tailwind обрабатывать значение и модификатор как одно значение:
@utility aspect-* { aspect-ratio: --value(--aspect-ratio-*, ratio, [ratio]);}
Это будет соответствовать утилитам, таким как aspect-square
, aspect-3/4
и aspect-[7/9]
.
Помимо использования вариантов, поставляемых с Tailwind, вы также можете добавлять свои собственные варианты с помощью директивы @custom-variant
:
@custom-variant theme-midnight { &:where([data-theme="midnight"] *) { @slot; }}
Теперь вы можете использовать вариант theme-midnight:<utility>
в своем HTML:
<html data-theme="midnight"> <button class="theme-midnight:bg-black ..."></button></html>
Вы можете создавать варианты, используя сокращенный синтаксис, когда вложенность не требуется:
@custom-variant theme-midnight (&:where([data-theme="midnight"] *));
Когда пользовательский вариант имеет несколько правил, они могут быть вложены друг в друга:
@custom-variant any-hover { @media (any-hover: hover) { &:hover { @slot; } }}