İçeriğe geç
CSS

Tailwind CSS Component Pattern'leri: Card, Button, Form

Tarık Tunç
Tailwind CSS Component Pattern'leri: Card, Button, Form

Tailwind CSS Component Pattern'leri: Card, Button, Form

Tailwind CSS ile tutarlı ve yeniden kullanılabilir UI component'leri oluşturmak, utility-first yaklaşımın en önemli pratiğidir. Bu rehberde en yaygın UI component'lerini — Card, Button, Form, Modal, Badge ve Navigation — profesyonel seviyede Tailwind ile nasıl oluşturacağınızı, varyant yönetimini ve component organizasyonunu detaylıca ele alacağız.

1. Button Component ve Varyantları

Button, her uygulamanın temel yapı taşıdır. Boyut, renk, durum ve ikon varyantlarıyla esnek bir button sistemi oluşturmak önemlidir.

<!-- Primary Button -->
<button class="inline-flex items-center justify-center gap-2
               px-4 py-2 text-sm font-medium rounded-lg
               bg-blue-500 text-white
               hover:bg-blue-600 active:bg-blue-700
               focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2
               disabled:opacity-50 disabled:cursor-not-allowed
               transition-colors duration-150">
  Kaydet
</button>

<!-- Secondary / Outline Button -->
<button class="inline-flex items-center justify-center gap-2
               px-4 py-2 text-sm font-medium rounded-lg
               border-2 border-gray-300 text-gray-700 bg-transparent
               hover:bg-gray-50 hover:border-gray-400
               dark:border-gray-600 dark:text-gray-300 dark:hover:bg-gray-800
               focus:outline-none focus:ring-2 focus:ring-gray-500 focus:ring-offset-2
               transition-colors duration-150">
  İptal
</button>

<!-- Ghost Button -->
<button class="inline-flex items-center justify-center gap-2
               px-4 py-2 text-sm font-medium rounded-lg
               text-gray-600 hover:bg-gray-100 hover:text-gray-900
               dark:text-gray-400 dark:hover:bg-gray-800 dark:hover:text-gray-100
               transition-colors duration-150">
  Daha Fazla
</button>

<!-- Danger Button -->
<button class="inline-flex items-center justify-center gap-2
               px-4 py-2 text-sm font-medium rounded-lg
               bg-red-500 text-white
               hover:bg-red-600 active:bg-red-700
               focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2
               transition-colors duration-150">
  Sil
</button>

<!-- Button Boyutları -->
<button class="px-3 py-1.5 text-xs rounded-md ...">Küçük</button>
<button class="px-4 py-2 text-sm rounded-lg ...">Normal</button>
<button class="px-6 py-3 text-base rounded-lg ...">Büyük</button>
<button class="px-8 py-4 text-lg rounded-xl ...">Çok Büyük</button>

<!-- Loading State -->
<button class="inline-flex items-center gap-2 px-4 py-2 text-sm
               bg-blue-500 text-white rounded-lg opacity-75 cursor-wait"
        disabled>
  <svg class="animate-spin h-4 w-4" viewBox="0 0 24 24">
    <circle class="opacity-25" cx="12" cy="12" r="10"
            stroke="currentColor" stroke-width="4" fill="none" />
    <path class="opacity-75" fill="currentColor"
          d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" />
  </svg>
  Yükleniyor...
</button>
Bilgi: React veya Vue gibi component framework'lerinde, bu button varyantlarını props ile yönetmek en temiz yaklaşımdır. clsx veya cva (class-variance-authority) gibi kütüphaneler, koşullu class yönetimini kolaylaştırır.

2. Card Component Pattern'leri

Card, web uygulamalarının en temel bileşenlerinden biridir. Görsel, başlık, açıklama ve aksiyon alanlarından oluşur ve farklı varyantlarda kullanılabilir.

