0Pricing
Tailwind CSS Academy · Lezione

Menu select e caselle di spunta

Stilizzi i menu a discesa select e le caselle di spunta native e utilizzi il plugin @tailwindcss/forms per uniformare gli stili dei moduli tra i browser.

Menu select e caselle di spunta è una lezione Tailwind CSS Academy gratuita su CoddyKit. Questa è la lezione 2 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Tailwind CSS Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Tailwind CSS Academy include 4 lezioni in totale.

Parti di questa lezione non sono ancora state tradotte e vengono mostrate in inglese.

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.

Domande Frequenti

La lezione «Menu select e caselle di spunta» è gratuita?

Sì — il testo completo di «Menu select e caselle di spunta» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Tailwind CSS Academy, passa a CoddyKit PRO. Il corso Tailwind CSS Academy include 4 lezioni in totale.

Cosa imparerò in «Menu select e caselle di spunta»?

Stilizzi i menu a discesa select e le caselle di spunta native e utilizzi il plugin @tailwindcss/forms per uniformare gli stili dei moduli tra i browser. Eserciti Tailwind CSS Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Tailwind CSS Academy?

Non è richiesta alcuna esperienza precedente. Tailwind CSS Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 4.

Quanto tempo richiede la lezione «Menu select e caselle di spunta»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Tailwind CSS Academy?

Sì. Ogni lezione Tailwind CSS Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Stile per input di testo e textarea
  2. Menu select e caselle di spunta
  3. Pattern per il layout dei moduli
  4. Validazione e stati di errore
← Torna a Tailwind CSS Academy