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
ş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.
Kullanımı:
. 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ı.
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.
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!
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">
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>
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>
)
}
- 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
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!