<!-- Standart Card -->
<div class="bg-white dark:bg-gray-900 rounded-xl shadow-card
            border border-gray-100 dark:border-gray-800
            overflow-hidden transition-shadow hover:shadow-lg">
  <img src="/project.webp" alt="Proje görseli"
       class="w-full h-48 object-cover" />
  <div class="p-5">
    <div class="flex items-center gap-2 mb-3">
      <span class="inline-flex items-center px-2.5 py-0.5 rounded-full
                   text-xs font-medium bg-blue-100 text-blue-700
                   dark:bg-blue-900/30 dark:text-blue-400">
        CSS
      </span>
      <span class="text-xs text-gray-500">5 dk okuma</span>
    </div>
    <h3 class="text-lg font-bold text-gray-900 dark:text-white mb-2">
      Card Başlığı
    </h3>
    <p class="text-gray-600 dark:text-gray-400 text-sm leading-relaxed
              line-clamp-2">
      Card açıklama metni. İki satırla sınırlandırılmış.
    </p>
    <div class="flex items-center justify-between mt-4 pt-4
                border-t border-gray-100 dark:border-gray-800">
      <div class="flex items-center gap-2">
        <img src="/avatar.webp" class="w-8 h-8 rounded-full object-cover" alt="" />
        <span class="text-sm font-medium text-gray-700 dark:text-gray-300">
          Tarik Tunç
        </span>
      </div>
      <a href="#" class="text-sm font-medium text-blue-500 hover:text-blue-600">
        Oku →
      </a>
    </div>
  </div>
</div>

<!-- Horizontal Card -->
<div class="flex flex-col sm:flex-row bg-white dark:bg-gray-900
            rounded-xl shadow-card overflow-hidden">
  <img src="/image.webp" alt=""
       class="w-full sm:w-48 h-48 sm:h-auto object-cover" />
  <div class="flex-1 p-5 flex flex-col justify-between">
    <div>
      <h3 class="font-bold text-gray-900 dark:text-white">Başlık</h3>
      <p class="text-sm text-gray-600 dark:text-gray-400 mt-1">Açıklama</p>
    </div>
    <div class="flex items-center gap-2 mt-3">
      <span class="text-xs text-gray-500">15 Mart 2026</span>
    </div>
  </div>
</div>

3. Form Component'leri

Form elemanları kullanıcı etkileşiminin temelini oluşturur. Tutarlı görünüm, erişilebilirlik ve validasyon geri bildirimi önemlidir.

<!-- Form Layout -->
<form class="space-y-6 max-w-lg">
  <!-- Text Input -->
  <div class="space-y-1.5">
    <label class="block text-sm font-medium text-gray-700 dark:text-gray-300">
      E-posta Adresi
    </label>
    <input type="email"
           class="w-full px-3 py-2.5 rounded-lg
                  bg-white dark:bg-gray-900
                  border border-gray-300 dark:border-gray-600
                  text-gray-900 dark:text-gray-100
                  placeholder-gray-400 dark:placeholder-gray-500
                  focus:border-blue-500 focus:ring-2 focus:ring-blue-500/20
                  dark:focus:border-blue-400 dark:focus:ring-blue-400/20
                  outline-none transition-all"
           placeholder="ornek@email.com" />
    <p class="text-xs text-gray-500">İş e-postanızı tercih edin.</p>
  </div>

  <!-- Error State -->
  <div class="space-y-1.5">
    <label class="block text-sm font-medium text-red-600 dark:text-red-400">
      Şifre
    </label>
    <input type="password"
           class="w-full px-3 py-2.5 rounded-lg
                  border-2 border-red-500 dark:border-red-400
                  bg-red-50 dark:bg-red-900/10
                  text-gray-900 dark:text-gray-100
                  focus:ring-2 focus:ring-red-500/20
                  outline-none" />
    <p class="text-xs text-red-600 dark:text-red-400 flex items-center gap-1">
      Şifre en az 8 karakter olmalıdır.
    </p>
  </div>

  <!-- Select -->
  <div class="space-y-1.5">
    <label class="block text-sm font-medium text-gray-700 dark:text-gray-300">
      Kategori
    </label>
    <select class="w-full px-3 py-2.5 rounded-lg
                   bg-white dark:bg-gray-900
                   border border-gray-300 dark:border-gray-600
                   text-gray-900 dark:text-gray-100
                   focus:border-blue-500 focus:ring-2 focus:ring-blue-500/20
                   outline-none">
      <option value="">Seçiniz...</option>
      <option value="css">CSS</option>
      <option value="tailwind">Tailwind CSS</option>
    </select>
  </div>

  <!-- Checkbox -->
  <label class="flex items-start gap-3 cursor-pointer">
    <input type="checkbox"
           class="mt-0.5 w-4 h-4 rounded
                  border-gray-300 dark:border-gray-600
                  text-blue-500 focus:ring-blue-500/20" />
    <span class="text-sm text-gray-600 dark:text-gray-400">
      Kullanım koşullarını kabul ediyorum.
    </span>
  </label>

  <!-- Submit -->
  <button type="submit"
          class="w-full py-2.5 px-4 bg-blue-500 text-white font-medium
                 rounded-lg hover:bg-blue-600
                 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2
                 transition-colors">
    Gönder
  </button>
