Bootstrap در مقابل Tailwind — کدام برای پروژه Laravel مناسبتر است؟
مقایسه Bootstrap 5 و Tailwind CSS 4 در پروژه Laravel: سرعت توسعه، سفارشیسازی، حجم bundle، Filament و تجربه تیم در ایران.
سوال «فرانت را با چه چیزی بزنیم؟» در شروع هر پروژه Laravel تکرار میشود. Bootstrap هنوز در پروژههای شرکتی ایران زیاد است؛ Tailwind در استارتاپها و پنلهای مدرن. هر دو با Vite و Blade کار میکنند — تفاوت در نقطهٔ شروع، کنترل design، نیاز به کامپوننت آماده و تجربهٔ تیم است.
خلاصه: Bootstrap مجموعهای از کامپوننتهای آماده (navbar، modal، form) بهاضافهٔ utility class است و برای رسیدن سریع به UI استاندارد مناسب است. Tailwind یک ابزار utility-first است که کامپوننت آماده ندارد و ظاهر را مستقیم با کلاسهای کوچک میسازید؛ برای design system اختصاصی کنترل بیشتری میدهد. هیچکدام همیشه بهتر نیست: اگر پروژه از قبل یک design system یا قالب دارد، معمولاً همان مهمتر از ترجیح کلی است.
Bootstrap 5 — خلاصه
کامپوننت آماده: navbar، modal، card، grid، form. با کلاسهای از پیش طراحیشده سریع صفحه میسازید و یادگیری برای مبتدی آسانتر است. Bootstrap 5 دیگر به jQuery وابسته نیست؛ بخش JavaScript آن (modal، dropdown، tooltip) جداگانه import میشود و dropdown و tooltip به Popper نیاز دارند. Bootstrap هم utility class دارد (d-flex، mt-3، text-center) و ظاهر را با متغیرهای Sass یا CSS variables سفارشی میکنید. نسخهٔ RTL آمادهٔ CSS (bootstrap.rtl.min.css) برای فارسی همراه بسته است.
<div class="container">
<div class="row">
<div class="col-md-6">محتوا</div>
</div>
</div>
Tailwind CSS — خلاصه
Utility-first: flex، pt-4، text-gray-700. در Tailwind 4 تنظیمات design system (رنگ، فونت، فاصله) بهطور پیشفرض داخل خود فایل CSS با @theme تعریف میشود و فایل tailwind.config.js دیگر الزامی نیست. Tailwind فقط کلاسهایی را تولید میکند که در فایلهای پروژه پیدا کند. سفارشیسازی ظاهر منحصربهفرد راحتتر است؛ در عوض HTML شلوغتر به نظر میرسد و modal یا dropdown آماده ندارد — رفتار تعاملی را با Alpine.js، Livewire یا یک کتابخانهٔ کامپوننت جدا میسازید.
<div class="max-w-4xl mx-auto px-4 py-8">
<h1 class="text-2xl font-bold text-slate-900">عنوان</h1>
</div>
جدول مقایسه در Laravel
| معیار | Bootstrap | Tailwind |
|---|---|---|
| نقطهٔ شروع | کامپوننت آماده + utility | فقط utility؛ کامپوننت را خودتان میسازید |
| سرعت MVP با UI استاندارد | بالا | متوسط، مگر با کتابخانهٔ کامپوننت |
| UI منحصربهفرد | نیاز به override زیاد یا تم Sass | کنترل کامل از طریق theme |
| JavaScript تعاملی | modal و dropdown آماده (Bootstrap JS) | ندارد؛ Alpine، Livewire یا کتابخانهٔ جدا |
| حجم CSS نهایی | بسته به ماژولهایی که import میکنید | فقط کلاسهای استفادهشده ساخته میشود |
| RTL فارسی | فایل RTL آماده | variantهای rtl: و utilityهای منطقی مثل ms-* و pe-* |
| Filament | پنل Filament جدا و با CSS خودش کار میکند | همخوان با Filament (Filament با Tailwind ساخته شده) |
| تیم قدیمی jQuery/Bootstrap | راحت | منحنی یادگیری |
حجم واقعی CSS به نحوهٔ استفادهٔ شما بستگی دارد؛ بهجای اعداد کلی، خروجی npm run build پروژهٔ خودتان را بسنجید.
Laravel + Vite
اسکلت جدید Laravel 12 با Vite و Tailwind 4 (از طریق پلاگین @tailwindcss/vite) میآید. همین سایت هم همین ترکیب را دارد: در package.json پکیجهای tailwindcss و @tailwindcss/vite و در resources/css/app.css این خطوط:
@import 'tailwindcss';
@source '../../storage/framework/views/*.php';
@source '../**/*.blade.php';
@theme {
--font-sans: 'Instrument Sans', ui-sans-serif, system-ui, sans-serif;
}
@source مسیرهایی را که Tailwind باید برای پیدا کردن کلاسها بخواند اضافه میکند. این پیشفرض اسکلت است، نه الزام؛ پروژهٔ شما ممکن است Bootstrap یا ترکیب دیگری داشته باشد.
برای Bootstrap در همان ساختار Vite:
npm install bootstrap @popperjs/core
// resources/js/app.js
import 'bootstrap/dist/css/bootstrap.rtl.min.css';
import * as bootstrap from 'bootstrap';
اگر میخواهید متغیرهای Bootstrap را با Sass تغییر دهید، sass را به devDependencies اضافه کنید و بهجای فایل CSS آماده، Sass خود Bootstrap را import کنید. در هر دو حالت، فایلها را در @vite داخل layout صدا بزنید و برای production npm run build اجرا کنید.
کلاسهای پویا در Blade
Tailwind کلاس را از متن فایل پیدا میکند و کد را اجرا نمیکند. پس class="text-{{ $color }}-600" کار نمیکند، چون رشتهٔ کامل text-red-600 هیچجا نوشته نشده. نام کامل کلاسها را در یک آرایه بنویسید و از آن انتخاب کنید:
$classes = [
'danger' => 'text-red-600',
'success' => 'text-green-600',
][$variant];
کی Bootstrap؟
- سایت شرکتی با deadline کوتاه و UI استاندارد
- تیم بدون frontend اختصاصی
- مشتری UI شبیه قالبهای آشنا میخواهد
- یکپارچگی با قالبهای admin آماده Bootstrap
- پروژهٔ موجودی که از قبل روی Bootstrap ساخته شده
کی Tailwind؟
- برند اختصاصی و design system
- استفاده از Filament / Livewire Flux
- تیم به utility-first عادت دارد
- پروژه از starter kitهای Laravel (React، Vue یا Livewire) شروع میشود که همه بر پایهٔ Tailwindاند
سرعت سایت بیشتر از CSS framework به تصویر، JavaScript، کش و query بستگی دارد: بهینهسازی Laravel و Core Web Vitals.
Design system و استفادهٔ مجدد از کامپوننت
در هر دو ابزار، مشکل اصلی نگهداری تکرار است: اگر دکمهٔ اصلی در ۴۰ فایل با کلاسهای متفاوت نوشته شود، تغییر رنگ برند پروژهٔ چندروزه میشود. در Bootstrap ظاهر را با متغیرهای تم کنترل میکنید؛ در Tailwind با @theme و tokenهای رنگ و فاصله. در هر دو، الگوهای تکراری را به Blade component ببرید.
Blade Components
با Blade component کلاسهای تکراری را encapsulate کنید — چه Bootstrap چه Tailwind:
<x-button variant="primary">ارسال</x-button>
داخل component، $attributes->merge(['class' => '...']) اجازه میدهد کلاس پایه ثابت بماند و صفحه فقط کلاس اضافه بفرستد. این کار وابستگی صفحهها به framework را هم کم میکند: اگر روزی ابزار عوض شود، بیشتر تغییر داخل componentهاست نه همهٔ viewها.
Responsive و دسترسپذیری
هر دو mobile-firstاند و breakpointهای مشابه دارند (Bootstrap: sm تا xxl؛ Tailwind: sm تا 2xl). تفاوت در دسترسپذیری است: مستندات کامپوننتهای Bootstrap الگوی ARIA و کیبورد را نشان میدهند، اما فقط اگر markup را درست کپی کنید. Tailwind هیچ رفتار تعاملی ندارد؛ focus state، کنترل با کیبورد و برچسبها را خودتان یا کتابخانهٔ کامپوننت باید تأمین کند. در هر دو حالت، کنتراست رنگ و اندازهٔ لمس را تست کنید — دسترسپذیری سایت و سایت موبایلفرندلی.
Livewire، Inertia و فریمورکهای JavaScript
- Blade ساده: هر دو بدون محدودیت.
- Livewire: با هر دو کار میکند؛ اما JavaScript بوتاسترپ DOM را مستقیم تغییر میدهد و بعد از بهروزرسانی Livewire ممکن است state یک modal از دست برود — یا آن بخش را با
wire:ignoreجدا کنید یا رفتار تعاملی را با Alpine بسازید. کتابخانهٔ Flux برای Livewire بر پایهٔ Tailwind است. - Inertia با Vue یا React: starter kitهای رسمی Laravel از Tailwind و کامپوننتهای shadcn استفاده میکنند؛ Bootstrap هم ممکن است، ولی معمولاً از نسخههای مخصوص Vue/React آن. جزئیات اتصال: Vue و Laravel.
وقتی پروژه از قبل design system دارد
در پروژهٔ موجود، سؤال «کدام بهتر است؟» معمولاً سؤال درستی نیست. اگر سایت روی Bootstrap ساخته شده و تیم با آن راحت است، مهاجرت به Tailwind فقط برای ترند یعنی بازنویسی viewها، تست دوبارهٔ همهٔ صفحهها و ریسک ناهماهنگی ظاهر. همینطور اگر برند یک design system در Figma با tokenهای مشخص دارد، ابزاری را انتخاب کنید که پیادهسازی همان tokenها را سادهتر کند. پنل ادمین میتواند جدا باشد: Filament با CSS خودش کار میکند و مانع Bootstrap در سایت عمومی نیست.
آیا میتوان ترکیب کرد؟
در دو بخش جدا بله — مثلاً سایت عمومی با Bootstrap و پنل Filament با Tailwind، هرکدام با bundle خودش. در یک صفحه توصیه نمیشود: reset پایهٔ Tailwind (Preflight) و Reboot در Bootstrap هر دو استایل پایهٔ عناصر را تغییر میدهند و نامهای مشترکی مثل container رفتار متفاوت دارند. اگر در دورهٔ مهاجرت مجبورید، از prefix در Tailwind استفاده کنید و بازهٔ گذار را کوتاه نگه دارید.
تجربه بازار ایران
فریلنس شرکتی: اغلب Bootstrap. محصول و SaaS: Tailwind + Filament. هزینه پروژه بیشتر به design اختصاصی بستگی دارد تا ابزار — UI اختصاصی با هر کدام زمان طراحی و پیادهسازی بیشتری از قالب آماده میخواهد.
چکلیست تصمیم
- پروژه از قبل design system، قالب یا کد CSS دارد؟ اول همان را بسنجید.
- تیم با کدام ابزار تجربه دارد و چه کسی بعداً نگهداری میکند؟
- UI استاندارد کافی است یا برند ظاهر اختصاصی میخواهد؟
- کامپوننت تعاملی (modal، dropdown) از کجا میآید و دسترسپذیری آن را چه کسی تست میکند؟
- Livewire، Inertia یا Blade ساده؟ پنل ادمین Filament دارید؟
- RTL و فونت فارسی در هر دو ابزار در یک صفحهٔ نمونه تست شده؟
جمعبندی
Bootstrap = کامپوننت آماده، شروع سریع و آشنایی تیم. Tailwind = کنترل design system و هماهنگی با ecosystem فعلی Laravel (starter kitها، Filament، Flux). برای Laravel هر دو معتبرند؛ انتخاب را بر اساس پروژهٔ موجود، تیم، نیاز UI و هزینهٔ نگهداری بگیرید، نه بر اساس ادعای کلی «سریعتر» یا «مدرنتر». ساختار: resources/views. شروع پروژه: چکلیست.