Sức mạnh của Tailwind nằm ở variant: tiền tố điều kiện áp dụng lớp khi màn hình đủ rộng (md:), khi rê chuột (hover:), focus, khi phần tử cha được rê (group-hover:), khi phần tử anh em được chọn (peer-checked:), khi ở chế độ tối (dark:). Bài này hệ thống các variant quan trọng.
- Thiết kế mobile-first với sm, md, lg, xl, 2xl
- Dùng hover, focus, focus-visible, active, disabled
- Dùng group-* và peer-*
- Dùng first, last, odd, even, has-*, container query @container
Một số khái niệm
Giống Bootstrap, Tailwind là mobile-first: lớp không tiền tố áp dụng mọi màn hình, md:grid-cols-3 áp dụng từ 768px trở lên. Breakpoint: sm 640px, md 768px, lg 1024px, xl 1280px, 2xl 1536px. Có thể kết hợp nhiều variant: md:hover:bg-green-700, dark:md:text-white.
| Variant | Ví dụ | Áp dụng khi |
|---|---|---|
| Responsive | md:flex lg:w-1/3 | Màn hình ≥ breakpoint |
| Trạng thái | hover:, focus:, active:, disabled: | Tương tác |
| focus-visible: | focus-visible:ring-2 | Focus bằng bàn phím |
| group-hover: | Cha có class group được rê | Thẻ đổi màu cả khối |
| peer-checked: | Phần tử anh em có class peer được chọn | Công tắc, tab không JS |
| first:, last:, odd:, even: | odd:bg-slate-50 | Theo vị trí |
| has-[:checked]: | Cha chứa phần tử được chọn | Giống :has() |
| @md: (container) | @container + @md:flex-row | Khung chứa ≥ 448px |
| max-md: | max-md:hidden | Nhỏ hơn md |
Lưới responsive
<div class="grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4">
<div class="rounded-xl bg-sky-100 p-4 text-center">Python</div><div class="rounded-xl bg-sky-100 p-4 text-center">JavaScript</div>
<div class="rounded-xl bg-sky-100 p-4 text-center">PHP</div><div class="rounded-xl bg-sky-100 p-4 text-center">SQL</div>
</div>
<p class="mt-2 text-sm text-slate-500"><span class="md:hidden">Bạn đang ở màn hình nhỏ (dưới md).</span><span class="max-md:hidden">Bạn đang ở màn hình từ md trở lên.</span></p>hover, focus, group, peer
<a href="#" class="group block max-w-xs rounded-xl border border-slate-200 p-4 transition hover:border-green-500 hover:shadow-lg">
<h3 class="font-semibold group-hover:text-green-700">Khóa học CSS</h3>
<p class="text-sm text-slate-500">Rê chuột vào cả thẻ, tiêu đề đổi màu, mũi tên dịch sang <span class="inline-block transition group-hover:translate-x-1">→</span></p>
</a>
<label class="mt-4 inline-flex cursor-pointer items-center gap-3">
<input type="checkbox" class="peer sr-only">
<span class="relative h-6 w-11 rounded-full bg-slate-300 transition peer-checked:bg-green-600 after:absolute after:left-0.5 after:top-0.5 after:size-5 after:rounded-full after:bg-white after:transition peer-checked:after:translate-x-5"></span>
<span class="text-sm">Công tắc không cần JavaScript</span>
</label>
<input class="mt-3 block w-64 rounded-lg border border-slate-300 px-3 py-2 outline-none focus:border-green-600 focus:ring-4 focus:ring-green-600/20 invalid:border-rose-500" type="email" placeholder="Email (gõ sai để thấy invalid:)">Vị trí, :has và container query
<ul class="max-w-xs divide-y divide-slate-200 rounded-lg border">
<li class="p-2 first:font-bold odd:bg-slate-50">Sơn La</li><li class="p-2 odd:bg-slate-50">Điện Biên</li><li class="p-2 odd:bg-slate-50 last:text-rose-600">Lai Châu</li>
</ul>
<label class="mt-3 block max-w-xs rounded-lg border-2 p-3 has-[:checked]:border-green-600 has-[:checked]:bg-green-50"><input type="radio" name="g" class="mr-2">Gói Cơ bản (chọn để thấy has-)</label>
<div class="@container mt-3 max-w-md rounded-lg border p-3"><div class="flex flex-col gap-2 @sm:flex-row"><div class="h-16 rounded bg-slate-300 @sm:w-28"></div><p class="text-sm">Thẻ đổi bố cục theo khung chứa với @container và @sm:</p></div></div>Đặt variant theo thứ tự nhất quán (responsive trước, rồi trạng thái): md:hover:; tiện ích Prettier plugin for Tailwind tự sắp xếp lớp theo thứ tự chuẩn.
hover: trên điện thoại cảm ứng có thể “dính” sau khi chạm; Tailwind v4 mặc định chỉ áp dụng hover cho thiết bị có chuột (@media (hover: hover)).
- Lưới thẻ 1 → 2 → 3 → 4 cột theo breakpoint.
- Thẻ bài viết: rê chuột cả thẻ, ảnh phóng to (group-hover:scale-105).
- Làm tab hoặc công tắc bằng peer-checked.
- Ẩn sidebar trên điện thoại bằng max-lg:hidden.
- Mobile-first: sm, md, lg, xl, 2xl; max-* cho chiều ngược.
- hover, focus, focus-visible, active, disabled, invalid.
- group-*, peer-*, has-[...] cho quan hệ giữa phần tử.
- @container + @sm/@md cho container query.