Bạn đã bao giờ đặt z-index: 99999 trên một phần tử trong CSS của mình và nó không xuất hiện trên các phần tử khác chưa? Một giá trị lớn sẽ dễ dàng đặt phần tử đó lên trên bất kỳ phần tử nào khác một cách trực quan, giả sử tất cả các phần tử khác nhau được đặt ở giá trị thấp hơn hoặc hoàn toàn không được đặt. Trang web thường được thể hiện trong không gian hai chiều; tuy nhiên, bằng cách áp dụng các thuộc tính CSS cụ thể, một mặt phẳng trục z tưởng tượng được đưa vào để truyền tải chiều sâu. Mặt phẳng này vuông góc với màn hình và từ đó, người dùng nhận thấy thứ tự của các phần tử, cái này chồng lên cái kia. Ý tưởng đằng sau trục z tưởng tượng, nhận thức của người dùng về các phần tử xếp chồng, là các thuộc tính CSS tạo ra nó kết hợp với nhau để tạo thành cái mà chúng ta gọi là bối cảnh xếp chồng. Chúng ta sẽ nói về cách các phần tử được “xếp chồng” trên một trang web, điều gì kiểm soát thứ tự xếp chồng và các cách tiếp cận thực tế để “xếp chồng” các phần tử khi cần. Giới thiệu về bối cảnh xếp chồng Hãy tưởng tượng trang web của bạn như một cái bàn. Khi bạn thêm các phần tử HTML, bạn đang đặt từng mảnh giấy lên bàn. Mảnh giấy cuối cùng được đặt tương đương với phần tử HTML được thêm gần đây nhất và nó nằm trên tất cả các tờ giấy khác được đặt trước nó. Đây là luồng tài liệu bình thường, ngay cả đối với các phần tử lồng nhau. Bản thân bàn biểu thị bối cảnh xếp chồng gốc, được hình thành bởi phần tử , chứa tất cả các thư mục khác. Bây giờ, các thuộc tính CSS cụ thể sẽ phát huy tác dụng. Các thuộc tính như vị trí (với chỉ mục z), độ mờ, biến đổi và chứa) hoạt động giống như một thư mục. Thư mục này lấy một phần tử và tất cả các phần tử con của nó, trích xuất chúng từ ngăn xếp chính và nhóm chúng thành một ngăn xếp phụ riêng biệt, tạo ra cái mà chúng ta gọi là bối cảnh xếp chồng. Đối với các phần tử được định vị, điều này xảy ra khi chúng ta khai báo một giá trị chỉ mục z khác với giá trị tự động. Đối với các thuộc tính như độ mờ, biến đổi và bộ lọc, bối cảnh xếp chồng được tạo tự động khi áp dụng các giá trị cụ thể.

Hãy cố gắng hiểu điều này: Khi một mảnh giấy (tức là một phần tử con) nằm trong một thư mục (tức là bối cảnh xếp chồng của cha mẹ), nó không bao giờ có thể thoát khỏi thư mục đó hoặc được đặt giữa các giấy tờ trong một thư mục khác. Chỉ mục z của nó bây giờ chỉ có liên quan trong thư mục riêng của nó.

Trong hình minh họa bên dưới, Giấy B hiện nằm trong bối cảnh xếp chồng của Thư mục B và chỉ có thể được sắp xếp cùng với các giấy tờ khác trong thư mục.

Nếu muốn, hãy tưởng tượng rằng bạn có hai thư mục trên bàn làm việc:

Thư mục A
Thư mục B

.folder-a { z-index: 1; } .folder-b { z-index: 2; }

Hãy cập nhật đánh dấu một chút. Bên trong Thư mục A là một trang đặc biệt, z-index: 9999. Bên trong Thư mục B là một trang đơn giản, z-index: 5.

Trang đặc biệt

Trang thuần túy

.trang đặc biệt { z-index: 9999; } .plain-page { z-index: 5; }

