Tailwind ile bir kart, buton, input veya badge yapmak için ayrı bir bileşen kütüphanesine ihtiyacınız yok; birkaç utility sınıfını doğru sırayla düşünmek yeterli. Bir buton için iç boşluk (px-4 py-2), köşe (rounded-lg), renk (bg-blue-600 text-white), durumlar (hover:, focus-visible:, disabled:) ve geçiş (transition-colors) yazarsınız. Kart için kenarlık, arka plan, padding ve gölge; input için genişlik, kenarlık, odak görünümü ve placeholder rengi; badge için de küçük, yuvarlak bir etiket kalıbı kullanılır. Bu yazıdaki tüm kalıplar v4.3.5 ile derlendi ve her sınıfın ürettiği CSS gösterildi.
Kalıpların çıkış noktası Tailwind skill'indeki ortak örnekler (card, button, input). Bunları v4 adlarıyla güncelledik ve klavye odağı, devre dışı durum gibi eksik parçaları ekledik. Durum varyantlarının mantığı hover, focus ve active, form durumları form stilleri yazılarında; bütün seri ise Tailwind CSS öğrenme rehberi sayfasında.
Birincil buton

Aşağıdaki buton, simgeyle birlikte de düzgün hizalansın diye inline-flex kullanıyor ve içeriği ortalıyor. Odak görünümü için focus: yerine focus-visible: seçtik; böylece fareyle tıklandığında değil, klavyeyle gelindiğinde halka görünür. Belgeler focus-visible'ı, elementin klavyeyle odaklandığı durum için tarif eder.
<button type="button" class="inline-flex items-center justify-center gap-2 rounded-lg bg-blue-600 px-4 py-2 text-sm font-medium text-white transition-colors hover:bg-blue-700 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600 disabled:cursor-not-allowed disabled:opacity-50">Kaydet</button>v4.3.5 ile derlenen CSS (utilities katmanı tam, @property ve tema blokları kısaltıldı):
@layer utilities {
.inline-flex {
display: inline-flex;
}
.items-center {
align-items: center;
}
.justify-center {
justify-content: center;
}
.gap-2 {
gap: calc(var(--spacing) * 2);
}
.rounded-lg {
border-radius: var(--radius-lg);
}
.bg-blue-600 {
background-color: var(--color-blue-600);
}
.px-4 {
padding-inline: calc(var(--spacing) * 4);
}
.py-2 {
padding-block: calc(var(--spacing) * 2);
}
.text-sm {
font-size: var(--text-sm);
line-height: var(--tw-leading, var(--text-sm--line-height));
}
.font-medium {
--tw-font-weight: var(--font-weight-medium);
font-weight: var(--font-weight-medium);
}
.text-white {
color: var(--color-white);
}
.transition-colors {
transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to;
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
transition-duration: var(--tw-duration, var(--default-transition-duration));
}
@media (hover: hover) {
.hover\:bg-blue-700:hover {
background-color: var(--color-blue-700);
}
}
.focus-visible\:outline-2:focus-visible {
outline-style: var(--tw-outline-style);
outline-width: 2px;
}
.focus-visible\:outline-offset-2:focus-visible {
outline-offset: 2px;
}
.focus-visible\:outline-blue-600:focus-visible {
outline-color: var(--color-blue-600);
}
.disabled\:cursor-not-allowed:disabled {
cursor: not-allowed;
}
.disabled\:opacity-50:disabled {
opacity: 50%;
}
}
/* (kısaltıldı) */Aynı derlemenin tema bloğunda kullanılan değerler şöyle: --color-blue-600: oklch(54.6% 0.245 262.881), --color-blue-700: oklch(48.8% 0.243 264.376), --radius-lg: 0.5rem, --text-sm: 0.875rem, --font-weight-medium: 500, --default-transition-duration: 150ms ve --default-transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1). Kök yazı boyutu 16px kabul edilirse buton yatayda 16px, dikeyde 8px iç boşluk alır ve metin 14px olur.
Çıktıda üç ayrıntıya dikkat edin. transition-colors listesine outline-color da dahil; yükseltme kılavuzu bu yüzden outline rengini koşulsuz vermenizi önerir, aksi hâlde odaklanma anında renk geçişi garip görünebilir. Burada outline rengi yalnızca focus-visible: ile verildi; geçişin rengi de kapsamasını istemiyorsanız outline-blue-600 sınıfını varyantsız yazabilirsiniz. İkincisi, outline-2 genişliği verirken stili --tw-outline-style değişkeninden alır; bu değişkenin başlangıç değeri derlemenin @property bloğunda solid olarak tanımlı. Üçüncüsü, hover kuralı @media (hover: hover) içinde; dokunmatik ekranlarda üzerine gelme rengi uygulanmaz.
İkincil ve tehlike butonları
Varyantlar için aynı iskeleti koruyup yalnızca renk sınıflarını değiştirmek en kolay yoldur. İkincil buton beyaz zemin ve gri kenarlık kullanır; tehlike butonu kırmızı tonlarla çalışır:
<button class="rounded-lg border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-900 hover:bg-gray-50">Vazgeç</button>
<button class="rounded-lg bg-red-600 px-4 py-2 text-sm font-medium text-white hover:bg-red-700">Sil</button>v4.3.5 ile derlenen CSS'in hover kısmı:
/* (kısaltıldı) */
@media (hover: hover) {
.hover\:bg-gray-50:hover {
background-color: var(--color-gray-50);
}
.hover\:bg-red-700:hover {
background-color: var(--color-red-700);
}
}
/* (kısaltıldı) */Varyantları bir şablon dilinde seçerken her varyantın tam sınıf listesini yazın. Tailwind kaynak dosyalarını düz metin olarak tarar; bg-{{ renk }}-600 gibi parçalardan kurulan bir ad dosyada hiç geçmediği için CSS'i de üretilmez. Belgelerin önerdiği yol, her varyant adını önceden yazılmış tam sınıf listesine eşleyen bir tablo tutmaktır. Ayrıntılar sınıf tarama yazısında.
Kart
Skill'deki kart kalıbı rounded-lg border bg-white p-6 shadow-sm şeklinde. v4'te bu kalıbı aynen kullanırsanız bir sürprizle karşılaşırsınız: yükseltme kılavuzuna göre border sınıfının varsayılan rengi artık gray-200 değil, currentColor. Yani kenarlık metin rengiyle, genellikle koyu renkte çizilir. Bu yüzden kenarlık rengini her zaman açıkça yazın:
<div class="rounded-xl border border-gray-200 bg-white p-6 shadow-sm">
<h3 class="text-lg font-semibold text-gray-900">Başlangıç paketi</h3>
<p class="mt-1 text-sm text-gray-500">Kişisel siteler için.</p>
</div>v4.3.5 ile derlenen CSS'in kartın kendi sınıflarına ait kısmı:
/* (kısaltıldı) */
.rounded-xl {
border-radius: var(--radius-xl);
}
.border {
border-style: var(--tw-border-style);
border-width: 1px;
}
.border-gray-200 {
border-color: var(--color-gray-200);
}
.bg-white {
background-color: var(--color-white);
}
.p-6 {
padding: calc(var(--spacing) * 6);
}
.shadow-sm {
--tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 1px 2px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1));
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
}
/* (kısaltıldı) */Tema bloğunda --radius-xl: 0.75rem ve --color-gray-200: oklch(92.8% 0.006 264.531) tanımlı. Gölge, box-shadow özelliğini beş değişkenden birleştiriyor; bu sayede aynı elemente ring ve gölge birlikte verilebiliyor. v3'ten gelenler için not: yükseltme kılavuzu, v3'teki shadow sınıfının v4'te shadow-sm, v3'teki shadow-sm'nin de shadow-xs olarak yeniden adlandırıldığını belirtir. Kart içindeki başlıkta text-lg font-semibold kullanmamızın nedeni Preflight'ın başlık boyutlarını sıfırlamasıdır; bkz. Preflight.
Kartı tıklanabilir yapmak isterseniz dış elemente group verip içerideki başlığı group-hover: ile renklendirebilirsiniz; bu kalıp group ve peer yazısında. Kartları bir ızgarada yan yana dizmek için grid-cols yazısına bakın.
Badge (durum etiketi)

