position: absolute qua một ví dụ
Phần tử định vị absolute được nhấc ra khỏi luồng thông thường và đặt bằng top, right, bottom và left. Các khoảng lệch này tính từ phần tử tổ tiên gần nhất có position khác static, vì vậy phần tử cha được đặt position: relative:
Xóa position: relative khỏi .card thì nhãn nhảy lên góc trên bên phải của cả trang, vì nó không còn phần tử tổ tiên nào được định vị. Chỉ một dòng đó đã giải thích phần lớn các câu hỏi "position absolute không hoạt động".
Những điều cần biết về phần tử absolute:
- Chúng không chiếm chỗ. Tiêu đề và đoạn văn được dàn trang như thể nhãn không tồn tại.
- Chiều rộng của chúng co lại vừa nội dung, trừ khi bạn đặt
widthhoặc cảleftlẫnright. - Khoảng lệch được tính đến mép padding của khối chứa, tức là bên trong viền của nó.
Năm giá trị của position
| Giá trị | Nằm trong luồng? | Khoảng lệch tính từ | Dùng điển hình |
|---|---|---|---|
static (mặc định) | Có | Khoảng lệch bị bỏ qua | Phần tử thông thường |
relative | Có, chỗ của nó được giữ | Vị trí bình thường của chính nó | Mốc cho phần tử con absolute, dịch nhẹ |
absolute | Không | Phần tử tổ tiên được định vị gần nhất (hoặc cả trang) | Nhãn, tooltip, lớp phủ, nút đóng |
fixed | Không | Viewport | Header, nút chat, thanh thông báo cookie |
sticky | Có | Scroll container của nó, khi đã chạm khoảng lệch | Tiêu đề bảng, tiêu đề mục, thanh bên |
position: relative
Phần tử định vị relative vẫn ở nguyên chỗ của nó trong luồng. Khoảng lệch dịch chỗ nó được vẽ, nhưng chỗ trống ban đầu vẫn được giữ, nên không có gì xung quanh bị dịch chuyển:
Hộp 2 được vẽ lệch xuống 20px và sang phải 20px, đè lên hộp 3, nhưng hộp 3 không di chuyển: nó vẫn chừa chỗ cho hộp 2 ở vị trí ban đầu. Bản thân relative hiếm khi dùng để di chuyển phần tử; nhiệm vụ chính của nó là làm hộp mốc cho các phần tử con absolute.
Khoảng lệch và inset
top, right, bottom và left nhận độ dài, phần trăm (theo khối chứa) và auto. Thuộc tính viết tắt inset đặt cả bốn theo cùng thứ tự với margin:
.overlay {
position: absolute;
inset: 0; /* top: 0; right: 0; bottom: 0; left: 0; */
}
.corner {
position: absolute;
inset: auto 16px 16px auto; /* bottom right corner, 16px in */
}
Đặt hai cạnh đối diện sẽ kéo giãn phần tử: left: 0; right: 0 làm nó rộng bằng khối chứa. inset: 0 trên phần tử con absolute là cách chuẩn để phủ một lớp lên cả thẻ.
Căn giữa với absolute và transform
top: 50%; left: 50% đặt góc trên bên trái của phần tử vào chính giữa. Sau đó translate(-50%, -50%) kéo nó lùi lại một nửa kích thước của chính nó:
Flexbox và grid căn giữa đơn giản hơn khi phần tử có thể ở trong luồng; trang căn giữa một div so sánh mọi cách làm.
position: fixed
Phần tử fixed được đặt theo viewport và đứng yên ở đó khi trang cuộn:
.chat-button {
position: fixed;
bottom: 16px;
right: 16px;
}
Có hai điểm dễ vấp. Phần tử fixed không chiếm chỗ, nên header fixed sẽ che phần đầu trang trừ khi bạn thêm padding-top cho body. Và nếu bất kỳ phần tử tổ tiên nào có transform, filter hoặc perspective, phần tử tổ tiên đó sẽ thành hộp mốc thay cho viewport, nên phần tử sẽ cuộn theo nó.
position: sticky
Phần tử sticky cuộn bình thường cho đến khi chạm khoảng lệch của nó, rồi dính lại ở đó cho đến khi cuối phần tử cha cuộn qua. Hãy cuộn hộp bên dưới:
Mỗi chữ cái dính vào đỉnh hộp cuộn trong khi mục của nó còn hiển thị, rồi bị chữ tiếp theo đẩy đi, vì phần tử sticky không bao giờ rời khỏi phần tử cha của nó.
Khi sticky không dính, hãy kiểm tra những điều sau:
- Không có khoảng lệch.
position: stickykhông làm gì nếu thiếutop,bottom,lefthoặcright. - Một phần tử tổ tiên có
overflow: hidden,autohoặcscroll. Nó trở thành scroll container, và nếu nó không thật sự cuộn thì không có gì dính cả. Hãy dùngoverflow: clipnếu bạn chỉ cần ẩn phần tràn. - Phần tử cha không cao hơn phần tử sticky. Bên trong không còn chỗ để dính.
- Phần tử cha flex hoặc grid kéo giãn nó. Trong một hàng flex, hãy thêm
align-self: flex-startcho thanh bên sticky.
Lỗi thường gặp
- Quên
position: relativetrên phần tử cha của phần tử absolute. - Dùng absolute để dàn trang. Các phần tử absolute phớt lờ nhau và phớt lờ nội dung, nên chữ sẽ đè lên nhau trên màn hình nhỏ. Hãy dùng flexbox hoặc grid để dàn trang và chỉ dùng absolute cho các chi tiết trang trí nhỏ.
- Đặt khoảng lệch cho phần tử static.
top: 10pxkhông làm gì nếu thiếuposition. - Loay hoay xem phần tử nào nằm trên. Các phần tử định vị chồng lên nhau được sắp xếp theo z-index.
- Header fixed che mất nội dung. Hãy thêm padding cho trang, hoặc
scroll-padding-topđể các liên kết neo dừng ngay bên dưới header.
Câu hỏi thường gặp
position: absolute có tác dụng gì?
Nó đưa phần tử ra khỏi luồng thông thường (các phần tử khác hành xử như thể nó không tồn tại) và đặt nó bằng top, right, bottom và left, tính từ khối chứa của nó: phần tử tổ tiên gần nhất có position khác static.
Làm sao định vị absolute một phần tử theo phần tử cha?
Đặt position: relative; cho phần tử cha và position: absolute; cho phần tử con, kèm các khoảng lệch như top: 0; right: 0;. Nếu không có phần tử cha được định vị, phần tử con sẽ được đặt theo cả trang.
position relative và absolute khác nhau thế nào?
relative giữ phần tử trong luồng và chỉ dịch chỗ nó được vẽ, chỗ trống ban đầu vẫn được giữ lại. absolute gỡ phần tử khỏi luồng và đặt nó theo phần tử tổ tiên được định vị.
Vì sao position: sticky không hoạt động?
Thường là do một trong ba lý do: chưa đặt top (hoặc khoảng lệch khác), một phần tử tổ tiên có overflow: hidden hoặc auto và trở thành scroll container, hoặc phần tử cha của phần tử sticky không cao hơn chính nó, nên không còn chỗ để dính.
fixed và sticky khác nhau thế nào?
fixed bị gỡ khỏi luồng và ghim vào viewport (trừ khi một phần tử tổ tiên có transform hoặc filter). sticky vẫn ở trong luồng và cuộn bình thường cho đến khi chạm khoảng lệch của nó, rồi dính lại trong khi phần tử cha vẫn còn trên màn hình.