</form>
İpucu: @tailwindcss/forms eklentisi, form elemanlarının varsayılan stillerini normalize eder ve Tailwind utility class'larıyla kolayca özelleştirilebilir hale getirir. Kurulum: npm install @tailwindcss/forms.

4. Component Organizasyonu ve class-variance-authority

Büyük projelerde component varyantlarını yönetmek için cva (class-variance-authority) kütüphanesi mükemmel bir çözümdür.

// button.ts — CVA ile Button varyantları
import { cva, type VariantProps } from 'class-variance-authority';

export const buttonVariants = cva(
  // Base styles
  'inline-flex items-center justify-center gap-2 font-medium rounded-lg transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed',
  {
    variants: {
      variant: {
        primary: 'bg-blue-500 text-white hover:bg-blue-600 focus:ring-blue-500',
        secondary: 'border-2 border-gray-300 text-gray-700 hover:bg-gray-50 focus:ring-gray-500',
        ghost: 'text-gray-600 hover:bg-gray-100 hover:text-gray-900',
        danger: 'bg-red-500 text-white hover:bg-red-600 focus:ring-red-500',
      },
      size: {
        sm: 'px-3 py-1.5 text-xs',
        md: 'px-4 py-2 text-sm',
        lg: 'px-6 py-3 text-base',
      },
    },
    defaultVariants: {
      variant: 'primary',
      size: 'md',
    },
  }
);

export type ButtonVariants = VariantProps<typeof buttonVariants>;

// React kullanımı
// <button className={buttonVariants({ variant: 'primary', size: 'lg' })}>
//   Kaydet
// </button>
Uyarı: @apply direktifini component stil tanımlamak için aşırı kullanmayın. Bu, Tailwind'in utility-first felsefesine aykırıdır ve bakım maliyetini artırır. Component framework'lerinde props bazlı yaklaşım, saf HTML projelerinde ise template/include kullanmak daha iyidir.

Sonuç

Tailwind CSS ile profesyonel UI component'leri oluşturmak, doğru pattern'leri bilmekle başlar. Button'larda varyant ve durum yönetimi, Card'larda esnek yapı ve responsive davranış, Form'larda erişilebilirlik ve validasyon geri bildirimi temel unsurlardır. CVA gibi araçlar ile varyant yönetimini sistematize edebilir, dark mode desteğini her component'e tutarlı şekilde ekleyebilirsiniz. Tailwind'in güçlü yanı, bu pattern'leri bir kez oluşturup kolayca çoğaltabilmenizdir.

Kaynaklar

İlgili Yazılar