Tailwind CSS'te form alanlarını durumlarına göre biçimlendirmek için durum varyantlarını kullanırsınız: geçersiz alan için invalid:border-red-500, kullanıcı etkileşiminden sonra geçersiz olan alan için user-invalid:border-red-500, işaretli kutu için checked:bg-sky-600, devre dışı alan için disabled:bg-gray-50. Placeholder metni placeholder:, dosya seçme düğmesi file: ile biçimlenir. Onay kutusu ve radyo rengini accent-*, tarayıcının varsayılan kontrol görünümünü appearance-none, içeriğe göre büyüyen alanları field-sizing-content yönetir.

Bu yazıda form durum varyantlarının hangi sözde sınıfı ürettiğini, invalid ile user-invalid farkını, sözde öğe varyantlarını, form kontrolü utility'lerini ve tam bir form alanı örneğini v4.3.5 ile derlenmiş gerçek çıktılarla inceliyoruz. Genel etkileşim varyantları (hover, focus, focus-visible) hover, focus ve active durumları yazısında, alanın yanındaki mesajı alanın durumuna göre göstermek group ve peer kullanımı yazısında; serinin tamamı Tailwind öğrenme rehberinde.

Form durum varyantları tablosu

Form durum varyantları tablosu: required, optional, valid, invalid

Resmî durum sayfasının hızlı başvuru tablosunda form ile ilgili varyantların her biri tek bir CSS sözde sınıfına karşılık gelir. Aşağıdaki eşlemeler v4.3.5 derlemesiyle doğrulandı; örneğin required:border-red-300 .required\:border-red-300:required, in-range:border-green-500 .in-range\:border-green-500:in-range seçicisini üretti.

VaryantCSSAnlamı
required:requiredrequired özniteliği olan alan
optional:optionalrequired olmayan alan
valid:validDeğeri doğrulamayı geçen alan
invalid:invalidDeğeri doğrulamayı geçemeyen alan
user-valid:user-validKullanıcı etkileşiminden sonra geçerli
user-invalid:user-invalidKullanıcı etkileşiminden sonra geçersiz
disabled / enabled:disabled / :enabledDevre dışı veya etkin kontrol
read-only:read-onlySalt okunur alan
checked:checkedİşaretli onay kutusu, radyo veya seçenek
indeterminate:indeterminateBelirsiz durumdaki onay kutusu
default:defaultVarsayılan seçili seçenek
in-range / out-of-range:in-range / :out-of-rangemin ve max sınırları içinde veya dışında
placeholder-shown:placeholder-shownPlaceholder görünürken (alan boş)
autofill:autofillTarayıcı otomatik doldurduğunda

Sayısal alanlarda in-range ve out-of-range çifti kullanışlıdır. <input type="number" min="1" max="10" class="out-of-range:border-red-500 in-range:border-green-500"> derlendiğinde çıktıda önce .in-range\:border-green-500:in-range, sonra .out-of-range\:border-red-500:out-of-range kuralı yer aldı. Değer 1 ile 10 arasındaysa yeşil, dışındaysa kırmızı kenarlık uygulanır; iki sözde sınıf aynı anda doğru olamayacağı için aralarındaki sıra burada sonucu değiştirmez.

Skill'deki kısa form listesi invalid, valid, required, placeholder ve checked varyantlarını gösterir; geri kalanlar resmî sayfadan gelir. Hepsi diğer varyantlar gibi yığılabilir ve her utility ile kullanılabilir.

invalid ile user-invalid arasındaki fark

Bir e-posta alanını geçersizken kırmızı göstermek ilk akla gelen şeydir. Resmî sayfaya göre user-* varyantları kullanıcı etkileşiminden sonra uygulanır; invalid ise bunu beklemez. Aşağıdaki alanda iki yaklaşımı ve odak durumunu birlikte kullandık.

html
<input type="email" required class="border border-gray-300 invalid:border-red-500 user-invalid:border-red-500 focus:border-sky-500 focus:invalid:border-red-500">

v4.3.5 ile derlenen CSS:

