Just-in-Time: Следующее поколение Tailwind CSS
Tailwind CSS на GitHubTailwind CSS в Telegram

Наведение, фокус и другие состояния

Использование утилит для стилизации элементов при наведении, фокусе и т. д.

Обзор

Подобно тому, как Tailwind обрабатывает адаптивный дизайн, стилизация элементов при наведении курсора, фокусе и т. д. может выполняться с помощью префикса утилит с соответствующим вариантом состояния.

<form>
  <input class="border border-transparent focus:outline-none focus:ring-2 focus:ring-purple-600 focus:border-transparent ...">
  <button class="bg-purple-600 hover:bg-purple-700 focus:outline-none focus:ring-2 focus:ring-purple-600 focus:ring-opacity-50 ...">
    Зарегистрироваться
  </button>
</form>

Не все варианты состояния включены для всех утилит по умолчанию из-за соображений размера файла, но мы постарались сделать все возможное, чтобы включить наиболее часто используемые комбинации из коробки.

Полный список вариантов, включенных по умолчанию, смотрите в справочной таблице в конце этой страницы.

Если вам нужно настроить таргетинг на состояние, которое Tailwind не поддерживает, вы можете расширить поддерживаемые варианты, написав вариант плагина.


Hover

Добавьте префикс hover: чтобы использовать утилиту только при наведении курсора.

<button class="bg-red-500 hover:bg-red-700 ...">
  Наведите на меня
</button>

По умолчанию вариант hover включен для следующих основных подключаемых модулей:

  • backgroundColor
  • backgroundOpacity
  • borderColor
  • borderOpacity
  • boxShadow
  • gradientColorStops
  • opacity
  • rotate
  • scale
  • skew
  • textColor
  • textDecoration
  • textOpacity
  • translate

Вы можете контролировать, включены ли варианты hover для плагина в разделе variants Вашего файла tailwind.config.js:

// tailwind.config.js
module.exports = {
  // ...
  variants: {
    extend: {
      padding: ['hover'],
    }
  },
}

Focus

Добавьте префикс focus:, чтобы применить утилиту только к фокусу.

<input class="focus:ring-2 focus:ring-blue-600 ...">

По умолчанию вариант focus включен для следующих основных подключаемых модулей:

  • accessibility
  • backgroundColor
  • backgroundOpacity
  • borderColor
  • borderOpacity
  • boxShadow
  • gradientColorStops
  • opacity
  • outline
  • placeholderColor
  • placeholderOpacity
  • ringColor
  • ringOffsetColor
  • ringOffsetWidth
  • ringOpacity
  • ringWidth
  • rotate
  • scale
  • skew
  • textColor
  • textDecoration
  • textOpacity
  • translate
  • zIndex

Вы можете контролировать, включены ли варианты focus для плагина в разделе variants Вашего файла tailwind.config.js:

// tailwind.config.js
module.exports = {
  // ...
  variants: {
    extend: {
      maxHeight: ['focus'],
    }
  },
}

Active

Добавьте префикс active:, чтобы применить утилиту только тогда, когда элемент активен.

<button class="bg-green-500 active:bg-green-700 ...">
  Кликните на меня
</button>

По умолчанию вариант active не включен ни для каких основных плагинов.

Вы можете контролировать, включены ли active варианты для плагина в разделе variants Вашего файла tailwind.config.js:

// tailwind.config.js
module.exports = {
  // ...
  variants: {
    extend: {
      backgroundColor: ['active'],
    }
  },
}

Group-hover

Если вам нужно стилизовать дочерний элемент при наведении курсора на определенный родительский элемент, добавьте класс group к родительскому элементу и добавьте префикс group-hover: к утилите на дочернем элементе.

Новый проект

Создайте новый проект из множества начальных шаблонов.

<div class="group border-indigo-500 hover:bg-white hover:shadow-lg hover:border-transparent ...">
  <p class="text-indigo-600 group-hover:text-gray-900 ...">Новый проект</p>
  <p class="text-indigo-500 group-hover:text-gray-500 ...">Создайте новый проект из множества начальных шаблонов.</p>
</div>

По умолчанию вариант group-hover включен для следующих основных подключаемых модулей:

  • backgroundColor
  • backgroundOpacity
  • borderColor
  • borderOpacity
  • boxShadow
  • opacity
  • textColor
  • textDecoration
  • textOpacity

Вы можете контролировать, включены ли варианты group-hover для плагина в разделе variants Вашего файла tailwind.config.js:

// tailwind.config.js
module.exports = {
  // ...
  variants: {
    extend: {
      divideColor: ['group-hover'],
    }
  },
}