Badge, kısa bir durum bilgisini öne çıkaran küçük ve yuvarlak bir etikettir. Açık bir zemin rengi ile aynı renk ailesinin koyu tonunu metinde kullanmak okunabilir bir eşleşme verir:
<span class="inline-flex items-center rounded-full bg-green-100 px-2.5 py-0.5 text-xs font-medium text-green-800">Aktif</span>v4.3.5 ile derlenen CSS'in badge'e özgü kuralları:
/* (kısaltıldı) */
.rounded-full {
border-radius: calc(infinity * 1px);
}
.bg-green-100 {
background-color: var(--color-green-100);
}
.px-2\.5 {
padding-inline: calc(var(--spacing) * 2.5);
}
.py-0\.5 {
padding-block: calc(var(--spacing) * 0.5);
}
.text-xs {
font-size: var(--text-xs);
line-height: var(--tw-leading, var(--text-xs--line-height));
}
.text-green-800 {
color: var(--color-green-800);
}
/* (kısaltıldı) */rounded-full artık 9999px değil, calc(infinity * 1px) üretiyor; sonuç yine tam yuvarlak köşedir. Ondalıklı aralık değerleri seçicide kaçışlı nokta ile yazılıyor (.px-2\.5). text-xs için tema bloğu --text-xs: 0.75rem ve --text-xs--line-height: calc(1 / 0.75) veriyor. Renk ailesini değiştirmek için bg-amber-100 text-amber-800 veya bg-red-100 text-red-800 gibi aynı kalıbı kullanabilirsiniz; palet ayrıntıları renk paleti yazısında.
Etiketli input
Skill'deki input kalıbı w-full px-3 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent placeholder:text-gray-400 şeklinde. Bu kalıpta iki v4 farkı var: outline-none v4'te outline-style: none anlamına gelir ve yükseltme kılavuzu eski davranış için outline-hidden adını verir; border da yine renk belirtilmezse currentColor kullanır. Aşağıdaki sürümde odak göstergesini outline ile verdik ve hatalı değeri yalnızca kullanıcı alanla etkileşime girdikten sonra gösteren user-invalid: varyantını kullandık:
<label for="eposta" class="block text-sm font-medium text-gray-700">E-posta</label>
<input id="eposta" type="email" required placeholder="ad@ornek.com"
class="w-full rounded-lg border border-gray-300 px-3 py-2 placeholder:text-gray-400 focus:border-blue-500 focus:outline-2 focus:outline-blue-500/40 user-invalid:border-red-500 disabled:bg-gray-100">
<p class="mt-1 text-sm text-gray-500">Size yalnızca fatura gönderilir.</p>v4.3.5 ile derlenen CSS'in input'a özgü durum kuralları:
/* (kısaltıldı) */
.placeholder\:text-gray-400::placeholder {
color: var(--color-gray-400);
}
.user-invalid\:border-red-500:user-invalid {
border-color: var(--color-red-500);
}
.focus\:border-blue-500:focus {
border-color: var(--color-blue-500);
}
.focus\:outline-2:focus {
outline-style: var(--tw-outline-style);
outline-width: 2px;
}
.focus\:outline-blue-500\/40:focus {
outline-color: color-mix(in srgb, oklch(62.3% 0.214 259.815) 40%, transparent);
@supports (color: color-mix(in lab, red, red)) {
outline-color: color-mix(in oklab, var(--color-blue-500) 40%, transparent);
}
}
.disabled\:bg-gray-100:disabled {
background-color: var(--color-gray-100);
}
/* (kısaltıldı) *//40 opaklık eki, outline rengini color-mix() ile yüzde 40 görünür yapıyor; @supports bloğu ise tarayıcı oklab karışımını destekliyorsa tema değişkeniyle ikinci bir değer veriyor. Bu ekin ayrıntıları renk opaklığı yazısında. label elementindeki for="eposta" ile input'un id değerinin eşleşmesi, tıklamayla odaklanmayı ve ekran okuyucuların alan adını okumasını sağlar; görsel olarak etiket istemiyorsanız onu silmek yerine sr-only ile gizleyin. Yardım metnindeki mt-1 sınıfı da ilginç bir ayrıntı veriyor: bu derlemede .mt-1 kuralı margin-top: var(--spacing); olarak, yani çarpansız üretildi.
@apply ile bileşen sınıfı mı, şablon mu?
Aynı buton yüzlerce sayfada tekrar ediyorsa sınıf listesini bir yerde toplamak istersiniz. Belgeler bunun için öncelikle React, Vue, Svelte bileşenlerini ya da Blade, Twig, Nunjucks gibi şablon parçalarını önerir. Tek elementlik küçük kalıplarda ise @layer components içinde @apply ile bir sınıf yazmak kabul edilebilir:
<button class="btn-ana rounded-full">Gönder</button>@import "tailwindcss" source(none);
@source "./ornek.html";
@layer components {
.btn-ana {
@apply rounded-lg bg-blue-600 px-4 py-2 font-medium text-white hover:bg-blue-700;
}
}v4.3.5 ile derlenen CSS (@property blokları kısaltıldı):
@layer utilities {
.rounded-full {
border-radius: calc(infinity * 1px);
}
}
@layer components {
.btn-ana {
border-radius: var(--radius-lg);
background-color: var(--color-blue-600);
padding-inline: calc(var(--spacing) * 4);
padding-block: calc(var(--spacing) * 2);
--tw-font-weight: var(--font-weight-medium);
font-weight: var(--font-weight-medium);
color: var(--color-white);
&:hover {
@media (hover: hover) {
background-color: var(--color-blue-700);
}
}
}
}
/* (kısaltıldı) */@apply, sınıfların bildirimlerini olduğu gibi .btn-ana içine kopyaladı; hover varyantı da iç içe bir kural olarak geldi. Bileşen components katmanında olduğu için HTML'deki rounded-full utility sınıfı rounded-lg değerini ezer ve buton hap biçiminde olur. Bu yöntemin artıları ve eksileri, Vue veya Svelte stil bloklarında gereken @reference direktifi ile birlikte @apply ve bileşen sınıfları yazısında.
Kalıpları birleştirmek: paket kartı
Tek tek kalıplar hazır olduğunda gerçek bir arayüz parçası kurmak, onları iç içe yerleştirmekten ibarettir. Aşağıdaki örnekte kartın içine bir başlık satırı, sağına bir badge, altına kısa bir açıklama ve en alta bir buton koyduk. Kartlar sm ve üstünde iki sütunlu bir ızgarada yan yana duruyor:
<div class="grid gap-6 sm:grid-cols-2">
<div class="flex flex-col gap-4 rounded-xl border border-gray-200 bg-white p-6 shadow-sm">
<div class="flex items-center justify-between">
<h3 class="text-lg font-semibold text-gray-900">Başlangıç</h3>
<span class="inline-flex items-center rounded-full bg-green-100 px-2.5 py-0.5 text-xs font-medium text-green-800">Önerilen</span>
</div>
<p class="text-sm text-gray-500">Kişisel siteler için.</p>
<button type="button" class="mt-auto inline-flex items-center justify-center rounded-lg bg-blue-600 px-4 py-2 text-sm font-medium text-white hover:bg-blue-700 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600">Seç</button>
</div>
</div>v4.3.5 ile derlenen CSS'in bu birleşime özgü kuralları:
@layer utilities {
.mt-auto {
margin-top: auto;
}
/* (kısaltıldı) */
.flex-col {
flex-direction: column;
}
/* (kısaltıldı) */
.text-lg {
font-size: var(--text-lg);
line-height: var(--tw-leading, var(--text-lg--line-height));
}
/* (kısaltıldı) */
.font-semibold {
--tw-font-weight: var(--font-weight-semibold);
font-weight: var(--font-weight-semibold);
}
/* (kısaltıldı) */
@media (width >= 40rem) {
.sm\:grid-cols-2 {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
}
}Kartı flex flex-col gap-4 ile dikey bir flex kapsayıcısı yaptık; böylece içerideki parçalar arasına tek tek margin vermek yerine tek bir boşluk değeri yetti. Butondaki mt-auto, çıktıda margin-top: auto üretiyor ve dikey flex içinde kalan boşluğu butonun üstüne topluyor. Izgaradaki kartlar aynı satırda varsayılan olarak eşit yükseklikte uzadığı için, açıklamaları farklı uzunlukta olan iki kartın butonları da alt kenarda hizalanır. Tema bloğunda --text-lg: 1.125rem ve --font-weight-semibold: 600 değerleri yer alıyor. Kartları ızgaraya dizmek ve sütun sayısını breakpoint'lere göre değiştirmek için responsive tasarım yazısına bakabilirsiniz.
Bu birleşimde dikkat edilmesi gereken tek şey, aynı bileşenin farklı parçalarında aynı özelliği iki kez ayarlamamaktır. Örneğin butonun genişliğini kart içinde w-full ile tam yapmak isterseniz bunu yalnızca butona yazın; kartın kendisine bir genişlik sınıfı eklemek ayrı bir karardır.
Bir kalıbı kendi projenize uyarlarken
Hazır bir sınıf listesini kopyalamak kolaydır; zor olan, onu kendi tasarımınıza uyarlarken tutarlılığı korumaktır. Kalıpları değiştirirken şu soruları sırayla sormak işinizi kolaylaştırır. İlk soru boyuttur: buton ve input aynı satırda yan yana duracaksa ikisinin dikey iç boşluğu ve yazı boyutu aynı olmalıdır; bu yazıdaki örneklerde ikisi de py-2 kullanıyor. İkinci soru renk ailesidir: birincil buton, odak halkası ve input'un odak kenarlığı aynı renk ailesinden gelirse kullanıcı hangi öğenin etkileşimli olduğunu daha kolay anlar. Biz mavi aileyi seçtik; markanızın rengini kullanmak için onu @theme içinde bir değişken olarak tanımlarsınız ve sınıflar otomatik olarak üretilir.
Üçüncü soru durumlardır. Her etkileşimli öğe için en az dört durumu düşünün: normal, üzerine gelme, klavye odağı ve devre dışı. Hata durumu taşıyabilen form alanlarında buna bir beşinci durum eklenir. Bu durumlardan birini atlamak genellikle fark edilmez, ta ki bir kullanıcı klavyeyle gezinene veya devre dışı bir butona tıklamaya çalışana kadar. Dördüncü soru karanlık temadır: projeniz dark: kullanıyorsa her zemin, metin ve kenarlık rengi için bir karşılık yazmanız gerekir; bunu kalıbı ilk kurarken yapmak, sonradan eklemekten çok daha kolaydır. Son olarak, aynı kalıp birden fazla dosyada tekrar ediyorsa belgelerin önerdiği gibi onu bir şablon parçasına taşıyın ve dışarıdan sınıf eklemek yerine seçenekler kabul etmesini sağlayın.
Sık yapılan hatalar

- Kenarlık rengini yazmamak: v4'te
bordervarsayılan olarakcurrentColorkullanır; açık gri bir çizgi içinborder-gray-200ekleyin. - Odak göstergesini silip yerine bir şey koymamak:
outline-noneveyaoutline-hiddenyazdıysanızfocus-visible:ile kendi göstergenizi ekleyin. - Varyant sınıflarını parçalardan kurmak:
bg-{{ renk }}-600üretilmez; tam sınıf adlarını yazın. - Bileşen sınıfını katmansız yazmak:
.btn-anakatmansız olursarounded-fullonu ezemez. - v3 gölge adlarını aynen taşımak: v3'teki
shadowgörünümü v4'teshadow-smadını taşır.
Sık Sorulan Sorular
Butonlarda imleç neden el işaretine dönmüyor?
Yükseltme kılavuzuna göre v4 Preflight'ı butonlarda cursor: default kullanır. El işareti isteyen butona cursor-pointer sınıfı ekleyebilir ya da kılavuzdaki gibi @layer base içinde button:not(:disabled) için cursor: pointer tanımlayabilirsiniz.
Devre dışı butonda hover rengi de değişir mi?
Bu derlemedeki hover:bg-blue-700 kuralı yalnızca :hover sözde sınıfına bakar, :disabled durumunu dikkate almaz. Devre dışı butonda hover rengini istemiyorsanız disabled:pointer-events-none kullanabilir veya belgelerdeki not- varyantıyla hover:not-disabled:bg-blue-700 yazabilirsiniz. Bu sınıf v4.3.5 derlemesinde .hover\:not-disabled\:bg-blue-700:hover:not(:disabled) seçicisini üretti, yani yalnızca devre dışı olmayan butonda çalışır.
focus ile focus-visible arasında hangisini seçmeliyim?
Butonlar için focus-visible genellikle daha uygundur, çünkü yalnızca klavye odağında görünür. Input'larda ise odağın her durumda görünmesi istenir; bu yüzden input örneğinde focus: kullandık.
Bu kalıpları karanlık temaya nasıl uyarlarım?
Her renk sınıfının yanına dark: varyantlı bir karşılık eklersiniz, örneğin kart için dark:border-gray-800 dark:bg-gray-900. Varsayılan davranış ve sınıfla geçiş dark mode yazısında.
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 CSS öğrenme rehberi · Hover ve focus durumları · Form stilleri · @apply ve bileşen sınıfları · Sayfa düzeni örnekleri · Erişilebilirlik sınıfları