Cascading Style Sheets

Thuộc tính z-index

Thuộc tính z-index để điều khiển thứ tự hiện thị các phần tử khi chúng bị đè lên nhau (xếp chồng lên nhau). Có nghĩa trong trường hợp các phần tử đè lên nhau (như khi bạn áp dụng các thuộc tính position, left, top ...), thì bạn có thể chỉ định phần tử nào là phía trước (nằm trên) phần tử nào phía sau (nằm dưới).

Thuộc tính z-order là xếp thứ tự phần tử theo trục z. Một phần tử có giá trị z-order cao hơn thì nó sẽ nằm trên (đè lên) phần tử có z-order thấp hơn.

Để hiểu rõ về z-index cũng cần tìm hiểu về ngữ cảnh xếp chồng các phần tử, nghĩa là ảnh hưởng của z-index tùy thuộc vào ngữ cảnh của nó nữa.

Cú pháp:

z-index: auto | int

z-index có giá trị nhận là auto thì trong ngữ ảnh xếp chồng của nó nó có giá trị index là 0. Còn lại muốn thiết lập thứ tự z-index của nó thì chỉ ra giá trị là một số nguyên

Có ví dụ sau:

<style>
    .parent-ele {
        border: 1px solid red;
        padding: 10px;
        position: relative;
        width: 600px;
    }
    .child-ele {
        text-align: center;
        display: inline-block;
        position: relative;
        height: 150px;
        width: 150px;
    }
    .green-ele {
        background: #008000d1;
        left: 10px;
        top: 10px;
    }
    .red-ele {
        background: #ff0000d1;
        left: -110px;
        top: 40px;
    }
    .orange-ele {
        background: #ff8c00cc;
        left: -230px;
        top: 70px;
    }
    .zindex-1 {
        z-index: 1;
    }
    .zindex-2 {
        z-index: 2;
    }
    .zindex-3 {
        z-index: 3;
    }
    .zindex-4 {
        z-index: 4;
    }
    .zindex-5 {
        z-index: 5;
    }
    .zindex-6 {
        z-index: 6;
    }
</style>

<div class="parent-ele">
    <div class="child-ele green-ele">[1]</div>
    <div class="child-ele green-red">[2]</div>
    <div class="child-ele green-orange">[3]</div>
</div>
[1]
[2]
[3]

Các box màu xanh, đỏ, cam cùng phần trong một phần tử cha (cùng một ngữ ảnh xếp chồng) - không có thiết lập z-index (hoặc z-index đều bằng nhau) thì phần tử nào phía sau trong DOM (trong HTML) sẽ xếp chồng lên phần tử đứng trước. Box màu vàng đè lên cả box đỏ và box xanh.

Giờ muốn box vàng ở dưới cùng - box xanh ở trên cùng thì chỉ cần cho box vàng có z-index nhỏ nhất và box xanh có z-index lớn nhất

<div class="parent-ele">
    <div class="child-ele green-ele zindex-3">zindex-3</div>
    <div class="child-ele red-ele zindex-2">zindex-2</div>
    <div class="child-ele orange-ele zindex-1">zindex-1</div>
</div>
zindex-3
zindex-2
zindex-1

Thử cho box đỏ lên trên cùng, rồi đến xanh, cuối cùng là vàng

<div class="parent-ele">
    <div class="child-ele green-ele zindex-2">zindex-2</div>
    <div class="child-ele red-ele zindex-3">zindex-3</div>
    <div class="child-ele orange-ele zindex-1">zindex-1</div>
</div>
zindex-2
zindex-3
zindex-1

Ngữ cảnh xếp chồng phần tử stacking context

Ngư cảnh xếp chồng là hệ tọa độ 3 chiều (x,y,z), các phần tử thuộc về một ngữ cảnh xếp chồng chúng được sắp xếp trong nó theo thứ tự lập bởi z-index.

Ngữ cảnh xếp chồng có thể hình thành ở bất kỳ đầu, sau đây là một số trường hợp:

  • Phần tử gốc <html>
  • Phần tử có giá trị position là absolute hoặc relative đồng thời có z-index khác auto.
  • Phần tử có giá trị position là fixed hoặc sticky.
  • Phần tử con trong flex hoặc grid có z-index khác auto.
  • Phần tử có opacity khác 1.
  • Phần tử có transform hoặc filter khác none.

