Dùng position: sticky; top: 0 trên <th> để header bảng luôn hiển thị khi cuộn.
Ví dụ 1: Basic sticky header
<!DOCTYPE html>
<html>
<head>
<style>
.table-wrapper {
height: 200px; overflow-y: auto;
border: 1px solid #ddd; border-radius: 8px;
}
table { width: 100%; border-collapse: collapse; font-size: 16px; }
th, td { padding: 12px; text-align: center; border-bottom: 1px solid #eee; }
th {
position: sticky; top: 0;
background: #667eea; color: white;
z-index: 1; box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
tbody tr:hover { background: #f8f9fa; }
</style>
</head>
<body>
<h1>Bảng Header Cố Định Khi Cuộn</h1>
<div class="table-wrapper">
<table>
<thead>
<tr><th>ID</th><th>Tên</th><th>Email</th><th>Vai trò</th><th>Trạng thái</th></tr>
</thead>
<tbody>
<tr><td>1</td><td>Nguyễn Văn A</td><td>a@email.com</td><td>Admin</td><td>Hoạt động</td></tr>
<tr><td>2</td><td>Trần Thị B</td><td>b@email.com</td><td>User</td><td>Hoạt động</td></tr>
<tr><td>3</td><td>Lê Văn C</td><td>c@email.com</td><td>Editor</td><td>Khóa</td></tr>
<!-- Thêm nhiều row để test cuộn -->
<tr><td>4</td><td>Phạm Thị D</td><td>d@email.com</td><td>User</td><td>Hoạt động</td></tr>
<tr><td>5</td><td>Hoàng Văn E</td><td>e@email.com</td><td>Admin</td><td>Hoạt động</td></tr>
<tr><td>6</td><td>Vũ Thị F</td><td>f@email.com</td><td>User</td><td>Hoạt động</td></tr>
<tr><td>7</td><td>Đặng Văn G</td><td>g@email.com</td><td>Editor</td><td>Khóa</td></tr>
<tr><td>8</td><td>Bùi Thị H</td><td>h@email.com</td><td>User</td><td>Hoạt động</td></tr>
<tr><td>9</td><td>Ngô Văn I</td><td>i@email.com</td><td>Admin</td><td>Hoạt động</td></tr>
<tr><td>10</td><td>Dương Thị K</td><td>k@email.com</td><td>User</td><td>Hoạt động</td></tr>
</tbody>
</table>
</div>
</body>
</html>
Ví dụ 2: Sticky header + sticky first column
<style>
.table-wrapper2 { height: 300px; overflow: auto; }
table { border-collapse: separate; border-spacing: 0; }
th, td { min-width: 150px; white-space: nowrap; }
th { position: sticky; top: 0; background: #2c3e50; color: white; z-index: 2; }
th:first-child, td:first-child { position: sticky; left: 0; background: #34495e; z-index: 3; }
th:first-child { background: #1a252f; z-index: 4; }
</style>
Kết quả
- Cuộn dọc: header giữ nguyên vị trí top:0
- Cuộn ngang: cột đầu tiên giữ nguyên left:0
- Góc trên trái: z-index cao nhất
Lưu ý
- Cần container cha có
overflow: auto/scrollvàheightcố định border-collapse: collapsecho sticky đơn giản,separatecho sticky cả hàng và cột- Hỗ trợ: Chrome 56+, Firefox 32+, Safari 6.1+, Edge 16+