Group-focus

Вариант group-focus работает так же, как group-hover за исключением фокуса:

<button class="group bg-yellow-500 focus:bg-yellow-600 ...">
  <svg class="text-white group-focus:text-yellow-300 ..."></svg>
  Закладка
</button>

По умолчанию вариант group-focus не включен ни для каких основных плагинов.

Вы можете контролировать, включены ли варианты group-focus для плагина в разделе variants Вашего файла tailwind.config.js:

// tailwind.config.js
module.exports = {
  // ...
  variants: {
    extend: {
      backgroundColor: ['group-focus'],
    }
  },
}

Focus-within

Добавьте префикс focus-within:, чтобы применять утилиту только тогда, когда этот элемент или любой из его потомков имеет фокус.

<form>
  <div class="text-gray-400 focus-within:text-gray-600 ...">
    <div class="...">
      <svg fill="currentColor"></svg>
    </div>
    <input class="focus:ring-2 focus:ring-gray-300 ...">
  </div>
</form>

По умолчанию вариант focus-within включен для следующих основных подключаемых модулей:

  • accessibility
  • backgroundColor
  • backgroundOpacity
  • borderColor
  • borderOpacity
  • boxShadow
  • opacity
  • outline
  • ringColor
  • ringOffsetColor
  • ringOffsetWidth
  • ringOpacity
  • ringWidth
  • textColor
  • textDecoration
  • textOpacity
  • zIndex

Вы можете контролировать, включены ли варианты focus-within для плагина в разделе variants Вашего файла tailwind.config.js:

// tailwind.config.js
module.exports = {
  // ...
  variants: {
    extend: {
      scale: ['focus-within'],
    }
  },
}

Focus-visible

Обратите внимание, что focus-visible в настоящее время требует полифиллов JS и PostCSS для достаточной поддержки браузером.

Добавьте префикс focus-visible:, чтобы применить утилиту только тогда, когда элемент имеет фокус, но только если пользователь использует клавиатуру.

<button class="focus:ring-2 focus:ring-red-500 ...">
  Кольцо в focus
</button>
<button class="focus:outline-none focus-visible:ring-2 focus-visible:ring-rose-500 ...">
  Кольцо в focus-visible
</button>

Обратите внимание, что в настоящее время только Chrome, Edge и Firefox нативно поддерживают focus-visible, поэтому для достаточной поддержки браузера вы должны установить и настроить оба параметра JS полифил focus-visible и PostCSS полифил focus-visible. Обязательно включите плагин PostCSS после Tailwind в свой список плагинов PostCSS:

// postcss.config.js
module.exports = {
  plugins: {
    tailwindcss: {},
    'postcss-focus-visible': {},
    autoprefixer: {}
  }
}

По умолчанию вариант focus-visible не включен ни для каких основных плагинов.

Вы можете контролировать, включены ли варианты focus-visible для плагина в разделе variants Вашего файла tailwind.config.js:

// tailwind.config.js
module.exports = {
  // ...
  variants: {
    extend: {
      textDecoration: ['focus-visible'],
    }
  },
}

Motion-safe

Добавьте префикс motion-safe:, чтобы применить утилиту только тогда, когда мультимедийная функция prefers-reduced-motion совпадает с no-preference.

Например, эта кнопка будет анимироваться только при наведении курсора, если пользователь не включил «Уменьшить движение» в своей системе.

<button class="transform motion-safe:hover:scale-110 ...">
  Наведите на меня
</button>

Обратите внимание, что в отличие от большинства других вариантов, motion-safe можно комбинировать как с адаптивными вариантами, так и с другими вариантами, такими как hover, складывая их в следующем порядке:

<div class="sm:motion-safe:hover:animate-spin">
  <!-- ... -->
</div>

По умолчанию вариант motion-safe не включен ни для каких основных плагинов.

Вы можете контролировать, включены ли варианты motion-safe для плагина в разделе variants Вашего файла tailwind.config.js:

// tailwind.config.js
module.exports = {
  // ...
  variants: {
    extend: {
      animation: ['motion-safe'],
    }
  },
}

Motion-reduce

Добавьте префикс motion-reduce:, чтобы применить утилиту только тогда, когда мультимедийная функция prefers-reduced-motion совпадает с reduce.

Например, эта кнопка по умолчанию будет анимировать при наведении курсора, но анимация будет отключена, если пользователь включил «Уменьшить движение» в своей системе.

<button class="transform hover:scale-110 motion-reduce:transform-none ...">
  Наведите на меня
</button>

