Giới thiệu
Svelte với CSS scoped là một lựa chọn tuyệt vời cho các thành phần được bao gói. Nhưng khi ứng dụng của bạn phát triển, việc viết CSS tùy chỉnh cho mỗi nút, thẻ và điều chỉnh lề có thể làm chậm tiến độ. Đây chính là lúc Tailwind CSS tỏa sáng. Đây là một framework utility-first cung cấp cho bạn các lớp có sẵn cho khoảng cách, kiểu chữ, màu sắc và chế độ tối — tất cả đều được tích hợp ngay trong mã HTML của bạn. Kết hợp nó với CSS scoped của Svelte, bạn sẽ có được sự kết hợp hoàn hảo giữa việc prototyping nhanh và các thành phần dễ bảo trì.
Trong bài viết này, bạn sẽ học cách:
- Thiết lập Tailwind trong SvelteKit.
- Tạo kiểu cho các thành phần bằng các utility của Tailwind.
- Triển khai chế độ tối chỉ với một lớp chuyển đổi.
- Kết hợp các utility của Tailwind với CSS scoped.
- Tránh những cạm bẫy như "class soup".
- Kết thúc với một dự án mini được tạo kiểu kết hợp tất cả.
Bước 1: Tailwind + Svelte — Một cặp hoàn hảo 💘
Cho đến nay, bạn đã thấy sức mạnh của phong cách tích hợp sẵn của Svelte. CSS scoped, :global
, và các chỉ thị lớp bao phủ rất nhiều lĩnh vực. Tuy nhiên, đôi khi bạn không muốn viết một quy tắc CSS tùy chỉnh cho mọi thứ nhỏ nhặt:
- Khoảng cách (
margin
,padding
) - Màu sắc và nền
- Các góc tròn, bóng, hiệu ứng hover
Đó là lúc Tailwind CSS phát huy tác dụng. Đây là một framework CSS utility-first cung cấp cho bạn các lớp như:
p-4
→ paddingbg-blue-500
→ màu nềnrounded-lg
→ góc tròn
Thay vì phải chuyển đổi giữa các tệp HTML và CSS, bạn có thể tạo kiểu ngay trong mã Svelte bằng các lớp.
Trước (CSS thủ công)
html
<!-- Button.svelte -->
<button class="btn">Click Me</button>
<style>
.btn {
background: royalblue;
color: white;
padding: 0.5rem 1rem;
border-radius: 0.5rem;
cursor: pointer;
}
</style>
Sau (Tailwind)
html
<!-- Button.svelte -->
<button class="bg-blue-500 text-white px-4 py-2 rounded-lg">
Click Me
</button>
Không cần khối <style>
— Tailwind xử lý tất cả với các utility.
👉 Mục tiêu không phải là từ bỏ phong cách của Svelte — mà là Tailwind giúp các mẫu thông dụng nhanh hơn và nhất quán hơn, trong khi CSS scoped của Svelte vẫn rất tuyệt cho các kiểu riêng lẻ.
Bước 2: Thiết lập Tailwind trong SvelteKit
Tailwind tích hợp một cách liền mạch với SvelteKit. Hãy cùng nhau thực hiện từng bước.
1. Cài đặt Tailwind và các công cụ hỗ trợ
Tại thư mục gốc của dự án, chạy:
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init tailwind.config.cjs -p
Hai tệp sẽ được tạo ra:
tailwind.config.cjs
→ Cấu hình Tailwindpostcss.config.cjs
→ Cấu hình PostCSS
2. Cấu hình Tailwind
Mở tailwind.config.cjs
và đảm bảo rằng nó quét các tệp .svelte
của bạn:
module.exports = {
content: ['./src/**/*.{html,js,svelte,ts}'],
theme: {
extend: {}
},
plugins: []
};
Điều này cho Tailwind biết để purge CSS không sử dụng từ tất cả các thành phần Svelte của bạn.
3. Thêm Tailwind vào CSS toàn cục
Tạo (hoặc chỉnh sửa) src/app.css
và thêm các lớp Tailwind:
@tailwind base;
@tailwind components;
@tailwind utilities;
4. Nhập CSS vào layout gốc của bạn
Trong SvelteKit, layout gốc là src/routes/+layout.svelte
. Nhập app.css
vào đó:
<script>
import "../app.css";
</script>
<slot />
Điều này đảm bảo rằng các kiểu Tailwind có sẵn ở khắp nơi trong ứng dụng của bạn.
✅ Vậy là xong! Bây giờ bạn có thể bắt đầu sử dụng các lớp Tailwind trực tiếp trong bất kỳ tệp .svelte
nào.
Ví dụ:
<button class="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded-lg">
Click Me
</button>
Bước 3: Sử dụng Tailwind trong các thành phần
Bây giờ Tailwind đã được thiết lập, hãy sử dụng nó bên trong một thành phần Svelte.
Bạn không cần khối <style>
ở đây — chỉ cần áp dụng các lớp Tailwind trực tiếp trong thuộc tính class
.
Button.svelte
<script>
export let label = "Click Me";
</script>
<button class="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded-lg">
{label}
</button>
Sau đó nhập nó vào một trang (ví dụ src/routes/+page.svelte
):
<script>
import Button from '$lib/Button.svelte';
</script>
<h1>Chào mừng</h1>
<Button label="Bắt đầu" />
✅ Điều này ngay lập tức tạo ra một nút được tạo kiểu đẹp mắt với:
- Nền màu xanh (
bg-blue-500
) - Trạng thái hover (
hover:bg-blue-600
) - Văn bản màu trắng, padding và góc tròn
Không cần CSS thêm.
⚡ Quy trình này rất tuyệt vời cho việc prototyping hoặc cho các nhóm muốn kiểu dáng nhất quán, sẵn sàng cho sản xuất mà không cần viết nhiều CSS tùy chỉnh.
Bước 4: Chế độ tối với Tailwind
Nhớ tính năng chủ đề từ Bước 10 không? Tailwind làm chế độ tối dễ dàng vô cùng.
Đầu tiên, bật nó trong tailwind.config.cjs
:
module.exports = {
darkMode: 'class', // hoặc 'media'
content: ['./src/**/*.{html,js,svelte,ts}'],
theme: { extend: {} }
};
Bây giờ bạn có thể sử dụng tiền tố dark:
để định nghĩa các kiểu thay thế.
DarkModeDemo.svelte
<script>
let dark = false;
function toggleTheme() {
dark = !dark;
document.body.classList.toggle("dark", dark);
}
</script>
<button
class="px-4 py-2 mb-4 bg-gray-200 dark:bg-gray-700 rounded-lg"
on:click={toggleTheme}
>
Chuyển đổi chế độ tối
</button>
<div class="p-4 bg-white text-black dark:bg-black dark:text-white rounded-lg">
Xin chào chế độ tối 👋
</div>
Sử dụng: nhập DarkModeDemo
vào một trang (+page.svelte
) và thử chuyển đổi.
✅ Chỉ với tiền tố dark:
:
- Màu nền và văn bản lập tức thay đổi
- Hoạt động trên toàn bộ ứng dụng nếu bạn áp dụng
dark
chobody
👉 Tailwind thực sự biến chế độ tối thành một dòng mã, so với việc quản lý các biến CSS thủ công.
Bước 5: Kết hợp Tailwind với CSS Scoped
Tailwind tuyệt vời cho bố cục, khoảng cách và màu sắc — nhưng đôi khi bạn cần một chút sắc nét hơn (như chuyển tiếp mượt mà, keyframes, hoặc các điều chỉnh chi tiết). Đó là lúc CSS scoped của Svelte vẫn phát huy tác dụng.
Thực hành tốt nhất là:
👉 Sử dụng Tailwind cho 90% kiểu dáng.
👉 Thêm CSS scoped khi các utility không thể diễn đạt những gì bạn cần.
Ví dụ: Kết hợp cả hai
ActiveButton.svelte
<script>
export let active = false;
function toggle() {
active = !active;
}
</script>
<button
class="px-4 py-2 rounded-lg text-white"
class:bg-blue-500={active}
class:bg-gray-400={!active}
on:click={toggle}
>
{active ? "Active" : "Inactive"}
</button>
<style>
/* CSS Scoped thêm vào chuyển tiếp mượt mà */
button {
transition: background 0.3s ease;
}
</style>
Sử dụng trong một trang:
<script>
import ActiveButton from '$lib/ActiveButton.svelte';
</script>
<ActiveButton />
Bây giờ khi bạn nhấp vào nút:
- Tailwind thiết lập kiểu cơ bản (
px-4
,rounded-lg
, màu sắc). - CSS scoped của Svelte giúp màu sắc mờ dần mượt mà thay vì đột ngột.
Điều này chứng tỏ điểm mạnh: Tailwind mang lại năng suất, CSS scoped mang lại sự kiểm soát.
Bước 6: Những cạm bẫy của Tailwind ⚠️
Tailwind và Svelte hoạt động tuyệt vời cùng nhau, nhưng đây là một số cạm bẫy bạn nên chú ý:
- Class soup (quá nhiều utility trong một phần tử) Tailwind khuyến khích xếp chồng các lớp nhỏ, nhưng nó có thể trở nên khó đọc:
<div class="flex items-center justify-between px-4 py-2 bg-blue-500 rounded-lg shadow-md hover:bg-blue-600 text-white">
Header
</div>
✅ Giải pháp: Trích xuất thành một thành phần (ví dụ <Header />
) hoặc sử dụng @apply
của Tailwind trong một stylesheet toàn cục để gộp các combo thông thường.
- Purging các lớp không sử dụng Tailwind loại bỏ CSS không sử dụng tại thời điểm build. Nếu
tailwind.config.cjs
của bạn không bao gồm*.svelte
, các kiểu của bạn có thể biến mất trong sản xuất.
Ví dụ cấu hình:
module.exports = {
content: ['./src/**/*.{html,js,svelte,ts}'], // ✅ bao gồm .svelte
theme: { extend: {} },
plugins: []
}
- CSS scoped vs utility của Tailwind Các lớp Tailwind là toàn cục, trong khi các kiểu của Svelte là scoped. May mắn thay, chúng thường không xung đột — nhưng hãy nhớ:
<div class="bg-blue-500">Xin chào</div>
<style>
div { background: red; } /* scoped → chỉ áp dụng ở đây */
</style>
✅ Giải pháp: Sử dụng Tailwind cho các kiểu chung, CSS scoped chỉ cho việc tinh chỉnh thành phần này.
👉 Quy tắc: Sử dụng Tailwind để nhanh chóng, CSS scoped để chính xác.
Bước 7: Dự án mini — Lưới thẻ đầy màu sắc 🃏
Hãy kết hợp mọi thứ lại với nhau — các kiểu scoped, các utility của Tailwind, chế độ tối và các lớp động — để tạo ra một lưới thẻ mini.
1. Tạo thành phần Card.svelte
src/lib/Card.svelte
<script>
export let title;
export let content;
export let color = "blue"; // nhận "blue" | "green" | "purple"
// Ánh xạ màu sắc tới các lớp Tailwind thực tế (quan trọng!)
const colorClasses = {
blue: "bg-blue-100 border-blue-500 text-blue-800",
green: "bg-green-100 border-green-500 text-green-800",
purple: "bg-purple-100 border-purple-500 text-purple-800"
};
</script>
<div
class={`p-6 rounded-xl shadow-lg transition border-l-4 ${colorClasses[color]}`}
>
<h2 class="text-xl font-bold mb-2">{title}</h2>
<p>{content}</p>
</div>
2. Sử dụng nó trong trang chính
src/routes/+page.svelte
<script>
import Card from "$lib/Card.svelte";
</script>
<div class="min-h-screen bg-gradient-to-r from-pink-200 via-purple-200 to-indigo-200 p-10">
<h1 class="text-3xl font-bold mb-6 text-center text-indigo-700">
Demo thẻ đầy màu sắc
</h1>
<div class="grid gap-6 grid-cols-1 sm:grid-cols-2 lg:grid-cols-3">
<Card
title="Học Svelte"
content="Xây dựng UIs nhanh, phản ứng."
color="blue"
/>
<Card
title="Tạo kiểu với Tailwind"
content="Các lớp utility-first giữ CSS gọn gàng."
color="green"
/>
<Card
title="Kết hợp các thành phần"
content="Thẻ, nút, modal — tất cả đều có thể tái sử dụng."
color="purple"
/>
</div>
</div>
3. Điều này cho thấy gì
✅ Các utility của Tailwind → khoảng cách, bóng, gradients, lưới đáp ứng.
✅ Các lớp động → màu sắc khác nhau cho mỗi thẻ.
✅ CSS scoped (tùy chọn) → nếu bạn muốn thêm các điều chỉnh nhỏ.
✅ Sẵn sàng cho chế độ tối → bạn có thể mở rộng Card.svelte
với các biến thể dark:
.
Kết quả: Một lưới thẻ đầy màu sắc, đẹp mắt thay vì một trang đơn giản.
Kết luận
Trong bài viết này, bạn đã học cách tạo kiểu cho các ứng dụng Svelte như một chuyên gia:
- Chủ đề với biến CSS và chế độ tối của Tailwind.
- Kết hợp Tailwind với Svelte để tối đa hóa năng suất.
Bây giờ bạn đã thấy cách Tailwind và Svelte bổ sung cho nhau — CSS scoped cho sự kiểm soát tinh tế, các utility cho việc tạo kiểu nhanh chóng, và chế độ tối được tích hợp sẵn. Với những công cụ này, bạn có thể xây dựng các ứng dụng không chỉ phản ứng mà còn được tạo kiểu đẹp mắt và nhất quán ở quy mô lớn.
👉 Đó là kết thúc chuỗi bài viết về phong cách của chúng tôi. Tiếp theo, chúng ta sẽ chuyển sang trạng thái & luồng dữ liệu trong Svelte: stores, API ngữ cảnh và các mẫu phản ứng nâng cao.
👉 Tiếp theo: Trạng thái & Luồng Dữ Liệu — Stores, API Ngữ Cảnh và Phản Ứng Nâng Cao. Đây là nơi chúng ta sẽ đi xa hơn props và events vào quản lý trạng thái toàn ứng dụng.