css
/* (kısaltıldı) */
@layer utilities {
  .border {
    border-style: var(--tw-border-style);
    border-width: 1px;
  }
  .border-gray-300 {
    border-color: var(--color-gray-300);
  }
  .invalid\:border-red-500:invalid {
    border-color: var(--color-red-500);
  }
  .user-invalid\:border-red-500:user-invalid {
    border-color: var(--color-red-500);
  }
  .focus\:border-sky-500:focus {
    border-color: var(--color-sky-500);
  }
  .focus\:invalid\:border-red-500:focus:invalid {
    border-color: var(--color-red-500);
  }
}

Bu alan required olduğu için, sayfa açılır açılmaz boştur ve :invalid durumundadır. Yani invalid:border-red-500 kullanıcı daha hiçbir şey yapmadan kenarlığı kırmızı yapar; boş bir formun baştan kırmızı görünmesi kullanıcıyı yanlış yönlendirir. user-invalid:border-red-500 ise yalnızca kullanıcı alanla etkileştikten sonra devreye girer. Pratikte çoğu formda yalnızca user-invalid kullanmak yeterlidir; burada ikisini birlikte karşılaştırma için yazdık.

Sıralamaya da dikkat edin: focus:border-sky-500 kuralı invalid kurallarından sonra geliyor. Geçersiz bir alan odaklanınca kenarlık mavi olur, hata rengi kaybolur. Bunu önlemek için resmî sayfadaki gibi focus:invalid: yığması eklenir; :focus:invalid seçicisi iki sözde sınıf içerdiği için daha seçicidir ve ayrıca dosyada en sonda durur. Tema değerleri: --color-red-500 oklch(63.7% 0.237 25.331), --color-sky-500 oklch(68.5% 0.169 237.323), --color-gray-300 oklch(87.2% 0.01 258.338).

disabled ve read-only alanlar

disabled ve read-only alanlar

Devre dışı bir alanın kullanıcıya farklı görünmesi, neden yazamadığını anlamasını kolaylaştırır. Resmî sayfadaki örnek disabled: ile arka planı, metin rengini, kenarlığı ve gölgeyi değiştirir; biz kısa bir sürümünü derledik.

html
<input type="text" value="kullanici1" disabled class="border disabled:bg-gray-50 disabled:text-gray-500 disabled:cursor-not-allowed read-only:bg-gray-100">

v4.3.5 ile derlenen CSS:

css
/* (kısaltıldı) */
@layer utilities {
  .border {
    border-style: var(--tw-border-style);
    border-width: 1px;
  }
  .read-only\:bg-gray-100:read-only {
    background-color: var(--color-gray-100);
  }
  .disabled\:cursor-not-allowed:disabled {
    cursor: not-allowed;
  }
  .disabled\:bg-gray-50:disabled {
    background-color: var(--color-gray-50);
  }
  .disabled\:text-gray-500:disabled {
    color: var(--color-gray-500);
  }
}

read-only kuralı disabled kurallarının önüne yerleşti. Devre dışı bir input :read-only ile de eşleşebilir ve o durumda iki arka plan kuralı birden geçerli olur; bu durumda sonra gelen disabled:bg-gray-50 kazanır. Bu yüzden ikisini aynı öğede kullanacaksanız sırayı derleyicinin belirlediğini bilin ve sonucu çıktıdan kontrol edin. cursor-not-allowed skill'deki buton kalıbında da disabled: ile birlikte gösterilir.

Onay kutusu ve radyo: accent-* mi, appearance-none mı?

İşaretli kontrolleri biçimlendirmenin iki yolu vardır. En hafifi accent-*: resmî accent-color sayfasına göre tarayıcının varsayılan rengini ezer ve kontrolün geri kalanını tarayıcıya bırakır. Tam kontrol istiyorsanız appearance-none ile tarayıcının yerel görünümünü kaldırır, checked: ile kendi görünümünüzü çizersiniz.

html
<input type="checkbox" class="size-4 accent-emerald-600">
<input type="checkbox" class="size-5 appearance-none rounded border border-gray-400 checked:border-sky-600 checked:bg-sky-600">

v4.3.5 ile derlenen CSS:

