- Demo trực quan: chọn mode position và xem phần tử thay đổi ra sao
- Chọn kiểu position
- Cuộn để xem fixed và sticky
- 1. Position là gì và vì sao hay gây rối
- 2. position: static – nền tảng của flow bình thường
- 3. position: relative – dịch chuyển nhưng vẫn giữ chỗ
- 4. position: absolute – bám theo hệ tọa độ của ai?
- 5. position: fixed – bám theo cửa sổ trình duyệt
- 6. position: sticky – trợ thủ tạo trải nghiệm đọc mượt mà
- 7. Những lỗi thường gặp khi dùng position
- 8. Chiến lược sử dụng position cho layout thực tế
- 9. Kết luận
Demo trực quan: chọn mode position và xem phần tử thay đổi ra sao
Demo dưới đây mô phỏng một khối nội dung đơn giản. Bạn chỉ cần bấm nút để chuyển giữa các kiểu static, relative, absolute, xem phần tử di chuyển và chiếm chỗ trong layout như thế nào. Đồng thời còn có ví dụ về fixed và sticky trong bối cảnh cuộn nội dung.
Chọn kiểu position
Cuộn để xem fixed và sticky
Đoạn nội dung 1: Lorem ipsum dolor sit amet, consectetur adipisicing elit. Molestias, voluptates.
Đoạn nội dung 2: Nulla facilisi. Proin feugiat tellus vitae urna pellentesque, at lacinia metus tincidunt.
Đoạn nội dung 3: Sed ac lectus sit amet libero rhoncus dictum eget non leo. Curabitur non mi in lacus placerat.
Đoạn nội dung 4: Suspendisse potenti. Integer volutpat, augue non luctus pellentesque, urna nibh commodo leo.
Đoạn nội dung 5: Nam pharetra lacinia risus, at eleifend leo ultrices ac. Suspendisse bibendum condimentum mi.
Đoạn nội dung 6: Phasellus eget maximus elit. Duis sit amet arcu ut arcu luctus efficitur.
Đoạn nội dung 7: Vivamus viverra, leo id bibendum accumsan, leo enim feugiat magna, vel pharetra neque turpis non arcu.
1. Position là gì và vì sao hay gây rối
Trong CSS, thuộc tính position trả lời ba câu hỏi:
- Phần tử có còn tham gia vào flow bình thường của tài liệu hay không.
- Nó được “neo” vào hệ tọa độ nào: chính nó, phần tử cha, hay viewport.
- Những thuộc tính như
top,right,bottom,leftđược hiểu theo cách nào.
Lý thuyết rất ngắn, nhưng khi áp dụng vào layout thực tế với nhiều phần tử lồng nhau, padding, margin, flex, grid… thì position trở thành điểm dễ sai. Nếu bạn đang phải dùng rất nhiều top/left “tạm bợ” để đẩy phần tử tới đúng chỗ, rất có thể gốc rễ là bạn đang hiểu sai hoặc lạm dụng position.
2. position: static – nền tảng của flow bình thường
static là giá trị mặc định của position. Khi một phần tử là static:
- Nó nằm trong flow bình thường của layout, đẩy những phần tử khác ra trước sau.
- Các thuộc tính
top,left,right,bottomkhông có tác dụng. - Nó không tạo hệ tọa độ đặc biệt cho phần tử con.
Ví dụ:
<div class="block">Khối A</div>
<div class="block">Khối B</div>
.block {
position: static; /* có thể bỏ vì đây là mặc định */
padding: 12px;
background: #f5f5f5;
margin-bottom: 8px;
}
Nếu bạn chỉ cần layout theo chiều dọc hoặc chiều ngang, hãy ưu tiên flexbox và grid, không cần động tới position. Position chỉ nên xuất hiện khi bạn thật sự cần chồng lớp, neo góc, đè lên nhau hoặc bám theo viewport.
3. position: relative – dịch chuyển nhưng vẫn giữ chỗ
Khi chuyển một phần tử sang position: relative, bạn thay đổi hai điều:
- Phần tử vẫn chiếm chỗ như cũ trong flow, nhưng có thể dịch chuyển bằng
top,left,right,bottom. - Nó trở thành hệ tọa độ cho những phần tử con dùng
position: absolute.
Đây là mô hình rất thường gặp khi cần gắn badge lên góc ảnh hoặc thẻ nội dung.
<div class="product-card uk-card uk-card-default uk-card-body">
<span class="product-badge">-30%</span>
<img src="image.jpg" alt="Sản phẩm" class="uk-margin-small-bottom">
<h4 class="uk-margin-remove-bottom">Tên sản phẩm</h4>
</div>
.product-card {
position: relative; /* tạo hệ tọa độ cho badge */
}
.product-badge {
position: absolute;
top: 8px;
right: 8px;
background: #f0506e;
color: #fff;
font-size: 12px;
padding: 2px 6px;
border-radius: 3px;
}
Nếu bỏ position: relative ở thẻ bao, badge rất dễ “trôi” tới một góc nào đó khó hiểu của giao diện. Khi debug layout có absolute, câu hỏi quan trọng nhất luôn là: phần tử này đang bám vào ai.
4. position: absolute – bám theo hệ tọa độ của ai?
Hiểu lầm phổ biến: absolute luôn bám theo toàn trang. Thực tế:
- Nếu có một tổ tiên bất kỳ có
positionkhácstaticthì phần tử absolute sẽ bám theo tổ tiên gần nhất đó. - Nếu không tìm được tổ tiên như vậy, nó mới bám theo viewport (hoặc root element).
Ví dụ minh họa với UIkit:
<div class="uk-card uk-card-default uk-card-body card-wrapper">
<p>Nội dung chính của card</p>
<button class="uk-button uk-button-primary card-button">
Hành động
</button>
</div>
.card-wrapper {
position: relative; /* làm gốc tọa độ cho card-button */
padding-bottom: 50px;
}
.card-button {
position: absolute;
bottom: 12px;
right: 12px;
}
Khi card được lặp nhiều lần trong grid, mỗi nút sẽ bám đúng góc phải dưới của card tương ứng. Nếu bỏ position: relative ở wrapper, tất cả nút có thể chồng lên nhau ở một vị trí ngoài ý muốn.
5. position: fixed – bám theo cửa sổ trình duyệt
position: fixed được dùng khi bạn cần phần tử bám vào một vị trí cố định trên màn hình, không phụ thuộc vào phần tử cha và không bị ảnh hưởng khi cuộn nội dung bên trong một container nào đó. Các trường hợp điển hình:
- Nút “lên đầu trang”.
- Popup chat ở góc màn hình.
- Thanh thông báo luôn hiện phía trên cùng.
Ví dụ đơn giản:
<button class="uk-button uk-button-primary back-to-top">
Lên đầu trang
</button>
.back-to-top {
position: fixed;
right: 16px;
bottom: 16px;
border-radius: 999px;
}
Trong demo đầu bài viết, nút “Trợ giúp” hoạt động theo đúng cơ chế này: dù bạn cuộn vùng nội dung hay cuộn cả trang, nó vẫn bám ở góc dưới bên phải của cửa sổ trình duyệt.
6. position: sticky – trợ thủ tạo trải nghiệm đọc mượt mà
position: sticky là sự kết hợp giữa relative và fixed. Ở trạng thái bình thường, phần tử cư xử như relative. Khi bạn cuộn tới một ngưỡng nhất định, nó “dính” lại như fixed nhưng chỉ trong phạm vi vùng cuộn.
Ví dụ một header trong vùng cuộn:
<div class="uk-card uk-card-default uk-card-body list-wrapper">
<div class="list-heading">Bảng dữ liệu</div>
<div class="list-body">
<!-- nhiều dòng nội dung -->
</div>
</div>
.list-wrapper {
max-height: 300px;
overflow-y: auto;
}
.list-heading {
position: sticky;
top: 0;
background: #fff;
padding: 8px 10px;
border-bottom: 1px solid #eee;
}
Khi cuộn, header này sẽ bám ở phía trên vùng cuộn, giúp người dùng luôn nhìn thấy tiêu đề cột hoặc tên section mà vẫn không chiếm chỗ ở toàn bộ trang như fixed.
7. Những lỗi thường gặp khi dùng position
Đa số layout khó bảo trì đều bắt nguồn từ một vài sai lầm lặp đi lặp lại:
- Dùng absolute để dựng cả layout: cố định từng phần tử bằng
top/lefttrông có vẻ đúng ở một độ phân giải, nhưng chỉ cần nội dung dài hơn hoặc thiết bị khác là vỡ ngay. - Quên thiết lập phần tử cha làm gốc tọa độ: không đặt
position: relativecho thẻ bao nhưng lại dùng absolute cho con, dẫn tới phần tử con bám vào một tổ tiên rất xa. - Nhầm lẫn giữa fixed và sticky: cần phần tử bám trong một khối nội dung cụ thể nhưng lại dùng fixed, khiến nó luôn đè lên mọi thứ khi người dùng cuộn qua các section khác.
- Dùng position để “chữa cháy” thay vì thiết kế lại layout: thay vì cấu trúc lại bằng flex/grid, chỉ thêm absolute cho đến khi nhìn tạm ổn. Kết quả là CSS khó đọc, khó sửa, mỗi lần thêm nội dung là phải căn chỉnh lại từ đầu.
8. Chiến lược sử dụng position cho layout thực tế
Để layout vững và dễ bảo trì, có thể giữ một nguyên tắc đơn giản:
- Dùng flexbox cho bố cục một chiều: hàng hoặc cột.
- Dùng CSS grid cho bố cục hai chiều phức tạp.
- Dùng margin, padding, gap cho khoảng cách.
- Chỉ dùng position khi cần:
- Chồng lớp: badge, tooltip, dropdown, overlay.
- Bám viewport: nút, thanh điều hướng, popup.
- Bám vùng cuộn: header bảng, sidebar filter, tiêu đề section.
Khi phải dùng position, hãy xác định rõ: phần tử này có cần giữ chỗ trong flow hay không, và nó cần bám vào hệ tọa độ nào. Trả lời được hai câu hỏi đó, bạn sẽ ít khi rơi vào vòng lặp thử từng giá trị position chỉ để “đến khi nào nó đúng thì thôi”.
9. Kết luận
Hiểu đúng về position là một bước quan trọng để nâng trình CSS. Chỉ với vài ví dụ nhỏ, bạn có thể thấy rõ sự khác biệt giữa static, relative, absolute, fixed và sticky trong cả layout đơn giản lẫn vùng cuộn phức tạp. Từ đó, mỗi khi cần đặt một phần tử vào vị trí “không bình thường”, bạn sẽ có lý do rõ ràng để chọn kiểu position phù hợp, thay vì chỉ thử tới khi ổn. Khi position không còn là vùng mù mờ, việc xây dựng giao diện ổn định và dễ mở rộng trở nên dễ dàng hơn rất nhiều.
Bình luận