Обратите внимание, что в отличие от большинства других вариантов, motion-reduce можно комбинировать как с адаптивными вариантами, так и с другими вариантами, такими как hover, складывая их в следующем порядке:

<div class="sm:motion-reduce:hover:animate-none">
  <!-- ... -->
</div>

По умолчанию вариант motion-reduce не включен ни для каких основных плагинов.

Вы можете контролировать, включены ли варианты motion-reduce для плагина в разделе variants Вашего файла tailwind.config.js:

// tailwind.config.js
module.exports = {
  // ...
  variants: {
    extend: {
      animation: ['motion-reduce'],
    }
  },
}

Disabled

Добавьте префикс disabled:, чтобы применять утилиту только тогда, когда элемент отключен.

<button class="disabled:opacity-50 ...">
  Отправить
</button>
<button class="disabled:opacity-50 ..." disabled>
  Отправить
</button>

По умолчанию вариант disabled не включен ни для каких основных плагинов.

Вы можете контролировать, включены ли варианты disabled для плагина в разделе variants Вашего файла tailwind.config.js:

// tailwind.config.js
module.exports = {
  // ...
  variants: {
    extend: {
      opacity: ['disabled'],
    }
  },
}

Visited

Добавьте префикс visited:, чтобы применять утилиту только при посещении ссылки.

<a href="#" class="text-blue-600 visited:text-purple-600 ...">Ссылка</a>

По умолчанию вариант visited не включен ни для каких основных плагинов.

Вы можете контролировать, включены ли варианты visited для плагина в разделе variants Вашего файла tailwind.config.js:

// tailwind.config.js
module.exports = {
  // ...
  variants: {
    extend: {
      textColor: ['visited'],
    }
  },
}

Checked

Добавьте префикс checked:, чтобы применять утилиту только тогда, когда в данный момент установлен переключатель или флажок.

<input type="checkbox" class="appearance-none checked:bg-blue-600 checked:border-transparent ...">

По умолчанию вариант checked не включен ни для каких основных плагинов.

Вы можете контролировать, включены ли варианты checked для плагина в разделе variants Вашего файла tailwind.config.js:

// tailwind.config.js
module.exports = {
  // ...
  variants: {
    extend: {
      backgroundColor: ['checked'],
      borderColor: ['checked'],
    }
  },
}

First-child

Добавьте префикс first:, чтобы применять утилиту только тогда, когда она является первым потомком своего родителя. Это в основном полезно, когда элементы создаются в каком-то цикле.

<div class="...">
  <div v-for="item in items" class="transform first:rotate-45 ...">
    {{ item }}
  </div>
</div>

Важно отметить, что вы должны добавлять любые утилиты first: к дочернему элементу, а не к родительскому элементу.

По умолчанию вариант first-child не включен ни для каких основных плагинов.

Вы можете контролировать, включены ли варианты first для плагина в разделе variants Вашего файла tailwind.config.js:

// tailwind.config.js
module.exports = {
  // ...
  variants: {
    extend: {
      borderWidth: ['first'],
    }
  },
}

Last-child

Добавьте префикс last:, чтобы применять утилиту только тогда, когда она является последним потомком своего родителя. Это в основном полезно, когда элементы создаются в каком-то цикле.

<div class="...">
  <div v-for="item in items" class="transform last:rotate-45 ...">
    {{ item }}
  </div>
</div>

Важно отметить, что вы должны добавлять любые утилиты last: к дочернему элементу, а не к родительскому элементу.

По умолчанию вариант last-child не включен ни для каких основных плагинов.

Вы можете контролировать, включены ли варианты last для плагина в разделе variants Вашего файла tailwind.config.js:

// tailwind.config.js
module.exports = {
  // ...
  variants: {
    extend: {
      borderWidth: ['last'],
    }
  },
}

Odd-child

Добавьте префикс odd:, чтобы использовать утилиту, только если она является нечетным потомком своего родителя. Это в основном полезно, когда элементы создаются в каком-то цикле.

<div class="...">
  <div v-for="item in items" class="transform odd:rotate-45 ...">
    {{ item }}
  </div>
</div>

Важно отметить, что вы должны добавлять любые утилиты odd: к дочернему элементу, а не к родительскому элементу.

По умолчанию вариант odd-child не включен ни для каких основных плагинов.

Вы можете контролировать, включены ли варианты odd для плагина в разделе variants файла tailwind.config.js file:

// tailwind.config.js
module.exports = {
  // ...
  variants: {
    extend: {
      backgroundColor: ['odd'],
    }
  },
}

Even-child