css
/* (kısaltıldı) */
@layer utilities {
  .size-4 {
    width: calc(var(--spacing) * 4);
    height: calc(var(--spacing) * 4);
  }
  .size-5 {
    width: calc(var(--spacing) * 5);
    height: calc(var(--spacing) * 5);
  }
  .appearance-none {
    appearance: none;
  }
  .rounded {
    border-radius: 0.25rem;
  }
  .border {
    border-style: var(--tw-border-style);
    border-width: 1px;
  }
  .border-gray-400 {
    border-color: var(--color-gray-400);
  }
  .accent-emerald-600 {
    accent-color: var(--color-emerald-600);
  }
  .checked\:border-sky-600:checked {
    border-color: var(--color-sky-600);
  }
  .checked\:bg-sky-600:checked {
    background-color: var(--color-sky-600);
  }
}

İlk kutu tarayıcının kendi onay işaretini korur, yalnızca vurgu rengi zümrüt yeşili olur. İkinci kutuda yerel görünüm kaldırıldığı için işaret de kaybolur; işaretlendiğinde yalnızca arka plan ve kenarlık rengi değişir, onay işaretini ayrıca bir SVG veya sözde öğeyle sizin çizmeniz gerekir. Resmî appearance sayfası bunun için kutunun yanına bir SVG koyup peer-checked:visible ile göstermeyi örnekler.