Trang nào ở trên cùng? Đó là trang .plain trong Thư mục B. Trình duyệt bỏ qua các giấy tờ con và xếp chồng hai thư mục lên nhau trước tiên. Nó nhìn thấy Thư mục B (z-index: 2) và đặt nó lên trên Thư mục A (z-index: 1) vì chúng ta biết rằng hai lớn hơn một. Trong khi đó, trang .special-page được đặt thành z-index: 9999 nằm ở cuối ngăn xếp mặc dù chỉ mục z của nó được đặt thành giá trị cao nhất có thể. Các bối cảnh xếp chồng cũng có thể được lồng vào nhau (các thư mục bên trong các thư mục), tạo ra một “cây phả hệ”. Nguyên tắc tương tự cũng được áp dụng: một đứa trẻ không bao giờ có thể thoát khỏi thư mục của cha mẹ nó. Bây giờ bạn đã hiểu cách các ngữ cảnh xếp chồng hoạt động giống như các thư mục nhóm và sắp xếp lại các lớp, điều đáng đặt ra là: tại sao các thuộc tính nhất định — như biến đổi và độ mờ — lại tạo các ngữ cảnh xếp chồng mới? Vấn đề là thế này: những thuộc tính này không tạo ra bối cảnh xếp chồng vì hình thức của chúng; họ làm điều đó vì cách thức hoạt động của trình duyệt. Khi bạn áp dụng biến đổi, độ mờ, bộ lọc hoặc phối cảnh, bạn đang thông báo cho trình duyệt: "Này, phần tử này có thể di chuyển, xoay hoặc mờ dần, vì vậy hãy sẵn sàng!"

Khi bạn sử dụng các thuộc tính này, trình duyệt sẽ tạo bối cảnh xếp chồng mới để quản lý việc hiển thị hiệu quả hơn. Điều này cho phép trình duyệt xử lý hoạt ảnh, biến đổi và hiệu ứng hình ảnh một cách độc lập, giảm nhu cầu tính toán lại cách các phần tử này tương tác với phần còn lại của trang. Hãy nghĩ về điều này khi trình duyệt nói: “Tôi sẽ xử lý thư mục này một cách riêng biệt để tôi không phải sắp xếp lại toàn bộ bàn làm việc mỗi khi có gì đó bên trong nó thay đổi”. Nhưng cómột tác dụng phụ. Khi trình duyệt nâng một phần tử vào lớp riêng của nó, nó phải “làm phẳng” mọi thứ bên trong nó, tạo ra một bối cảnh xếp chồng mới. Nó giống như lấy một tập hồ sơ ra khỏi bàn để xử lý riêng; mọi thứ bên trong thư mục đó sẽ được nhóm lại và trình duyệt hiện coi nó như một đơn vị duy nhất khi quyết định cái gì nằm trên cái gì. Vì vậy, mặc dù các thuộc tính biến đổi và độ mờ có thể không ảnh hưởng đến cách các phần tử xếp chồng lên nhau một cách trực quan, nhưng chúng ảnh hưởng đến việc tối ưu hóa hiệu suất. Một số thuộc tính CSS khác cũng có thể tạo bối cảnh xếp chồng vì những lý do tương tự. MDN cung cấp danh sách đầy đủ nếu bạn muốn tìm hiểu sâu hơn. Có khá nhiều thứ chỉ minh họa mức độ dễ dàng vô tình tạo ra bối cảnh xếp chồng mà không biết. Vấn đề “Dỡ bỏ” Các vấn đề về xếp chồng có thể phát sinh vì nhiều lý do, nhưng một số lý do phổ biến hơn những lý do khác. Các thành phần phương thức là một mẫu cổ điển vì chúng yêu cầu chuyển đổi thành phần để “mở” trên lớp trên cùng phía trên tất cả các thành phần khác, sau đó loại bỏ nó khỏi lớp trên cùng khi nó được “đóng”. Tôi khá tự tin rằng tất cả chúng ta đều đã từng gặp phải trường hợp mở một modal và vì bất kỳ lý do gì mà nó không xuất hiện. Không phải là nó không mở đúng cách mà là nó nằm ngoài tầm nhìn ở lớp thấp hơn của bối cảnh xếp chồng. Điều này khiến bạn phải tự hỏi “làm sao vậy?” kể từ khi bạn đặt:

