Hiển thị các element đè lên nhau trong css

1) Độ ưu tiên hiển thị là gì !?

- Độ ưu tiên hiển thị có thể tạm hiểu như một loại đơn vị đo lường dùng để quyết định việc "phần tử nào sẽ được hiển thị đè lên phần tử nào trong trường hợp các phần tử đó chồng chéo lên nhau do bị thiết lập nằm ở cùng một vị trí hoặc giao nhau."

- Tôi có một đoạn mã như bên dưới.




    Tiêu đề của trang web
    


    

- Ba phần tử #red #green #blue được thiết lập vị trí giao nhau, nên tại điểm giao nhau ba phần tử này bị chồng chéo lên nhau, trong đó:

  • Phần tử #blue được khai báo sau #green nên nó có độ ưu tiên hiển thị cao hơn #green
  • Phần tử #green được khai báo sau #red nên nó có độ ưu tiên hiển thị cao hơn #red

- Đó là lý do tại sao các bạn thấy phần tử #blue hiển thị đè lên phần tử #green, phần tử #green hiển thị đè lên phần tử #red, mà không phải theo một thứ tự khác.

2) Cách thiết lập độ ưu tiên hiển thị cho một phần tử HTML

Hiển thị các element đè lên nhau trong css

- Sau khi xem xong ví dụ phía trên thì chắc các bạn cũng đã thấy "đối với các phần tử anh em bị thiết lập nằm ở cùng một vị trí (hoặc giao nhau) thì các phần tử được khai báo sau sẽ có độ ưu tiên hiển thị cao hơn các phần tử được khai báo trước, điều đó đồng nghĩa với việc các phần tử khai báo sau sẽ hiển thị đè lên các phần tử khai báo trước."

- Vậy vấn đề đặt ra ở đây là: "Nếu muốn một phần tử được khai báo trước có độ ưu tiên hiển thị cao hơn phần tử được khai báo sau thì chúng ta phải làm như thế nào !?"

- Nếu muốn phần tử được khai báo trước có độ ưu tiên hiển thị cao hơn phần tử được khai báo sau thì chúng ta sử dụng thuộc tính z-index để thiết lập lại độ ưu tiên hiển thị cho phần tử được khai báo trước, sao cho độ ưu tiên hiển thị của nó lớn hơn các phần tử được khai báo sau.

- Cú pháp:

z-index: value;

- Trong đó, value có thể được xác định dựa theo một trong bốn loại giá trị.

auto

- Để mặc định (tương đương với việc không thiết lập độ ưu tiên)

Xem ví dụ
number

- Chỉ định độ ưu tiên hiển thị của phần tử dựa theo một số nguyên cụ thể, số nguyên này có thể là số âm hoặc số dương, số càng lớn thì độ ưu tiên hiển thị càng cao.

Xem ví dụ

- Lưu ý: Chúng ta chỉ nên sử dụng số âm khi muốn thiết lập cho phần tử có độ ưu tiên hiển thị thấp hơn so với những phần tử không được thiết lập độ ưu tiên hiển thị (những phần tử không được thiết lập độ ưu tiên hiển thị thường có mức độ ưu tiên hiển thị tương đương với 0)

Xem ví dụ
initial

- Sử dụng giá trị mặc định của nó.

(mặc định thì thuộc tính z-index có giá trị là auto)

Xem ví dụ
inherit

- Kế thừa giá trị thuộc tính z-index từ phần tử cha của nó.

Xem ví dụ

- Lưu ý: Thuộc tính z-index chỉ có tác dụng khi phần tử được thiết lập thuộc tính position với một trong các giá trị là relative, absolute, fixed.

Chắc hẳn các bạn đã từng cố gắng đặt z-index cho element tuy nhiên lại không có kết quả như mong đợi. Đây là một thuộc tính tưởng chừng đơn giản nhưng đôi khi lại khá là confuse. Bài viết này sẽ giải thích rõ hơn về cách mà z-index hoạt động.

Thứ tự stacking mặc định