Добавьте префикс even:, чтобы применять утилиту только тогда, когда она является четным потомком своего родителя. Это в основном полезно, когда элементы создаются в каком-то цикле.

<div class="...">
  <div v-for="item in items" class="transform even:rotate-45 ...">
    {{ item }}
  </div>
</div>

Важно отметить, что вы должны добавлять любые утилиты even: к дочернему элементу, а не к родительскому элементу.

По умолчанию вариант even-child не включен ни для каких основных плагинов.

Вы можете контролировать, включены ли варианты even для плагина в разделе variants Вашего файла tailwind.config.js:

// tailwind.config.js
module.exports = {
  // ...
  variants: {
    extend: {
      backgroundColor: ['even'],
    }
  },
}

Комбинирование с адаптивными префиксами

Варианты состояния также являются адаптивными, что означает, что вы можете делать такие вещи, как, например, изменять стиль наведения элемента в разных контрольных точках.

Чтобы применить вариант состояния к определенной контрольной точке, сначала добавьте префикс ответа перед префиксом состояния:

<button class="... hover:bg-green-500 sm:hover:bg-blue-500">
  <!-- ... -->
</button>

Создание вариантов для пользовательских утилит

Вы можете сгенерировать варианты состояния для Ваших собственных пользовательских классов CSS, заключив их в директиву @variants:

/* Ввод: */
@variants group-hover, hover, focus {
  .banana {
    color: yellow;
  }
}

/* Вывод: */
.banana {
  color: yellow;
}
.group:hover .group-hover\:banana {
  color: yellow;
}
.hover\:banana:hover {
  color: yellow;
}
.focus\:banana:focus {
  color: yellow;
}

Дополнительные сведения смотрите в документации директивы @variants.


Создание собственных вариантов

Вы можете создавать свои собственные варианты для любых состояний, которые Tailwind не поддерживает по умолчанию, написав собственный вариант плагина.

Например, этот простой плагин добавляет поддержку варианта псевдокласса required:

// tailwind.config.js
const plugin = require('tailwindcss/plugin')

module.exports = {
  plugins: [
    plugin(function({ addVariant, e }) {
      addVariant('required', ({ modifySelectors, separator }) => {
        modifySelectors(({ className }) => {
          return `.${e(`required${separator}${className}`)}:required`
        })
      })
    })
  ]
}

Узнайте больше о написании альтернативных плагинов в документации по вариантам плагинов.


Справочник вариантов по умолчанию

Из-за соображений размера файла Tailwind по умолчанию не включает все варианты для всех утилит.

Чтобы настроить, какие варианты включены для Вашего проекта, смотрите документацию по настройке вариантов.

