Foruma hoş geldin 👋, Ziyaretçi

Forum içeriğine ve tüm hizmetlerimize erişim sağlamak için foruma kayıt olmalı ya da giriş yapmalısınız. Foruma üye olmak tamamen ücretsizdir.

Tailwind ile utility class'ları component'lere çevirirken abstraction dengesini nasıl kurarım?

stackor

Üye
Katılım
14 Mart 2026
Mesajlar
16
Merhaba arkadaşlar, bugün Tailwind CSS kullanırken hepimizin kafasını karıştıran bir konudan bahsedeceğim. Utility-first yaklaşımıyla hızla arayüz inşa ederken, bir noktada "Bu kadar class tekrarı doğru mu?", "Bunu bir component'a çevirsem mi?" diye düşünmeye başladım. İşte tam burada abstraction (soyutlama) tuzağına düşmemek için kullandığım pratik yöntemleri paylaşacağım.

🔥 Karşılaştığım Sorun: Class Salatası mı, Aşırı Soyutlama mı?

Proje büyüdükçe, aynı button stilini 20 farklı yerde
HTML:
<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
şeklinde kullanmaya başladım. Bu, tek bir renk değişikliğinde 20 yeri güncellemek demekti. Hemen "Hadi bunu bir React/Vue component'ı yapayım!" dedim ama bu sefer de her küçük varyasyon için (outline, small, large) onlarca prop yazmaya başladım. Kodu gereksiz yere kompleks hale getirmiştim.

🧩 Çözüm Yolum: 3 Seviyeli Yaklaşım

Kendime basit bir kural koydum: Önce @apply, sonra Template, en son Component.

1. Seviye: CSS'de @apply ile Özelleştirilmiş Class'lar

Eğer bir UI parçası sadece birkaç yerde kullanılıyorsa ve stil kümesi sabitse, Tailwind'in @apply direktifini kullanarak özel bir CSS class'ı oluşturuyorum. Bu, utility'leri tek bir isim altında topluyor.

CSS:
/ styles/buttons.css /
.btn-primary {
  @apply bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:ring-2 focus:ring-blue-300 transition-colors duration-200;
}

.btn-secondary {
  @apply bg-gray-200 hover:bg-gray-300 text-gray-800 font-semibold py-2 px-4 rounded border border-gray-300;
}

Kullanımı:
HTML:
<button class="btn-primary">Kaydet</button>
. Bu, tekrarı azaltırken, component sisteminin karmaşıklığını getirmiyor.

2. Seviye: Template/Partial Kullanmak (Framework Bağımsız)

Eğer HTML yapısı da sabitse ve bu stil grubu projede çok sık tekrar ediyorsa, bir template (parçalı görünüm) oluşturuyorum. Mesela, bir kart (card) yapısı.

HTML:
<!-- partials/card.html -->
<div class="bg-white rounded-xl shadow-md overflow-hidden p-6 mb-4">
  <h3 class="text-xl font-bold text-gray-800 mb-2">{title}</h3>
  <div class="text-gray-600">
    {content}
  </div>
</div>

Bunu, backend dilinizin (Blade, Twig) veya frontend'de basit bir fonksiyonun partial'ı olarak kullanabilirsiniz. Stil ve yapı tek bir yerden yönetilir.

3. Seviye: Gerçek Bir Component'a Geçiş Zamanı

Ancak aşağıdaki durumların en az ikisi bir arada ise, artık bir component oluşturma zamanı gelmiş demektir:
- Stil grubu + HTML yapısı + İşlevsellik (onClick, disabled state) birlikte.
- Component'ın içinde başka component'lar (icon, spinner) barındırıyor.
- Çok sayıda dinamik varyasyon (size, color, variant) gerekiyor.

İşte o zaman, prop'ları kontrollü bir şekilde tanımladığım bir component yazıyorum.

JavaScript:
// components/Button.jsx (React Örneği)
const Button = ({ children, variant = 'primary', size = 'md', ...props }) => {
  const baseClasses = 'font-bold rounded focus:outline-none transition-colors duration-200'
  
  const variants = {
    primary: 'bg-blue-500 hover:bg-blue-700 text-white',
    secondary: 'bg-gray-200 hover:bg-gray-300 text-gray-800 border border-gray-300',
    danger: 'bg-red-500 hover:bg-red-700 text-white'
  }
  
  const sizes = {
    sm: 'py-1 px-3 text-sm',
    md: 'py-2 px-4',
    lg: 'py-3 px-6 text-lg'
  }

  const className = `${baseClasses} ${variants[variant]} ${sizes[size]} ${props.className || ''}`

  return (
    <button {...props} className={className}>
      {children}
    </button>
  )
}

⚠️ Dikkat Edilmesi Gereken Kırmızı Çizgiler

- Asla utility'lerin tüm gücünü kaybetmeyin. Component'ınız, className prop'u alarak dışarıdan ek stil eklenmesine izin vermeli.
- Erken optimizasyon yapmayın. Bir stil sadece 2-3 yerde kullanılıyorsa, onu component yapmak için kendinizi zorlamayın.
- Tailwind'in responsive ve state (hover, focus) prefix'lerini (md:, hover:) @apply ile kullanırken dikkatli olun. Bazen doğrudan component prop'u olarak geçmek daha iyidir.

Sonuç olarak, dengeyi bulmak "ne zaman soyutlayacağınızı" bilmekten geçiyor. Benim bu üç katmanlı yaklaşımım, proje büyüdükçe esnek ve sürdürülebilir kalmanı sağlıyor.

Siz Tailwind'de bu dengeyi kurmak için nasıl yöntemler kullanıyorsunuz? Hiç "keşke bunu component yapmasaydım" dediğiniz oldu mu? Yorumlarda deneyimlerinizi paylaşın!
 

Tema özelleştirme sistemi

Bu menüden forum temasının bazı alanlarını kendinize özel olarak düzenleye bilirsiniz.

Zevkine göre renk kombinasyonunu belirle

Tam ekran yada dar ekran

Temanızın gövde büyüklüğünü sevkiniz, ihtiyacınıza göre dar yada geniş olarak kulana bilirsiniz.

Geri