Để xác định một phần tử thuộc ngữ cảnh xếp chồng nào, cần truy ngược các phần tử chứa trong cây kế thừa sao cho gặp ngữ cảnh trên.

Có đoạn mã sau:

<style>
    .parent-ele1 {
        position: absolute;
        background: #c0c0c0c9;
        height: 300px;
    }
    .parent-ele2 {
        position: absolute;
        background: #821EA43F;
        height: 300px;
        top:  100px;
        left: 100px;
    }
</style>

<div class="parent-ele zindex-1">
    <div class="parent-ele1">
        <div class="child-ele green-ele">green in parent1</div>
        <div class="child-ele red-ele">red in parent1</div>
        <div class="child-ele orange-ele">orange  in parent1</div>
    </div>

    <div class="parent-ele2">
        <div class="child-ele green-ele">green  in  parent2</div>
        <div class="child-ele red-ele">red  in parent2</div>
        <div class="child-ele orange-ele">orange  in parent2</div>
    </div>
</div>

Xét sau phần tử con, truy ngược lại phần tử chứa cha thì chúng đều nằm trong phần tử gần nhất có class là parent-ele (có position: relative; và z-index khác auto). Do vậy sau phần tử này có thể dùng z-index để xếp thứ tự của chúng trong ngữ cảnh xếp chồng này. Đầu tiên, khi chưa set z-index thì thứ tự của nó theo thứ tự viết phần tử

green in parent1
red in parent1
orange in parent1
green in parent2
red in parent2
orange in parent2

Bây giờ hãy sắp xếp thứ tự : orange in parent1, green in parent2, red in parent2, orange in parent2, red in parent1, green in parent1

<div class="parent-ele zindex-1">
    <div class="parent-ele1">
        <div class="child-ele green-ele zindex-1">green in parent1</div>
        <div class="child-ele red-ele zindex-2">red in parent1</div>
        <div class="child-ele orange-ele zindex-6">orange  in parent1</div>
    </div>

    <div class="parent-ele2">
        <div class="child-ele green-ele zindex-5">green  in  parent2</div>
        <div class="child-ele red-ele zindex-4">red  in parent2</div>
        <div class="child-ele orange-ele zindex-3">orange  in parent2</div>
    </div>
</div>
green in parent1
red in parent1
orange in parent1
green in parent2
red in parent2
orange in parent2

Thay đổi ngữ cảnh xếp chồng

Bây giờ thẻ div có class parent-ele1parent-ele2 thiết lập nó có position (khác auto). Như giải thích phần trên, hai nó sẽ tạo ra hai ngữ cảnh xếp chồng khác nhau, và như vậy thuộc tính z-index trong các phần tử con trong hai thẻ này chỉ ảnh hưởng trong nội bộ phần tử.

<div class="parent-ele zindex-1">
    <div class="parent-ele1 zindex-2">
        <div class="child-ele green-ele zindex-4">green in parent1</div>
        <div class="child-ele red-ele zindex-6">red in parent1</div>
        <div class="child-ele orange-ele zindex-2">orange  in parent1</div>
    </div>

    <div class="parent-ele2 zindex-1">
        <div class="child-ele green-ele zindex-3">green  in  parent2</div>
        <div class="child-ele red-ele zindex-5">red  in parent2</div>
        <div class="child-ele orange-ele zindex-1">orange  in parent2</div>
    </div>
</div>
green in parent1
red in parent1
orange in parent1
green in parent2
red in parent2
orange in parent2

Như kết quả, parent-ele1 có z-index là 2, do vậy nó nằm trên parent-ele2 (có z-index là 1), và chúng là hai ngữ cảnh khác nhau thì tất cả các phần tử con trong parent-ele2 đều nằm dưới dưới các phần tử con trong parent-ele1. Cho dù phần tử tử con trong parent-ele2 có z-index lớn hơn.

Hai ngữ cảnh xếp chồng khác nhau, ngữ cảnh nào xếp trên thì các phần tử con của nó cũng xếp trên phần tử con của ngữ cảnh còn lại.


Đăng ký nhận bài viết mới