.lớp phủ { vị trí: cố định; /* tạo bối cảnh xếp chồng */ chỉ số z: 1; /* đặt phần tử lên một lớp phía trên mọi phần tử khác */ chèn: 0; chiều rộng: 100%; chiều cao: 100vh; tràn: ẩn; màu nền: #00000080; }

Điều này có vẻ đúng, nhưng nếu phần tử cha chứa trình kích hoạt phương thức là phần tử con bên trong phần tử cha khác cũng được đặt thành chỉ mục z: 1, thì về mặt kỹ thuật, phần tử đó sẽ đặt phương thức đó trong một lớp con bị thư mục chính che khuất. Hãy xem xét kịch bản cụ thể đó và một số cạm bẫy phổ biến khác trong bối cảnh xếp chồng. Tôi nghĩ bạn sẽ không chỉ thấy việc vô tình tạo ra các bối cảnh xếp chồng dễ dàng như thế nào mà còn thấy cách quản lý chúng sai cách. Ngoài ra, cách bạn quay lại trạng thái được quản lý còn tùy thuộc vào tình huống. Kịch bản 1: Phương thức bị mắc kẹt

Bạn có thể thấy ngay phương thức của mình bị mắc kẹt trong lớp cấp thấp và xác định lớp cha. Tiện ích mở rộng trình duyệt Các nhà phát triển thông minh đã xây dựng các tiện ích mở rộng để trợ giúp. Các công cụ như tiện ích mở rộng Chrome “Trình kiểm tra bối cảnh xếp chồng CSS” này thêm một tab chỉ mục z bổ sung vào DevTools của bạn để hiển thị cho bạn thông tin về các thành phần tạo bối cảnh xếp chồng.

Tiện ích mở rộng IDE Bạn thậm chí có thể phát hiện các vấn đề trong quá trình phát triển bằng tiện ích mở rộng như tiện ích mở rộng này dành cho VS Code, tiện ích này nêu bật các vấn đề bối cảnh xếp chồng tiềm ẩn ngay trong trình chỉnh sửa của bạn.

Giải nén và lấy lại quyền kiểm soát Sau khi chúng tôi xác định được nguyên nhân gốc rễ, bước tiếp theo là giải quyết nó. Có một số cách tiếp cận bạn có thể thực hiện để giải quyết vấn đề này và tôi sẽ liệt kê chúng theo thứ tự. Tuy nhiên, bạn có thể chọn bất kỳ ai ở mọi cấp độ; không ai có thể phàn nàn hay cản trở người khác. Thay đổi cấu trúc HTML Đây được coi là cách khắc phục tối ưu. Để gặp phải vấn đề về bối cảnh xếp chồng, bạn phải đặt một số thành phần ở những vị trí hài hước trong HTML của mình. Cơ cấu lại trang sẽ giúp bạn định hình lại DOM và loại bỏ vấn đề bối cảnh xếp chồng. Tìm phần tử có vấn đề và xóa phần tử đó khỏi phần tử bẫy trong đánh dấu HTML. Ví dụ: chúng ta có thể giải quyết tình huống đầu tiên, “The Trapped Modal,” bằng cách di chuyển .modal-container ra khỏi tiêu đề và đặt nó vào chính phần tử .

Tiêu đề

Nội dung chính

Nội dung này có chỉ số z là 2 và sẽ vẫn không bao gồm phương thức.

Khi bạn nhấp vào nút “Mở phương thức”, phương thức đó sẽ được đặt ở phía trước mọi thứ khác như dự kiến. Xem Kịch bản Bút 1: Phương thức bị mắc kẹt (Giải pháp) [phân nhánh] của Shoyombo Gabriel Ayomide. điều chỉnhBối cảnh xếp chồng cha mẹ trong CSS Điều gì sẽ xảy ra nếu phần tử đó là thứ bạn không thể di chuyển mà không phá vỡ bố cục? Tốt hơn là nên giải quyết vấn đề: cha mẹ thiết lập bối cảnh. Tìm thuộc tính CSS (hoặc các thuộc tính) chịu trách nhiệm kích hoạt ngữ cảnh và xóa nó. Nếu nó có mục đích và không thể xóa được, hãy cung cấp cho phần tử cha một giá trị chỉ số z cao hơn các phần tử anh chị em của nó để nâng toàn bộ vùng chứa. Với giá trị chỉ mục z cao hơn, vùng chứa chính sẽ di chuyển lên trên cùng và các phần tử con của nó xuất hiện gần người dùng hơn. Dựa trên những gì chúng ta đã học được trong kịch bản “Thả xuống chìm”, chúng ta không thể di chuyển menu thả xuống ra khỏi thanh điều hướng; nó sẽ không có ý nghĩa. Tuy nhiên, chúng ta có thể tăng giá trị z-index của vùng chứa .navbar lớn hơn giá trị z-index của phần tử .content. .navbar { nền: #333; /* chỉ mục z: 1; */ chỉ số z: 3; vị trí: tương đối; }

Với thay đổi này, menu .dropdown hiện xuất hiện phía trước nội dung mà không gặp vấn đề gì. Xem Kịch bản Bút 2: Thả xuống chìm (Giải pháp) [phân nhánh] của Shoyombo Gabriel Ayomide. Hãy thử Cổng thông tin nếu sử dụng Khung Trong các khung như React hoặc Vue, Cổng thông tin là một tính năng cho phép bạn hiển thị một thành phần bên ngoài hệ thống phân cấp cha thông thường của nó trong DOM. Cổng giống như một thiết bị dịch chuyển tức thời cho các thành phần của bạn. Chúng cho phép bạn hiển thị HTML của một thành phần ở bất kỳ đâu trong tài liệu (thường là ngay trong document.body) trong khi vẫn giữ nó được kết nối hợp lý với thành phần gốc ban đầu cho các đạo cụ, trạng thái và sự kiện. Điều này là hoàn hảo để thoát khỏi bẫy bối cảnh xếp chồng vì đầu ra được hiển thị thực sự xuất hiện bên ngoài vùng chứa chính có vấn đề. ReactDOM.createPortal( , tài liệu.body );

Điều này đảm bảo nội dung thả xuống của bạn không bị ẩn đằng sau nội dung gốc, ngay cả khi nội dung gốc có tràn: ẩn hoặc chỉ mục z thấp hơn. Trong kịch bản “Chú giải công cụ đã cắt” mà chúng ta đã xem xét trước đó, tôi đã sử dụng Cổng thông tin để giải cứu chú giải công cụ khỏi clip tràn: ẩn bằng cách đặt nó vào nội dung tài liệu và đặt nó phía trên trình kích hoạt trong vùng chứa. Xem Kịch bản Bút 3: Chú giải công cụ được cắt bớt (Giải pháp) [phân nhánh] của Shoyombo Gabriel Ayomide. Giới thiệu bối cảnh xếp chồng không có tác dụng phụ Tất cả các cách tiếp cận được giải thích trong phần trước đều nhằm mục đích "dỡ bỏ" các phần tử khỏi bối cảnh xếp chồng có vấn đề, nhưng có một số tình huống mà bạn thực sự cần hoặc muốn tạo bối cảnh xếp chồng. Tạo một bối cảnh xếp chồng mới thật dễ dàng, nhưng tất cả các phương pháp tiếp cận đều có tác dụng phụ. Tức là, ngoại trừ việc sử dụng cách ly: cách ly. Khi áp dụng cho một phần tử, bối cảnh xếp chồng của các phần tử con của phần tử đó được xác định tương ứng với từng phần tử con và trong bối cảnh đó, thay vì bị ảnh hưởng bởi các phần tử bên ngoài nó. Một ví dụ cổ điển là gán cho phần tử đó một giá trị âm, chẳng hạn như z-index: -1. Hãy tưởng tượng bạn có một thành phần .card. Bạn muốn thêm hình trang trí nằm phía sau văn bản của .card nhưng ở trên nền của thẻ. Nếu không có bối cảnh xếp chồng trên thẻ, z-index: -1 sẽ gửi hình dạng xuống cuối bối cảnh xếp chồng gốc (toàn bộ trang). Điều này làm cho nó biến mất sau nền trắng của .card: Xem chỉ số z âm (vấn đề) [phân nhánh] của Shoyombo Gabriel Ayomide. Để giải quyết vấn đề này, chúng ta khai báo cô lập: cô lập trên thẻ .card gốc: Xem Pen Negative z-index (giải pháp) [phân nhánh] của Shoyombo Gabriel Ayomide. Bây giờ, bản thân phần tử .card sẽ trở thành bối cảnh xếp chồng. Khi phần tử con của nó — hình dạng trang trí được tạo trên phần tử giả :trước — có chỉ mục z: -1, nó sẽ đi xuống cuối cùng của bối cảnh xếp chồng của phần tử gốc. Nó nằm hoàn hảo phía sau văn bản và trên nền của thẻ, như dự định. Kết luận Hãy nhớ rằng: lần tiếp theo chỉ mục z của bạn có vẻ ngoài tầm kiểm soát, đó là bối cảnh xếp chồng bị mắc kẹt. Tài liệu tham khảo

Bối cảnh xếp chồng (MDN) Chỉ mục Z và bối cảnh xếp chồng (web.dev) “Cách tạo bối cảnh xếp chồng mới với thuộc tính cách ly trong CSS”, Natalie Pina “Cái quái gì vậy, z-index??”, Josh Comeau

Đọc thêm về SmashingMag

“Quản lý CSS Z-Index trong các dự án lớn”, Steven Frieson “Tiêu đề dính và các phần tử có chiều cao đầy đủ: Một sự kết hợp khó khăn”, Philip Braunen “Quản lý chỉ mục Z trong ứng dụng web dựa trên thành phần”, Pavel Pomerantsev “Thuộc tính CSS Z-Index: Một cái nhìn toàn diện”, Louis Lazaris

You May Also Like

Enjoyed This Article?

Get weekly tips on growing your audience and monetizing your content — straight to your inbox.

No spam. Join 138,000+ creators. Unsubscribe anytime.

Create Your Free Bio Page

Join 138,000+ creators on Seemless.

Get Started Free