0
0
Lập trình
Thaycacac
Thaycacac thaycacac

Giải quyết nhầm lẫn với z-index một lần và mãi mãi

Đăng vào 5 ngày trước

• 4 phút đọc

Giải quyết nhầm lẫn với z-index một lần và mãi mãi

Giới thiệu

Trong quá trình phát triển web, chắc hẳn nhiều lập trình viên đã từng gặp phải tình huống khó chịu khi sử dụng thuộc tính z-index, đặc biệt là khi phải viết z-index: 99999; mà không đạt được kết quả mong muốn. Bài viết này sẽ giúp bạn hiểu rõ hơn về cách hoạt động của z-index, cùng với những mẹo và nguyên tắc quan trọng để tránh nhầm lẫn trong tương lai.

Hiểu về z-index

Các quy tắc cơ bản về z-index

Trước khi đi vào chi tiết, hãy cùng điểm qua một số quy tắc cơ bản nhưng rất quan trọng khi làm việc với z-index:

  • Nếu một phần tử không có giá trị z-index xác định, nó sẽ có giá trị z-index: auto.
  • Để z-index hoạt động, chúng ta phải định nghĩa một giá trị position khác ngoài static.
  • z-index sẽ hoạt động với flex và grid mà không cần định nghĩa một position.
  • Các phần tử nằm sâu hơn trong tài liệu sẽ nằm trên các phần tử xuất hiện trước chúng.

Khái niệm về Stacking Contexts

Để hiểu rõ hơn về những vấn đề liên quan đến z-index, chúng ta cần nắm vững một khái niệm rất quan trọng đó là Stacking Contexts. Đơn giản mà nói, stacking context là lý do khiến giá trị 99999 của bạn không hoạt động như mong đợi.

Để minh họa, hãy tưởng tượng một ví dụ đơn giản: so sánh độ tuổi của cha và con cái. Giả sử chúng ta có 2 người cha, mỗi người có 2 cậu con trai. Ahmed có Omar và Marwan, trong khi Mark có John và Jack.

Các quy tắc ở đây là chúng ta không thể so sánh độ tuổi của một đứa trẻ với độ tuổi của một người cha, và cũng không thể so sánh độ tuổi của một đứa trẻ với độ tuổi của đứa trẻ khác từ một người cha khác. Chúng ta chỉ có thể so sánh giữa độ tuổi của hai người cha (Ahmed và Mark), hoặc giữa độ tuổi của hai anh em.

Khi một người cha có đứa trẻ đầu tiên, anh ta bắt đầu tạo ra một gia đình (stacking context). Về logic, không thể có chuyện một trong những đứa trẻ lớn tuổi hơn cha của nó. Dù đứa trẻ đó có cao bao nhiêu hoặc nặng bao nhiêu (z-index: 99999;), nó cũng không thể vượt qua cha mình.

html Copy
<div class="position-relative z-index-2" id="Ahmed">
   <p class="position-relative z-index-10" id="Marwan"></p>
   <p class="position-relative z-index-1000" id="Omar"></p>
</div>

<div class="position-relative z-index-1" id="Mark">
   <p class="position-relative z-index-10" id="John"></p>
   <p class="position-relative z-index-1000" id="Jack"></p>
</div>

Trong ví dụ này, div với idAhmed tạo ra một stacking context khi nó có position: relativez-index: 2, vì vậy nó bắt đầu có gia đình riêng của mình.

Do đó, đứa trẻ với idOmar sẽ không bao giờ lớn hơn cha nó, mặc dù nó có z-index cao hơn.

Trong cùng một gia đình, chúng ta có thể so sánh hai anh em, vì vậy Omar cao hơn Marwan.

So sánh các stacking contexts

Bây giờ, nếu chúng ta muốn so sánh Ahmed với Mark? Vì cả hai đều đã tạo ra gia đình riêng (stacking contexts), chúng ta có thể so sánh chúng. Trong trường hợp này, Ahmed sẽ cao hơn Mark, vì Ahmedz-index cao hơn.

Còn nếu so sánh Mark với Omar? Như đã đề cập trước đó, chúng ta không thể so sánh cha với con của một người cha khác. Trong trường hợp này, chúng ta sẽ phải so sánh Mark với cha của Omar, tức là Ahmed.

Những trường hợp đặc biệt

Có những tình huống mà con cái có thể nằm trên cha mẹ của chúng. Điều này xảy ra khi cha không có position nào ngoài static. Trong trường hợp này, cha không tạo ra một stacking context mới, vì vậy đứa trẻ sẽ được so sánh trong root stacking context, ngay cả khi cha có z-index.

Theo ví dụ trên, điều này giống như việc đứa trẻ Omar đã trở thành một người cha và hiện đang được so sánh với các người cha khác.

Giải pháp cho vấn đề z-index

Biết được vấn đề là một nửa của giải pháp. Bây giờ khi vấn đề đã rõ ràng, bạn có thể nghĩ rằng "Nếu vấn đề là đứa trẻ bị mắc kẹt trong stacking context của cha, có lẽ giải pháp là tìm cách di chuyển đứa trẻ ra ngoài". Bạn hoàn toàn đúng, và đó là những gì mà các đội ngũ Vue và React đã làm khi tạo ra PortalTeleport.

PortalTeleport được sử dụng để dịch chuyển một phần tử nhất định (như dropdown, modals, popovers) đến body, nhằm giải phóng nó khỏi stacking context của cha.

Những giải pháp khác có thể bao gồm việc cấu trúc lại HTML của bạn, thay đổi thuộc tính position của các phần tử. Bạn đã hiểu ý tôi.

Tóm tắt

Dưới đây là một sơ đồ tóm tắt những điểm chính đã đề cập ở trên, giúp bạn nắm bắt khái niệm một cách rõ ràng hơn. Hy vọng rằng đây sẽ là sự kết thúc cho những giá trị 9 ngẫu nhiên bị ném vào mã của bạn.

Có thể bạn sẽ tự tin hơn khi giải thích cho nhóm của mình về những gì bạn đã hiểu 😉.

Nếu bạn có bất kỳ câu hỏi nào hoặc phản hồi, hãy để lại dưới đây. Tôi rất muốn nghe ý kiến của bạn.

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào