Bạn có hiểu rõ z-index trong CSS hay không :)
CSS
32
White

Vu Nhat Minh viết ngày 23/10/2015

Nguyên lý hoạt động của z-index

Nếu bạn là một front-end developer và thường xuyên làm việc với CSS, chắc bạn không còn lạ lẫm gì với z-index. Về lý thuyết thì cách thức hoạt động của z-index rất đơn giản: mỗi element trên trang web được hiển thị ngang và dọc theo 2 trục x và y, hiển thị thứ tự chồng lấn theo trục z. Hình vẽ bên dưới của smashingmagazine thể hiện rất dễ hiểu:

z-index imagination

z-index và position

Bây giờ mình sẽ lấy ví dụ cụ thể. Chúng ta có 3 block green, red, blue đều trực thuộc trực tiếp một div có class demo. Điều này khiến cho 3 block thuộc cùng một stacking context. Trong cùng một stacking context thì thứ tự trên dưới luôn được đảm bảo theo quy tắc: element nào có z-index cao hơn sẽ hiện lên trên. Nếu chưa có một element nào được set z-index thì thứ tự sẽ phụ thuộc vào thứ tự xuất hiện từ trước ra sau của DOM tree.

<div class="demo">
  <div class="red">
    <span>Red</span>
  </div>
  <div class="green">
    <span>Green</span>
  </div>
  <div class="blue">
    <span>Blue</span>
  </div>
</div>
.demo {
  margin-left: 40px;
  margin-top: 40px;
}
.red, .green, .blue {
  width: 100px;
  height: 100px;
  color: white;
  line-height: 100px;
  text-align: center;
}
.red {
  background: red;
}
.green {
  margin-top: -40px;
  margin-left: 60px;
  background: green;
}
.blue {
  margin-top: -40px;
  margin-left: 120px;
  background: blue;
}

Bây giờ thêm z-index vào 3 block để cho block red nổi lên đầu, block green nổi lên thứ 2 và block blue xuống cuối cùng

.red {
  z-index: 3;
}
.green {
  z-index: 2;
}
.blue {
  z-index: 1;
}

Bạn sẽ ngạc nhiên khi thấy thứ tự không hề thay đổi. z-index hoàn toàn không có giá trị trong lúc này!

Lý do ở đây là, z-index hoàn toàn mất tác dụng đối với những element không chỉ định positionlà một trong 3 giá trị absolute, fixed hay relative. Mình sẽ chỉnh như sau

.red {
  z-index: 3;
  position: relative;
}
.green {
  z-index: 2;
  position: relative;
}
.blue {
  z-index: 1;
  position: relative;
}

Chúng ta sẽ lập tức thấy hiệu quả của z-index

z-index âm và element không có position

Bây giờ mình lấy ví dụ về z-index âm và element không có thuộc tính position. Block green được bỏ position đi như sau

.red {
  z-index: 3;
  position: relative;
}
.green {
  z-index: 2;
  /*position: relative;*/
}
.blue {
  z-index: 1;
  position: relative;
}


Block green ngay lập tức mất ảnh hưởng của z-index và trờ về vị trí của một block với z-index: 0!
Dĩ nhiên, để ẩn ra sau một block với z-index:0 thì có thể set z-index thành một số âm như với block blue dưới đây

.red {
  z-index: 3;
  position: relative;
}

.green {
  z-index: 2;
  /*position: relative;*/
}

.blue {
  z-index: -1;
  position: relative;
}

Có thể tồn tại rất nhiều Stacking Context !

2 ví dụ bên trên thật dễ phải không :) Vậy hãy thử giải thích bài toán dưới đây.

<div>
  <span class="red">Red</span>
</div>
<div>
  <span class="green">Green</span>
</div>
<div>
  <span class="blue">Blue</span>
</div>
div:first-child {
  opacity: .99;
}
.red, .green, .blue {
  position: absolute;
  width: 100px;
  color: white;
  line-height: 100px;
  text-align: center;
}
.red {
  z-index: 1;
  top: 20px;
  left: 20px;
  background: red;
}
.green {
  top: 60px;
  left: 60px;
  background: green;
}
.blue {
  top: 100px;
  left: 100px;
  background: blue;
}

Rõ ràng là block red có z-index là 1, trong khi 2 block còn lại không chỉ định z-index (đồng nghĩ với việc mang giá trị z-index = 0). Cả 3 block đều có position: absolute nên thông số về z-index là hoàn toàn có giá trị. Tại sao block red lại ở dưới cùng ?
Nếu theo đúng thứ tự thì 3 khối block phải trông như dưới đây:

Để trả lời câu hỏi trên, chúng ta hãy để ý cấu trúc DOM trong bài toán này. red. green, blue bây giờ là 3 span không nằm trực tiếp trong một div, mà nằm trong 3 div là anh chị em với nhau !

Khi này, red, green, blue vẫn thuộc global stacking context chung của DOM tree. Tuy nhiên cần phải chú ý một điểm nữa là red nằm trong một div có thuộc tính opacity: .99! Với opacity, div nói trên đã "mở nhánh" ra thành một stacking context mới. Và z-index:1 của red về thực tế chỉ có giá trị trong nhánh stacking context nói trên.

Điều này có nghĩa là, toàn bộ div chứa red vẫn có thứ tự nhỏ hơn div chứa greenblue (do thứ tự xuất hiện từ trước ra sau của DOM), dẫn đến hiển thị như bài toán ban đầu đặt ra.

Kết luận

z-index là một tính chất hay gây nhức đầu đối với developer mới làm quen CSS. Tuy nhiên nếu nắm bắt tốt về stacking context, position và những thuộc tính có thể khiến stacking context "mở nhánh" như opacity, thì sẽ phần nào bớt-nhức-đầu hơn :)

Tham khảo

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

Vu Nhat Minh

54 bài viết.
721 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
116 29
Nếu bạn thường vào trang mua sắm của amazon, chắc sẽ chẳng lạ gì với menu Shop by Department. Tốc độ hiển thị nội dung của menu là tức thì so với d...
Vu Nhat Minh viết hơn 2 năm trước
116 29
White
87 4
Lời người dịch Người dịch là một developer , sau khi tìm đọc được bài viết này bằng bản gốc tiếng Anh đã cảm thấy như được "khai sáng" về khả năng...
Vu Nhat Minh viết hơn 2 năm trước
87 4
White
56 5
Đây là phần cuối của một series chuyên về thiết kế UI. Bạn nên đọc (Link) trước khi bắt đầu đọc phần này. Luật số 7: "Ăn trộm" như là một nghệ sỹ...
Vu Nhat Minh viết hơn 2 năm trước
56 5
Bài viết liên quan
White
16 9
Lời nói đầu Tuần trước mình đã bắt tay vào làm thử app theo ý tưởng clone chương trình "Ai là triệu phú" trên TV, với các chức năng cơ bản, chỉ sử...
Andy Crush viết hơn 2 năm trước
16 9
White
6 3
Sau đây là cách để tạo một square div và canh giữa theo chiều dọc bằng css. Đây là cách làm rất hay, hỗ trợ được những browser đời cũ như IE8 mà ko...
Toan Nguyen viết hơn 2 năm trước
6 3
White
12 0
Giới thiệu cơ bản về Styled components 1. Styled components là gì? 1.1. Phương pháp css truyền thống Trước khi nói về styled components chúng ta...
danhuynhdev viết 6 tháng trước
12 0
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
54 bài viết.
721 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!