Раскрывающиеся списки и флажки
Стилизуйте стандартные раскрывающиеся списки и флажки и используйте плагин @tailwindcss/forms для унификации стилей форм в разных браузерах.
«Раскрывающиеся списки и флажки» — бесплатный урок Tailwind CSS Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Tailwind CSS Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Tailwind CSS Academy содержит 4 уроков всего.
Части этого урока еще не переведены и отображаются на английском.
The Challenge With Native Form Controls
Native <select>, <checkbox>, and <radio> elements are notoriously difficult to style consistently across browsers. By default, they inherit the operating system's appearance using the appearance CSS property, which Tailwind resets with the appearance-none utility.
After removing the native appearance, you regain full control over styling. The @tailwindcss/forms plugin automates this reset for all form elements, giving you a clean cross-browser baseline without manually adding appearance-none everywhere.
<!-- Without plugin: manual appearance reset needed -->
<select class="appearance-none w-full px-3 py-2 border border-gray-300 rounded-lg">
<option>Option A</option>
</select>
<!-- With @tailwindcss/forms plugin: already normalized -->
<select class="w-full px-3 py-2 border border-gray-300 rounded-lg">
<option>Option A</option>
</select>Styling a Select Dropdown
A styled select uses the same base classes as a text input: w-full px-3 py-2 text-sm border border-gray-300 rounded-lg bg-white. Add a custom dropdown arrow by positioning a background SVG image or overlaying an absolutely positioned SVG icon.
The focus state uses the familiar focus:outline-none focus:ring-2 focus:ring-blue-500. Add cursor-pointer so the mouse cursor communicates that clicking opens a menu.
<div class="relative">
<select
class="w-full appearance-none px-3 py-2 text-sm text-gray-900 bg-white
border border-gray-300 rounded-lg cursor-pointer
focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent">
<option value="">Select a country</option>
<option value="us">United States</option>
<option value="uk">United Kingdom</option>
<option value="de">Germany</option>
</select>
<!-- Custom dropdown arrow -->
<div class="pointer-events-none absolute inset-y-0 right-3 flex items-center">
<svg class="w-4 h-4 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/>
</svg>
</div>
</div>Installing the Forms Plugin
The @tailwindcss/forms plugin provides an opinionated reset for all native form elements. Install it with npm install -D @tailwindcss/forms and add it to the plugins array in tailwind.config.js.
Once installed, all inputs, selects, textareas, checkboxes, and radio buttons receive a consistent base style. You can then layer Tailwind utilities on top without fighting browser defaults. Use require('@tailwindcss/forms')({ strategy: 'class' }) if you prefer the plugin to only apply when you add a specific class.
// tailwind.config.js
module.exports = {
content: ['./src/**/*.{html,js}'],
theme: {
extend: {},
},
plugins: [
require('@tailwindcss/forms'),
// Or with class strategy:
// require('@tailwindcss/forms')({ strategy: 'class' }),
],
}Styling Checkboxes
With the forms plugin, checkboxes are already normalized. You can then customize their size, color, and rounding with utilities. Use w-4 h-4 rounded text-blue-600 border-gray-300 — the text-blue-600 on a checkbox sets the fill color of the checkmark.
Pair the checkbox with a label using flex items-center gap-2 to keep them horizontally aligned. The label text uses text-sm font-medium text-gray-700.
<div class="flex items-center gap-2">
<input
id="terms"
type="checkbox"
class="w-4 h-4 rounded text-blue-600 border-gray-300
focus:ring-blue-500 focus:ring-2 cursor-pointer"
/>
<label for="terms" class="text-sm font-medium text-gray-700 cursor-pointer">
I agree to the <a href="/terms" class="text-blue-600 hover:underline">Terms of Service</a>
</label>
</div>Checkbox List for Multi-Select
A checkbox list allows users to select multiple options. Stack multiple checkbox items with space-y-3 on the container. Group them inside a <fieldset> with a <legend> for accessibility.
The legend identifies the entire group for screen readers, while individual labels are associated with their specific checkboxes via for/id attributes.
<fieldset>
<legend class="text-sm font-semibold text-gray-900 mb-3">Notification preferences</legend>
<div class="space-y-3">
<div class="flex items-center gap-2">
<input id="email-notif" type="checkbox" checked class="w-4 h-4 rounded text-blue-600 border-gray-300 focus:ring-blue-500" />
<label for="email-notif" class="text-sm text-gray-700">Email notifications</label>
</div>
<div class="flex items-center gap-2">
<input id="push-notif" type="checkbox" class="w-4 h-4 rounded text-blue-600 border-gray-300 focus:ring-blue-500" />
<label for="push-notif" class="text-sm text-gray-700">Push notifications</label>
</div>
<div class="flex items-center gap-2">
<input id="sms-notif" type="checkbox" class="w-4 h-4 rounded text-blue-600 border-gray-300 focus:ring-blue-500" />
<label for="sms-notif" class="text-sm text-gray-700">SMS notifications</label>
</div>
</div>
</fieldset>Styling Radio Buttons
Radio buttons are styled identically to checkboxes but use rounded-full instead of rounded to keep the circular appearance that users associate with single-selection. The text-blue-600 trick applies here too for the fill color.
All radio buttons in the same group must share the same name attribute so the browser enforces the single-selection constraint.
<fieldset>
<legend class="text-sm font-semibold text-gray-900 mb-3">Plan</legend>
<div class="space-y-2">
<div class="flex items-center gap-2">
<input id="plan-starter" type="radio" name="plan" value="starter"
class="w-4 h-4 text-blue-600 border-gray-300 focus:ring-blue-500" />
<label for="plan-starter" class="text-sm text-gray-700">Starter — Free</label>
</div>
<div class="flex items-center gap-2">
<input id="plan-pro" type="radio" name="plan" value="pro" checked
class="w-4 h-4 text-blue-600 border-gray-300 focus:ring-blue-500" />
<label for="plan-pro" class="text-sm text-gray-700">Pro — $29/mo</label>
</div>
<div class="flex items-center gap-2">
<input id="plan-enterprise" type="radio" name="plan" value="enterprise"
class="w-4 h-4 text-blue-600 border-gray-300 focus:ring-blue-500" />
<label for="plan-enterprise" class="text-sm text-gray-700">Enterprise — Custom</label>
</div>
</div>
</fieldset>Card-Style Radio Group
A card-style radio group wraps each option in a clickable card rather than showing a bare radio button. Hide the radio input visually but keep it accessible, and use the peer utility to style the card based on the input's checked state.
peer-checked:border-blue-600 peer-checked:ring-2 peer-checked:ring-blue-600 on the sibling label card creates a highlighted selection state with no JavaScript required.
<div class="grid grid-cols-3 gap-3">
<label class="cursor-pointer">
<input type="radio" name="tier" value="starter" class="sr-only peer" />
<div class="border-2 border-gray-200 rounded-lg p-4 text-center
peer-checked:border-blue-600 peer-checked:ring-2 peer-checked:ring-blue-600
hover:border-gray-300 transition-colors">
<p class="font-semibold text-gray-900">Starter</p>
<p class="text-sm text-gray-500">Free</p>
</div>
</label>
<label class="cursor-pointer">
<input type="radio" name="tier" value="pro" class="sr-only peer" checked />
<div class="border-2 border-gray-200 rounded-lg p-4 text-center
peer-checked:border-blue-600 peer-checked:ring-2 peer-checked:ring-blue-600
hover:border-gray-300 transition-colors">
<p class="font-semibold text-gray-900">Pro</p>
<p class="text-sm text-gray-500">$29/mo</p>
</div>
</label>
</div>Toggle Switch Component
A toggle switch is a styled checkbox that looks like a sliding on/off switch. Build it using an <input type='checkbox'> with sr-only and a sibling <div> that uses peer-checked utilities to animate.
The track uses w-11 h-6 bg-gray-200 rounded-full, and the knob uses an absolutely positioned w-4 h-4 bg-white rounded-full shadow. The peer-checked:translate-x-5 utility slides the knob right when checked.
<label class="flex items-center gap-3 cursor-pointer">
<div class="relative">
<input type="checkbox" class="sr-only peer" />
<div class="w-11 h-6 bg-gray-200 rounded-full transition-colors duration-200
peer-checked:bg-blue-600"></div>
<div class="absolute top-1 left-1 w-4 h-4 bg-white rounded-full shadow
transition-transform duration-200 peer-checked:translate-x-5"></div>
</div>
<span class="text-sm font-medium text-gray-700">Enable notifications</span>
</label>Custom Select With Search
The native <select> does not support searching. For searchable dropdowns, use a custom combination of an input + list. Show a text input where the user types, and filter a visible <ul> below it with JavaScript.
Style the dropdown list with absolute top-full left-0 right-0 mt-1 bg-white border border-gray-200 rounded-lg shadow-lg max-h-48 overflow-y-auto z-10 to position it correctly below the input.
<div class="relative">
<input
type="text"
placeholder="Search country..."
class="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg
focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
<ul class="absolute top-full left-0 right-0 mt-1 bg-white border border-gray-200
rounded-lg shadow-lg max-h-48 overflow-y-auto z-10">
<li class="px-3 py-2 text-sm text-gray-700 hover:bg-blue-50 cursor-pointer">Germany</li>
<li class="px-3 py-2 text-sm text-gray-700 hover:bg-blue-50 cursor-pointer">France</li>
<li class="px-3 py-2 text-sm text-blue-600 font-medium bg-blue-50 cursor-pointer">United Kingdom</li>
<li class="px-3 py-2 text-sm text-gray-700 hover:bg-blue-50 cursor-pointer">United States</li>
</ul>
</div>Disabled Checkbox and Select
Disabled checkboxes and selects use the disabled: variant. For checkboxes: disabled:opacity-50 disabled:cursor-not-allowed dims the element. For selects: combine these with disabled:bg-gray-50 to match the text input disabled pattern.
Always add the HTML disabled attribute — Tailwind's disabled: variants only activate when this attribute is present on the element.
<!-- Disabled checkbox -->
<div class="flex items-center gap-2">
<input
type="checkbox"
disabled
class="w-4 h-4 rounded border-gray-300 disabled:opacity-50 disabled:cursor-not-allowed"
/>
<label class="text-sm text-gray-400">Unavailable option</label>
</div>
<!-- Disabled select -->
<select
disabled
class="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg
disabled:bg-gray-50 disabled:text-gray-400 disabled:cursor-not-allowed">
<option>Disabled option</option>
</select>Range Input Styling
The <input type='range'> element creates a slider. With the forms plugin, you can style the track and thumb using accent-blue-600 — a CSS property that sets the color of native controls like range sliders, progress bars, and checkboxes with a single utility.
accent-blue-600 is the simplest way to brand native sliders without completely replacing them with custom components.
<div class="flex flex-col gap-1">
<label for="volume" class="text-sm font-medium text-gray-700">Volume: <span id="vol">50</span>%</label>
<input
id="volume"
type="range"
min="0"
max="100"
value="50"
oninput="document.getElementById('vol').textContent = this.value"
class="w-full h-2 accent-blue-600 cursor-pointer"
/>
</div>Quick Check
Test your understanding of Tailwind CSS Mastery concepts from this lesson.
Lesson Recap
In this lesson you learned: @tailwindcss/forms plugin normalizes native form elements across browsers giving a clean styling baseline; checkboxes and radios use text-blue-600 to set the fill color and focus:ring-blue-500 for focus rings; and the peer utility enables card-style radio groups and toggle switches that react to checked state without any JavaScript. Next up we design form layout patterns.
Часто задаваемые вопросы
Урок «Раскрывающиеся списки и флажки» бесплатный?
Да — полный текст урока «Раскрывающиеся списки и флажки» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Tailwind CSS Academy, подпишись на CoddyKit PRO. Курс Tailwind CSS Academy содержит 4 уроков всего.
Чему я научусь в уроке «Раскрывающиеся списки и флажки»?
Стилизуйте стандартные раскрывающиеся списки и флажки и используйте плагин @tailwindcss/forms для унификации стилей форм в разных браузерах. Ты практикуешь Tailwind CSS Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Tailwind CSS Academy?
Предыдущий опыт не требуется. Tailwind CSS Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «Раскрывающиеся списки и флажки»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Tailwind CSS Academy?
Да. Каждый урок Tailwind CSS Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Стилизация текстовых полей и многострочных полей
- Раскрывающиеся списки и флажки
- Шаблоны макетов форм
- Состояния проверки и ошибки