Trước tiên ta cùng xem xét thứ tự mặc định mà trình duyệt chồng element lên nhau từ sau lên trước:

  • Element root () dưới cùng
  • Non-positioned elements (static) theo thứ tự code từ trên xuống dưới và đè lên element root
  • Positioned elements (absolute, relative, sticky, fixed) theo thứ tự code từ trên xuống dưới và đè lên non-positioned elements

Ví dụ:

HTML

CSS

/* Để xem full CSS, click link bên dưới*/
.blue, .pink, .orange {
  position: absolute;
}

https://codepen.io/ivhed/pen/QrdEBB

Có thể thấy rằng block green mặc dù có div nằm dưới cùng theo thứ tự từ trên xuống nhưng do không được position nên đã bị những block được position khác đè lên.

Stack với z-index

Để thay đổi thứ tự đè lên nhau mặc định như trên ta có thể sử dụng đến thuộc tính z-index. Element với z-index cao hơn sẽ hiển thị đè lên element có z-index thấp hơn. Cũng cần lưu ý rằng z-index chỉ có tác dụng với những element đã được position.

HTML

CSS

.blue, .pink, .orange {
 position: absolute;
}
.blue {
 z-index: 2;
}
/* Set z-index của block orange cao hơn block blue để hiện thị đè lên block blue */
.orange {
 z-index: 3;
}
.green {
 z-index: 100; /* không có tác dụng */
}

https://codepen.io/ivhed/pen/xjqmpV

Stacking context

Giả sử ta muốn thêm một block purple nằm bên dưới block pink.

HTML

CSS

.blue, .pink, .orange, .purple {
  position: absolute;
}
.purple {
  z-index: 0;
}
/* Set z-index của block pink cao hơn block purple để hiện thị đè lên block purple */
.pink {
  z-index: 1;
}
.blue {
  z-index: 2;
}
.orange {
  z-index: 3;
}
.green {
  z-index: 100;
}

https://codepen.io/ivhed/pen/YLZdjx

Bằng việc đặt z-index của block purple thấp hơn z-index của block pink, block purple đã nằm dưới block pink. Nhưng chuyện gì đã xảy ra khi block màu cam lại bị đè dưới block màu xanh da trời? Đây là một bug phát sinh mà ta không hề mong muốn.

Vâng, lý do là khi ta đặt z-index cho block pink, ta đã tạo nên một thứ gọi là stacking context. z-index của một element chỉ có tác dụng trong phạm vi của stacking context bao hàm element đó. z-index của block orange chỉ có tác dụng trong stacking context do block pink tạo ra vậy nên mặc dù nó cao hơn z-index của block blue thì block orange vẫn bị block blue đè lên do 2 block này khác stacking context.

Để block blue nằm dưới block orange ta có thể làm cho chúng có cùng một stacking context bằng cách đặt div .blue ở trong div .pink.

HTML

https://codepen.io/ivhed/pen/erGoJE

Ngoài thuộc tính z-index thì khi đặt một số thuộc tính khác cho element ta cũng tạo ra một stacking context mới ví dụ: filter, opacity, transform… Bạn có thể tham khảo thêm ở đây.

Quay lại với ví dụ trước khi mà div .blue ngang hàng với div .pink. Lần này thay vì đặt z-index cho block pink ta sẽ thử đặt thuộc tính filter cho block này xem sao.

HTML

CSS

.blue, .pink, .orange {
  position: absolute;
}
/* Set filter cho block pink để tạo một stacking context mới */
.pink {
  filter: hue-rotate(20deg);
}
.blue {
  z-index: 2;
}
/* z-index của block orange chỉ có tác dụng trong stacking context mà block pink tạo ra nên 
mặc dù được set cao hơn của block blue nó vẫn bị block blue đè lên */
.orange {
  z-index: 3;
}
.green {
  z-index: 100;
}

https://codepen.io/ivhed/pen/LmWMQb

Vâng và đúng như dự đoán block orange đã bị block blue đè lên.

Kết luận

Khi muốn apply z-index cho một element bạn cần position cho element đó, đồng thời xác định được stacking context của các element để điều chỉnh sao cho hiển thị được như mong đợi. Cảm ơn các bạn đã theo dõi.

Tham khảo

Z-Index Explained: How to Stack Elements Using CSS

The stacking context