accent-* için birkaç ayrıntı daha: keyfi değer accent-[#50d71e], CSS değişkeni kısayolu accent-(--vurgu) biçimindedir ve derlendiğinde sırasıyla accent-color: #50d71e ve accent-color: var(--vurgu) üretti. Opaklık değiştiricisi de derlenir; accent-purple-500/25 bir color-mix() kuralına dönüştü. Ancak resmî sayfa, vurgu renginde opaklığın sınırlı tarayıcı desteği olduğunu ve şimdilik yalnızca Firefox'ta çalıştığını belirtir. Renk paleti Tailwind renk paleti, opaklık değiştiricisi renk opaklığı yazısında.

Sözde öğeler: placeholder, file ve after

Bazı varyantlar bir duruma değil, öğenin bir parçasına stil verir. placeholder: ::placeholder, file: ise dosya girişindeki düğmeyi seçen ::file-selector-button sözde öğesini hedefler. placeholder: ile placeholder-shown: karıştırılmamalıdır: ilki placeholder metninin kendisini biçimler, ikincisi placeholder görünürken input'un kendisini.

html
<input class="placeholder:text-gray-400 placeholder-shown:border-gray-300" placeholder="ornek@alanadi.com">
<input type="file" class="text-sm file:mr-4 file:rounded-md file:border-0 file:bg-sky-50 file:px-3 file:py-2 hover:file:bg-sky-100">

v4.3.5 ile derlenen CSS:

css
/* (kısaltıldı) */
@layer utilities {
  .text-sm {
    font-size: var(--text-sm);
    line-height: var(--tw-leading, var(--text-sm--line-height));
  }
  .file\:mr-4::file-selector-button {
    margin-right: calc(var(--spacing) * 4);
  }
  .file\:rounded-md::file-selector-button {
    border-radius: var(--radius-md);
  }
  .file\:border-0::file-selector-button {
    border-style: var(--tw-border-style);
    border-width: 0px;
  }
  .file\:bg-sky-50::file-selector-button {
    background-color: var(--color-sky-50);
  }
  .file\:px-3::file-selector-button {
    padding-inline: calc(var(--spacing) * 3);
  }
  .file\:py-2::file-selector-button {
    padding-block: calc(var(--spacing) * 2);
  }
  .placeholder\:text-gray-400::placeholder {
    color: var(--color-gray-400);
  }
  .placeholder-shown\:border-gray-300:placeholder-shown {
    border-color: var(--color-gray-300);
  }
  @media (hover: hover) {
    .hover\:file\:bg-sky-100:hover::file-selector-button {
      background-color: var(--color-sky-100);
    }
  }
}

hover:file:bg-sky-100 sınıfında sıra önemlidir. Soldan sağa okunduğunda "input'un üzerine gelindiğinde, onun dosya düğmesi" anlamına gelir ve seçici :hover::file-selector-button olur. Ters yazımı file:hover:bg-sky-100 de derlendi ve ::file-selector-button:hover üretti: bu kez yalnızca düğmenin kendi üzerine gelindiğinde çalışır. Resmî sayfa ilk biçimi kullanır. Zorunlu alan işareti için after: sözde öğesi de kullanışlıdır: after:ml-0.5 after:text-red-500 after:content-['*'] derlendiğinde ::after kurallarında --tw-content: '*' ve content: var(--tw-content) oluştu. Resmî sayfa yine de içerik DOM'da kalmalıysa gerçek bir öğe kullanmayı önerir.

field-sizing: içeriğe göre büyüyen alan

Resmî field-sizing sayfasına göre field-sizing-content bir form kontrolünün boyutunu içeriğine göre ayarlamasını sağlar, field-sizing-fixed ise sabit boyutta tutar. Sınırsız büyümeyi önlemek için min ve max yükseklikle birlikte kullanmak mantıklıdır.

html
<textarea class="field-sizing-content min-h-20 max-h-60 w-full border" rows="2"></textarea>

v4.3.5 ile derlenen CSS (textarea sınıfları):

css
@layer utilities {
  /* (kısaltıldı) */
  .field-sizing-content {
    field-sizing: content;
  }
  .max-h-60 {
    max-height: calc(var(--spacing) * 60);
  }
  .min-h-20 {
    min-height: calc(var(--spacing) * 20);
  }
  .w-full {
    width: 100%;
  }
}

Alan en az 5rem, en fazla 15rem yükseklikte kalır; arada içeriğe göre büyür. Resmî Tailwind CSS: Compatibility sayfası field-sizing: content özelliğini sınırlı tarayıcı desteği olan yeni platform özellikleri arasında sayar ve hedeflediğiniz tarayıcılar desteklemiyorsa bu utility'leri kullanmamayı söyler. Tarayıcılar tanımadıkları bir CSS özelliğini yok saydığı için desteklemeyen tarayıcıda alan normal boyutlandırmasıyla kalır; rows değerini makul tutmak bu durumda iyi bir yedektir. Boyut sınıfları width, height ve size yazısında.

Uygulamalı örnek: durumları olan bir e-posta alanı

Şimdiye kadarki parçaları tek bir alanda birleştirelim: zorunlu alan işareti olan bir etiket, placeholder rengi, odak rengi, yalnızca etkileşim sonrası gösterilen hata kenarlığı ve hata mesajı. Mesaj için peer kullanıyoruz; input mesajdan önce gelmeli.

html
<label for="eposta" class="after:ml-0.5 after:text-red-500 after:content-['*']">E-posta</label>
<input id="eposta" type="email" required placeholder="ornek@alanadi.com"
  class="peer w-full rounded-md border border-gray-300 px-3 py-2 placeholder:text-gray-400 focus:border-sky-500 user-invalid:border-red-500 focus:user-invalid:border-red-500">
<p class="invisible text-sm text-red-600 peer-user-invalid:visible">Geçerli bir e-posta adresi girin.</p>

v4.3.5 ile derlenen CSS (durum ve sözde öğe kuralları; düzen ve renk sınıfları çıkarıldı):

css
@layer utilities {
  /* (kısaltıldı) */
  :is(:where(.peer):user-invalid ~ .peer-user-invalid\:visible) {
    visibility: visible;
  }
  .placeholder\:text-gray-400::placeholder {
    color: var(--color-gray-400);
  }
  .after\:ml-0\.5::after {
    content: var(--tw-content);
    margin-left: calc(var(--spacing) * 0.5);
  }
  .after\:text-red-500::after {
    content: var(--tw-content);
    color: var(--color-red-500);
  }
  .after\:content-\[\'\*\'\]::after {
    --tw-content: '*';
    content: var(--tw-content);
  }
  .user-invalid\:border-red-500:user-invalid {
    border-color: var(--color-red-500);
  }
  .focus\:border-sky-500:focus {
    border-color: var(--color-sky-500);
  }
  .focus\:user-invalid\:border-red-500:focus:user-invalid {
    border-color: var(--color-red-500);
  }
}

Son üç kuralın sırası, bu örnekteki focus:user-invalid: sınıfının neden eklendiğini açıklar. Derlenen dosyada focus:border-sky-500, user-invalid:border-red-500 kuralından sonra gelir ve ikisi aynı ağırlıktadır; bu sınıf olmasaydı, geçersiz alana geri dönüp odaklanan kullanıcı hata rengi yerine mavi kenarlık görürdü. :focus:user-invalid seçicisi hem daha seçici hem de en sondadır, böylece odaktayken de kırmızı kalır. Aynı sorunu invalid bölümünde focus:invalid: ile çözmüştük; kural her iki varyant için de aynıdır.

Bu işaretlemedeki her durum sınıfının ürettiği kuralı yukarıdaki bölümlerde gördük:after: kuralları ::after, placeholder: ::placeholder, focus: :focus, user-invalid: :user-invalid, mesajdaki peer-user-invalid:visible ise :is(:where(.peer):user-invalid ~ .peer-user-invalid\:visible) seçicisine dönüşür. Sayfa ilk açıldığında alan boş ve required olduğu hâlde ne kenarlık kırmızıdır ne de mesaj görünür; kullanıcı alanla etkileşip geçersiz bir değer bıraktığında, tarayıcı :user-invalid durumunu uyguladığı anda ikisi birlikte devreye girer. Bu, invalid yerine user-invalid kullanmanın sağladığı kazançtır. Kart ve buton gibi diğer bileşenlerle birlikte tam bir form görünümü kart, buton ve input örnekleri yazısında.

Sık yapılan hatalar

Sık yapılan hatalar: Boş zorunlu alanın baştan kırmızı görünmesi, Odakta hata renginin kaybolması, placeholder ile placeholder-shown'ı karıştırmak, appearance-none sonrası işaret...
  • Boş zorunlu alanın baştan kırmızı görünmesi: invalid: etkileşimi beklemez; user-invalid: kullanın.
  • Odakta hata renginin kaybolması: focus: kuralı invalid kurallarından sonra gelir. focus:invalid: veya focus:user-invalid: ekleyin.
  • placeholder ile placeholder-shown'ı karıştırmak: İlki metni, ikincisi input'u biçimler.
  • appearance-none sonrası işaret beklemek: Yerel onay işareti de kalkar; kendi işaretinizi çizmeniz gerekir.
  • Vurgu rengine opaklık vermek: accent-purple-500/25 derlenir ama resmî sayfaya göre yalnızca Firefox'ta çalışır.
  • hover:file: ile file:hover:'ı karıştırmak: Biri input'a, diğeri düğmeye gelinmesine bakar.

Sık Sorulan Sorular

Tailwind'de form eklentisi kurmak gerekiyor mu?

Bu yazıdaki varyantların ve utility'lerin hepsi v4.3.5 çekirdeğinde derlendi; ek bir eklenti kullanılmadı. Form alanlarını sıfırlayan ayrı eklentiler bu serinin kapsamı dışındadır.

Checkbox rengini en kolay nasıl değiştiririm?

accent-sky-600 gibi bir accent-* sınıfı yeterlidir; tarayıcı kontrolü korunur, yalnızca rengi değişir. Tamamen özel bir görünüm için appearance-none ve checked: varyantlarına geçin.

Seçili radyo düğmesinin bulunduğu kartı nasıl vurgularım?

Radyonun kendisi için checked:, onu içeren etiket veya kart için has-checked: kullanılır. has-checked:bg-indigo-50 derlendiğinde :has(:checked) seçicisini üretir; kart, içindeki radyo seçildiği anda vurgulanır ve radyonun kart içindeki konumu önemli olmaz. Tam örnek ve peer ile karşılaştırması group ve peer kullanımı yazısında.

user-invalid ne zaman devreye girer?

Resmî sayfaya göre user-* varyantları kullanıcı etkileşiminden sonra uygulanır. Derlenen kural doğrudan :user-invalid sözde sınıfıdır; ne zaman eşleşeceğine tarayıcı karar verir.

Otomatik doldurulan alanı ayrıca biçimlendirebilir miyim?

autofill: varyantı :autofill sözde sınıfını hedefler; autofill:bg-yellow-50 derlendiğinde .autofill\:bg-yellow-50:autofill üretti. Tarayıcının kendi otomatik doldurma stili bununla ne ölçüde ezilebilir, tarayıcıdan tarayıcıya değişebilir; sonucu hedef tarayıcılarınızda deneyin.

Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.

İlgili içerikler: Tailwind öğrenme rehberi · hover ve focus · group ve peer · Kart, buton, input örnekleri · Erişilebilirlik · HTML öğrenme rehberi