Menu

CSS position: absolute, relative, fixed và sticky

position: absolute đặt phần tử ở tọa độ chính xác bên trong phần tử tổ tiên được định vị gần nhất. Tìm hiểu absolute hoạt động cùng position: relative thế nào, rồi đến fixed và sticky, các thuộc tính top/right/bottom/left và inset, và vì sao sticky đôi khi không dính.

Trang này có trình soạn thảo chạy trực tiếp. Sửa, chạy và xem đầu ra ngay lập tức.

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 width hoặc cả left lẫn right.
  • 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ỏ quaPhần tử thông thường
relativeCó, 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ẹ
absoluteKhôngPhầ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
fixedKhôngViewportHeader, nút chat, thanh thông báo cookie
stickyCóScroll container của nó, khi đã chạm khoảng lệchTiê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: sticky không làm gì nếu thiếu top, bottom, left hoặc right.
  • Một phần tử tổ tiên có overflow: hidden, auto hoặc scroll. 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ùng overflow: clip nế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-start cho thanh bên sticky.

Lỗi thường gặp

  • Quên position: relative trê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: 10px không làm gì nếu thiếu position.
  • 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.

Hình minh họa các ngôn ngữ lập trình của Coddy

Học lập trình cùng Coddy

Bắt đầu