Animated Tabs
Thanh tab có viên kính trượt giãn từ tab này sang tab kia, nội dung lướt theo cùng hướng
.zip · HTML / CSS / JS · v1.0.0
Miễn phí — không cần tài khoản hay email. Luôn là bản mới nhất.
Đang chạy trực tiếp
Giới thiệu
Thanh tab cho thấy bạn đang đi đâu. Chọn một tab, viên kính mờ giãn ra về phía nó — mép trước đi trước, mép sau theo sát — rồi thu gọn lại trên tab mới. Nội dung cũng chuyển theo: phần mới lướt vào từ phía viên kính vừa đi tới, phần cũ mờ dần đi.
- Hai kiểu: viên kính nằm sau chữ, hoặc một đường gạch chân gradient mảnh
- Ngang hoặc dọc; trên màn hình nhỏ thanh tab dài cuộn ngang được và luôn giữ tab đang chọn trong tầm nhìn
- Bám theo bố cục: thanh chỉ báo tự đo lại khi trang đổi kích thước hoặc web font tải xong
- Mọi màu, độ bo góc và thời gian đều là CSS custom property; script chỉ ghi vị trí
- Không cần cài gì: một file CSS và một script nhỏ, hoặc một component React
Tính năng
- Thanh chỉ báo giãn ra phủ cả hai tab rồi mới thu gọn về tab mới
- Nội dung mờ dần và trượt theo hướng di chuyển
- Kiểu viên kính và kiểu gạch chân, ngang hoặc dọc, đủ sáng và tối
- Thanh tab dài cuộn ngang được và luôn giữ tab đang chọn trong tầm nhìn
- Bản HTML/CSS/JS thuần và bản React (dùng được với Next.js)
- Không phụ thuộc thư viện, khoảng 5 KB sau gzip
Cách dùng
Gắn stylesheet và script một lần, rồi thêm data-tabs vào mỗi bộ tab:
<link rel="stylesheet" href="animated-tabs.css" />
<script src="animated-tabs.js" defer></script>
<div class="animated-tabs" data-tabs>
<div class="animated-tabs__list" role="tablist" aria-label="Cài đặt">
<button class="animated-tabs__tab" role="tab" type="button" aria-selected="true">Chung</button>
<button class="animated-tabs__tab" role="tab" type="button">Thanh toán</button>
</div>
<div class="animated-tabs__panel" role="tabpanel">…</div>
<div class="animated-tabs__panel" role="tabpanel" hidden>…</div>
</div>Tab được ghép với panel theo thứ tự (hoặc theo aria-controls); script tự điền id và các thuộc tính
ARIA còn thiếu. Để các panel là con trực tiếp của .animated-tabs và gắn hidden cho mọi panel trừ
panel đầu, để trang hiển thị đúng ngay cả trước khi script chạy. Tab có disabled sẽ bị bỏ qua.
Tuỳ chọn qua data attribute trên phần tử gốc: data-variant="underline" (mặc định: viên kính),
data-orientation="vertical", data-activation="manual" (mũi tên chỉ di chuyển focus, Enter / Space mới chọn).
Mỗi lần đổi tab đều phát sự kiện tabchange (có nổi bọt), dù do người dùng hay do script:
document.querySelector("#settings").addEventListener("tabchange", (event) => {
console.log(event.detail.value, event.detail.previousValue); // và .index, .previousIndex
});
AnimatedTabs.get(element).select("billing"); // theo data-value (không có thì theo id), hoặc theo vị tríTab thêm vào sau khi trang đã tải: AnimatedTabs.init(container) — hàm này trả về một hàm để gỡ ra.
AnimatedTabs.createTabs(element, { activation, orientation }) khởi tạo trực tiếp một phần tử.
Chép Tabs.tsx, animated-tabs.css và thư mục core vào dự án:
import { Tab, TabList, TabPanel, Tabs } from "./Tabs";
<Tabs defaultValue="general" onChange={(value) => console.log(value)}>
<TabList aria-label="Cài đặt">
<Tab value="general">Chung</Tab>
<Tab value="billing">Thanh toán</Tab>
</TabList>
<TabPanel value="general">…</TabPanel>
<TabPanel value="billing">…</TabPanel>
</Tabs>Dùng defaultValue để component tự giữ trạng thái, hoặc value + onChange để bạn tự giữ.
variant ("pill" | "underline"), orientation ("horizontal" | "vertical") và activation
("automatic" | "manual") đặt trên <Tabs>. Để <TabList> và các panel là con trực tiếp của
<Tabs>. Mọi prop của <div> / <button> đều dùng được (className, disabled, aria-*…). Panel
ẩn vẫn được giữ lại trong cây, nên trạng thái bên trong không mất. React 18 hoặc 19.
Component bắt đầu bằng "use client", nên dùng được trong mọi page hay server component. Với App
Router không cần làm gì thêm. Với Pages Router, chuyển dòng import CSS vào pages/_app.
Đặt các biến sau trên .animated-tabs (hoặc class của bạn):
| Biến | Đổi gì |
|---|---|
--tabs-text, --tabs-text-hover, --tabs-text-active |
Màu chữ của tab |
--tabs-surface, --tabs-border |
Rãnh kính phía sau các tab |
--tabs-pill, --tabs-pill-tint-from, --tabs-pill-tint-to, --tabs-pill-border, --tabs-glow |
Viên kính: nền, sắc màu, viền, quầng sáng |
--tabs-accent-from, --tabs-accent-to, --tabs-line |
Đường gạch chân: gradient và độ dày |
--tabs-ring |
Viền focus |
--tabs-radius, --tabs-padding, --tabs-gap |
Hình dạng, kích thước tab, khoảng cách giữa tab và nội dung |
--tabs-lead, --tabs-trail, --tabs-lag, --tabs-ease-lead, --tabs-ease-trail |
Độ giãn: mép trước, mép sau đi nhanh chậm ra sao, mép sau chờ bao lâu |
--tabs-panel-duration, --tabs-panel-shift |
Nội dung đổi trong bao lâu và trượt xa bao nhiêu |
Màu dùng light-dark(): tự theo color-scheme của trang. Hiệu ứng chuyển nội dung cần Chrome 117,
Safari 17.4 hoặc Firefox 129; trình duyệt cũ hơn đổi nội dung tức thì.
Hỏi về sản phẩm này
Chưa chắc có hợp dự án của bạn? Cứ hỏi — câu trả lời lấy từ chính trang này.
Lịch sử phiên bản
1.0.0First releaseMới nhất
Plain HTML/CSS/JS and React builds. Pill and underline styles, horizontal and vertical lists, automatic and manual activation, full keyboard and reduced-motion support.
- Bản sửa lỗi và tính năng mới đều có ngay ở nút tải này — file tải về luôn là bản mới nhất.
Có thể bạn sẽ thích
- ComponentĐiều hướng
Magnify Dock
Thanh dock kính mờ: icon phồng lên dưới con trỏ, các icon bên cạnh lướt sang nhường chỗ
Miễn phí