// Default configuration
module.exports = {
  // ...
  variants: {
    accessibility: ['responsive', 'focus-within', 'focus'],
    alignContent: ['responsive'],
    alignItems: ['responsive'],
    alignSelf: ['responsive'],
    animation: ['responsive'],
    appearance: ['responsive'],
    backdropBlur: ['responsive'],
    backdropBrightness: ['responsive'],
    backdropContrast: ['responsive'],
    backdropFilter: ['responsive'],
    backdropGrayscale: ['responsive'],
    backdropHueRotate: ['responsive'],
    backdropInvert: ['responsive'],
    backdropOpacity: ['responsive'],
    backdropSaturate: ['responsive'],
    backdropSepia: ['responsive'],
    backgroundAttachment: ['responsive'],
    backgroundBlendMode: ['responsive'],
    backgroundClip: ['responsive'],
    backgroundColor: ['responsive', 'dark', 'group-hover', 'focus-within', 'hover', 'focus'],
    backgroundImage: ['responsive'],
    backgroundOpacity: ['responsive', 'dark', 'group-hover', 'focus-within', 'hover', 'focus'],
    backgroundPosition: ['responsive'],
    backgroundRepeat: ['responsive'],
    backgroundSize: ['responsive'],
    backgroundOrigin: ['responsive'],
    blur: ['responsive'],
    borderCollapse: ['responsive'],
    borderColor: ['responsive', 'dark', 'group-hover', 'focus-within', 'hover', 'focus'],
    borderOpacity: ['responsive', 'dark', 'group-hover', 'focus-within', 'hover', 'focus'],
    borderRadius: ['responsive'],
    borderStyle: ['responsive'],
    borderWidth: ['responsive'],
    boxDecorationBreak: ['responsive'],
    boxShadow: ['responsive', 'group-hover', 'focus-within', 'hover', 'focus'],
    boxSizing: ['responsive'],
    brightness: ['responsive'],
    clear: ['responsive'],
    container: ['responsive'],
    contrast: ['responsive'],
    cursor: ['responsive'],
    display: ['responsive'],
    divideColor: ['responsive', 'dark'],
    divideOpacity: ['responsive', 'dark'],
    divideStyle: ['responsive'],
    divideWidth: ['responsive'],
    dropShadow: ['responsive'],
    fill: ['responsive'],
    filter: ['responsive'],
    flex: ['responsive'],
    flexDirection: ['responsive'],
    flexGrow: ['responsive'],
    flexShrink: ['responsive'],
    flexWrap: ['responsive'],
    float: ['responsive'],
    fontFamily: ['responsive'],
    fontSize: ['responsive'],
    fontSmoothing: ['responsive'],
    fontStyle: ['responsive'],
    fontVariantNumeric: ['responsive'],
    fontWeight: ['responsive'],
    gap: ['responsive'],
    gradientColorStops: ['responsive', 'dark', 'hover', 'focus'],
    grayscale: ['responsive'],
    gridAutoColumns: ['responsive'],
    gridAutoFlow: ['responsive'],
    gridAutoRows: ['responsive'],
    gridColumn: ['responsive'],
    gridColumnEnd: ['responsive'],
    gridColumnStart: ['responsive'],
    gridRow: ['responsive'],
    gridRowEnd: ['responsive'],
    gridRowStart: ['responsive'],
    gridTemplateColumns: ['responsive'],
    gridTemplateRows: ['responsive'],
    height: ['responsive'],
    hueRotate: ['responsive'],
    inset: ['responsive'],
    invert: ['responsive'],
    isolation: ['responsive'],
    justifyContent: ['responsive'],
    justifyItems: ['responsive'],
    justifySelf: ['responsive'],
    letterSpacing: ['responsive'],
    lineHeight: ['responsive'],
    listStylePosition: ['responsive'],
    listStyleType: ['responsive'],
    margin: ['responsive'],
    maxHeight: ['responsive'],
    maxWidth: ['responsive'],
    minHeight: ['responsive'],
    minWidth: ['responsive'],
    mixBlendMode: ['responsive'],
    objectFit: ['responsive'],
    objectPosition: ['responsive'],
    opacity: ['responsive', 'group-hover', 'focus-within', 'hover', 'focus'],
    order: ['responsive'],
    outline: ['responsive', 'focus-within', 'focus'],
    overflow: ['responsive'],
    overscrollBehavior: ['responsive'],
    padding: ['responsive'],
    placeContent: ['responsive'],
    placeItems: ['responsive'],
    placeSelf: ['responsive'],
    placeholderColor: ['responsive', 'dark', 'focus'],
    placeholderOpacity: ['responsive', 'dark', 'focus'],
    pointerEvents: ['responsive'],
    position: ['responsive'],
    resize: ['responsive'],
    ringColor: ['responsive', 'dark', 'focus-within', 'focus'],
    ringOffsetColor: ['responsive', 'dark', 'focus-within', 'focus'],
    ringOffsetWidth: ['responsive', 'focus-within', 'focus'],
    ringOpacity: ['responsive', 'dark', 'focus-within', 'focus'],
    ringWidth: ['responsive', 'focus-within', 'focus'],
    rotate: ['responsive', 'hover', 'focus'],
    saturate: ['responsive'],
    scale: ['responsive', 'hover', 'focus'],
    sepia: ['responsive'],
    skew: ['responsive', 'hover', 'focus'],
    space: ['responsive'],
    stroke: ['responsive'],
    strokeWidth: ['responsive'],
    tableLayout: ['responsive'],
    textAlign: ['responsive'],
    textColor: ['responsive', 'dark', 'group-hover', 'focus-within', 'hover', 'focus'],
    textDecoration: ['responsive', 'group-hover', 'focus-within', 'hover', 'focus'],
    textOpacity: ['responsive', 'dark', 'group-hover', 'focus-within', 'hover', 'focus'],
    textOverflow: ['responsive'],
    textTransform: ['responsive'],
    transform: ['responsive'],
    transformOrigin: ['responsive'],
    transitionDelay: ['responsive'],
    transitionDuration: ['responsive'],
    transitionProperty: ['responsive'],
    transitionTimingFunction: ['responsive'],
    translate: ['responsive', 'hover', 'focus'],
    userSelect: ['responsive'],
    verticalAlign: ['responsive'],
    visibility: ['responsive'],
    whitespace: ['responsive'],
    width: ['responsive'],
    wordBreak: ['responsive'],
    zIndex: ['responsive', 'focus-within', 'focus']
  }
}