คุณเคยตั้งค่า z-index: 99999 ให้กับองค์ประกอบใน CSS ของคุณหรือไม่ และองค์ประกอบนั้นจะไม่ปรากฏทับองค์ประกอบอื่น ๆ หรือไม่? ค่าที่มีขนาดใหญ่ควรวางองค์ประกอบนั้นไว้ด้านบนสิ่งอื่นใดอย่างมองเห็นได้โดยง่าย โดยถือว่าองค์ประกอบต่างๆ ทั้งหมดตั้งค่าไว้ที่ค่าที่ต่ำกว่าหรือไม่ได้ตั้งค่าเลย หน้าเว็บมักจะแสดงในพื้นที่สองมิติ อย่างไรก็ตาม ด้วยการใช้คุณสมบัติ CSS ที่เฉพาะเจาะจง ระนาบแกน z ในจินตนาการจึงถูกนำมาใช้เพื่อถ่ายทอดความลึก ระนาบนี้ตั้งฉากกับหน้าจอ จากนั้นผู้ใช้จะรับรู้ลำดับขององค์ประกอบ โดยองค์ประกอบหนึ่งอยู่ด้านบนของอีกองค์ประกอบหนึ่ง แนวคิดเบื้องหลังแกน z ในจินตภาพ ซึ่งเป็นการรับรู้ของผู้ใช้เกี่ยวกับองค์ประกอบแบบเรียงซ้อนก็คือคุณสมบัติ CSS ที่สร้างมันขึ้นมารวมกันเพื่อสร้างสิ่งที่เราเรียกว่าบริบทแบบเรียงซ้อน เราจะพูดถึงวิธีการ "เรียงซ้อน" องค์ประกอบบนหน้าเว็บ สิ่งที่ควบคุมลำดับการเรียงซ้อน และแนวทางปฏิบัติในการ "แยกซ้อน" องค์ประกอบเมื่อจำเป็น เกี่ยวกับการซ้อนบริบท ลองนึกภาพหน้าเว็บของคุณเป็นโต๊ะ เมื่อคุณเพิ่มองค์ประกอบ HTML คุณกำลังวางกระดาษทีละแผ่นบนโต๊ะ กระดาษชิ้นสุดท้ายที่วางจะเทียบเท่ากับองค์ประกอบ HTML ที่เพิ่มล่าสุด และจะอยู่ด้านบนของเอกสารอื่นๆ ทั้งหมดที่วางไว้ก่อนหน้านั้น นี่คือการไหลของเอกสารปกติ แม้แต่กับองค์ประกอบที่ซ้อนกันก็ตาม ตัวเดสก์เองแสดงถึงบริบทการสแต็ครูท ซึ่งสร้างขึ้นโดยองค์ประกอบ ซึ่งมีโฟลเดอร์อื่นๆ ทั้งหมด ตอนนี้คุณสมบัติ CSS เฉพาะเข้ามามีบทบาทแล้ว คุณสมบัติเช่นตำแหน่ง (ที่มีดัชนี z) ความทึบ แปลง และมี) ทำหน้าที่เหมือนกับโฟลเดอร์ โฟลเดอร์นี้รับองค์ประกอบและลูกทั้งหมด แยกออกจากสแต็กหลัก และจัดกลุ่มให้เป็นสแต็กย่อยที่แยกจากกัน สร้างสิ่งที่เราเรียกว่าบริบทการสแต็ก สำหรับองค์ประกอบที่มีตำแหน่ง สิ่งนี้จะเกิดขึ้นเมื่อเราประกาศค่าดัชนี z อื่นที่ไม่ใช่อัตโนมัติ สำหรับคุณสมบัติ เช่น ความทึบ การแปลง และตัวกรอง บริบทการซ้อนจะถูกสร้างขึ้นโดยอัตโนมัติเมื่อมีการใช้ค่าเฉพาะ

พยายามทำความเข้าใจสิ่งนี้: เมื่อกระดาษแผ่นหนึ่ง (เช่น องค์ประกอบลูก) อยู่ในโฟลเดอร์ (เช่น บริบทการซ้อนของพาเรนต์) กระดาษนั้นจะไม่สามารถออกจากโฟลเดอร์นั้นหรือวางไว้ระหว่างกระดาษในโฟลเดอร์อื่นได้ ขณะนี้ดัชนี z มีความเกี่ยวข้องเฉพาะภายในโฟลเดอร์ของตัวเองเท่านั้น

ในภาพประกอบด้านล่าง ตอนนี้ Paper B อยู่ในบริบทการเรียงซ้อนของโฟลเดอร์ B และสามารถสั่งซื้อได้กับกระดาษอื่นๆ ในโฟลเดอร์เท่านั้น

ลองจินตนาการว่าคุณมีสองโฟลเดอร์บนโต๊ะ:

โฟลเดอร์ ก
โฟลเดอร์ B

.folder-a { ดัชนี z: 1; } .folder-b { ดัชนี z: 2; }

มาอัพเดตมาร์กอัปกันสักหน่อย Inside Folder A เป็นหน้าพิเศษ ดัชนี z: 9999 ภายในโฟลเดอร์ B เป็นหน้าธรรมดา ดัชนี z: 5

หน้าพิเศษ

หน้าธรรมดา

.หน้าพิเศษ { ดัชนี z: 9999; } .plain-page { ดัชนี z: 5; }

หน้าไหนอยู่ด้านบน? มันคือ .plain-page ในโฟลเดอร์ B เบราว์เซอร์จะละเว้นเอกสารย่อยและซ้อนทั้งสองโฟลเดอร์ก่อน เห็นโฟลเดอร์ B (z-index: 2) และวางไว้บนโฟลเดอร์ A (z-index: 1) เพราะเรารู้ว่าสองมีค่ามากกว่าหนึ่ง ในขณะเดียวกัน หน้า .special-page ตั้งค่าเป็น z-index: 9999 จะอยู่ที่ด้านล่างของสแต็ก แม้ว่าดัชนี z จะถูกตั้งค่าเป็นค่าสูงสุดที่เป็นไปได้ก็ตาม บริบทการซ้อนสามารถซ้อนกันได้ (โฟลเดอร์ภายในโฟลเดอร์) สร้าง "แผนผังครอบครัว" ใช้หลักการเดียวกันนี้: เด็กไม่สามารถหลบหนีจากโฟลเดอร์ของผู้ปกครองได้ ตอนนี้คุณคงเข้าใจแล้วว่าบริบทการสแต็กทำงานเหมือนกับโฟลเดอร์ที่จัดกลุ่มและเรียงลำดับเลเยอร์ใหม่อย่างไร ก็คุ้มค่าที่จะถามว่าทำไมคุณสมบัติบางอย่าง เช่น การแปลงและความทึบ จึงสร้างบริบทการสแต็กใหม่ สิ่งสำคัญคือ: คุณสมบัติเหล่านี้ไม่ได้สร้างบริบทแบบซ้อนเนื่องจากลักษณะที่ปรากฏ พวกเขาทำมันเพราะวิธีการทำงานของเบราว์เซอร์ภายใต้ประทุน เมื่อคุณใช้การแปลง ความทึบ ฟิลเตอร์ หรือเปอร์สเปคทีฟ คุณกำลังบอกเบราว์เซอร์ว่า “เฮ้ องค์ประกอบนี้อาจเคลื่อนไหว หมุน หรือจางหายไป ดังนั้นเตรียมตัวให้พร้อม!”

เมื่อคุณใช้คุณสมบัติเหล่านี้ เบราว์เซอร์จะสร้างบริบทการเรียงซ้อนใหม่เพื่อจัดการการเรนเดอร์ได้อย่างมีประสิทธิภาพมากขึ้น ซึ่งช่วยให้เบราว์เซอร์จัดการภาพเคลื่อนไหว การแปลง และเอฟเฟ็กต์ภาพได้อย่างอิสระ ช่วยลดความจำเป็นในการคำนวณใหม่ว่าองค์ประกอบเหล่านี้โต้ตอบกับส่วนที่เหลือของหน้าอย่างไร ลองนึกถึงเบราว์เซอร์ที่พูดว่า "ฉันจะจัดการโฟลเดอร์นี้แยกกัน ดังนั้นฉันจึงไม่ต้องสับเปลี่ยนทั้งโต๊ะทุกครั้งที่มีบางอย่างในนั้นเปลี่ยนแปลง" แต่มีผลข้างเคียง เมื่อเบราว์เซอร์ยกองค์ประกอบลงในเลเยอร์ของตัวเอง องค์ประกอบนั้นจะต้อง "ทำให้เรียบ" ทุกสิ่งภายในองค์ประกอบนั้น สร้างบริบทการซ้อนใหม่ เหมือนกับการนำแฟ้มออกจากโต๊ะเพื่อจัดการแยกกัน ทุกอย่างภายในโฟลเดอร์นั้นจะถูกจัดกลุ่ม และตอนนี้เบราว์เซอร์จะถือว่ามันเป็นหน่วยเดียวเมื่อตัดสินใจว่าอะไรจะอยู่ด้านบนของอะไร ดังนั้นแม้ว่าคุณสมบัติการแปลงและความทึบอาจไม่ส่งผลต่อวิธีที่องค์ประกอบต่างๆ เรียงกันเป็นภาพ แต่ก็เป็นเช่นนั้น และเป็นการเพิ่มประสิทธิภาพการทำงาน คุณสมบัติ CSS อื่นๆ อีกหลายรายการสามารถสร้างบริบทแบบซ้อนได้ด้วยเหตุผลที่คล้ายกัน MDN จัดเตรียมรายการทั้งหมดไว้หากคุณต้องการเจาะลึกยิ่งขึ้น มีค่อนข้างน้อย ซึ่งแสดงให้เห็นว่าการสร้างบริบทแบบซ้อนโดยไม่ตั้งใจนั้นง่ายเพียงใดโดยที่ไม่รู้ตัว ปัญหา "การไม่วางซ้อน" ปัญหาการซ้อนสามารถเกิดขึ้นได้จากหลายสาเหตุ แต่บางสาเหตุก็พบบ่อยกว่าสาเหตุอื่นๆ ส่วนประกอบ Modal เป็นรูปแบบคลาสสิกเนื่องจากจำเป็นต้องสลับส่วนประกอบเป็น “เปิด” บนเลเยอร์ด้านบนเหนือองค์ประกอบอื่นๆ ทั้งหมด จากนั้นจึงลบออกจากชั้นบนสุดเมื่อ “ปิด” ฉันค่อนข้างมั่นใจว่าเราทุกคนต้องเผชิญกับสถานการณ์ที่เราเปิดโมดอลและไม่ปรากฏขึ้นไม่ว่าด้วยเหตุผลใดก็ตาม ไม่ใช่ว่าเปิดไม่ถูกต้อง แต่จะไม่อยู่ในสายตาในชั้นล่างของบริบทการซ้อน สิ่งนี้ทำให้คุณสงสัยว่า “ทำไม?” ตั้งแต่คุณตั้งค่า:

.ซ้อนทับ { ตำแหน่ง: คงที่; /* สร้างบริบทการซ้อน */ ดัชนี z: 1; /* วางองค์ประกอบไว้บนเลเยอร์เหนือสิ่งอื่นใด */ สิ่งที่ใส่เข้าไป: 0; ความกว้าง: 100%; ความสูง: 100vh; ล้น: ซ่อนเร้น; สีพื้นหลัง: #00000080; }

สิ่งนี้ดูถูกต้อง แต่ถ้าองค์ประกอบหลักที่มีทริกเกอร์โมดอลเป็นองค์ประกอบลูกภายในองค์ประกอบหลักอื่นที่ตั้งค่าเป็น z-index: 1 ด้วย ซึ่งในทางเทคนิคจะวางโมดอลในเลเยอร์ย่อยที่ถูกบดบังโดยโฟลเดอร์หลัก มาดูสถานการณ์เฉพาะนั้นและข้อผิดพลาดทั่วไปอื่นๆ บางประการในการซ้อนบริบท ฉันคิดว่าคุณจะเห็นไม่เพียงแต่ความง่ายในการสร้างบริบทแบบซ้อนโดยไม่ตั้งใจเท่านั้น แต่ยังรวมถึงวิธีจัดการบริบทที่ไม่ถูกต้องอีกด้วย นอกจากนี้ วิธีที่คุณกลับสู่สถานะที่ได้รับการจัดการนั้นขึ้นอยู่กับสถานการณ์ สถานการณ์ที่ 1: Modal ที่ติดอยู่

คุณสามารถเห็นโมดอลของคุณติดอยู่ในเลเยอร์ระดับต่ำได้ทันทีและระบุพาเรนต์ได้ ส่วนขยายเบราว์เซอร์ นักพัฒนาที่ชาญฉลาดได้สร้างส่วนขยายเพื่อช่วย เครื่องมือเช่นส่วนขยาย Chrome “CSS Stacking Context Inspector” จะเพิ่มแท็บ z-index พิเศษให้กับ DevTools ของคุณเพื่อแสดงข้อมูลเกี่ยวกับองค์ประกอบที่สร้างบริบทแบบซ้อน

ส่วนขยาย IDE คุณยังสามารถมองเห็นปัญหาในระหว่างการพัฒนาด้วยส่วนขยายเช่นนี้สำหรับ VS Code ซึ่งเน้นปัญหาบริบทการซ้อนที่อาจเกิดขึ้นได้โดยตรงในตัวแก้ไขของคุณ

การแยกซ้อนและการควบคุมกลับคืนมา หลังจากที่เราระบุสาเหตุที่แท้จริงแล้ว ขั้นตอนต่อไปคือการจัดการกับมัน มีหลายวิธีที่คุณสามารถใช้เพื่อแก้ไขปัญหานี้ และฉันจะแสดงรายการตามลำดับ คุณสามารถเลือกใครก็ได้ในระดับใดก็ได้ ไม่มีใครสามารถบ่นหรือขัดขวางผู้อื่นได้ เปลี่ยนโครงสร้าง HTML นี่ถือเป็นการแก้ไขที่เหมาะสมที่สุด เพื่อให้คุณประสบปัญหาการซ้อนบริบท คุณต้องวางองค์ประกอบบางอย่างในตำแหน่งที่ตลกภายใน HTML ของคุณ การปรับโครงสร้างเพจใหม่จะช่วยให้คุณปรับรูปร่าง DOM ใหม่และขจัดปัญหาบริบทการซ้อน ค้นหาองค์ประกอบที่มีปัญหาและลบออกจากองค์ประกอบที่ดักจับในมาร์กอัป HTML ตัวอย่างเช่น เราสามารถแก้ไขสถานการณ์แรก “The Trapped Modal” ได้โดยการย้าย .modal-container ออกจากส่วนหัวและวางไว้ในองค์ประกอบ ด้วยตัวเอง

<ชั้นส่วนหัว = "ส่วนหัว">

ส่วนหัว

<คลาสหลัก = "เนื้อหา">

เนื้อหาหลัก

เนื้อหานี้มีดัชนี z เป็น 2 และจะยังคงไม่ครอบคลุมโมดอล

เมื่อคุณคลิกปุ่ม "เปิด Modal" Modal จะอยู่ด้านหน้าสิ่งอื่นตามที่ควรจะเป็น ดูสถานการณ์ปากกาที่ 1: The Trapped Modal (โซลูชัน) [แยกออก] โดย Shoyombo Gabriel Ayomide ปรับบริบทการซ้อนผู้ปกครองใน CSS จะเกิดอะไรขึ้นถ้าองค์ประกอบนั้นเป็นองค์ประกอบที่คุณไม่สามารถเคลื่อนย้ายได้โดยไม่ทำลายเลย์เอาต์? ดีกว่าที่จะแก้ไขปัญหา: ผู้ปกครองเป็นผู้กำหนดบริบท ค้นหาคุณสมบัติ CSS (หรือคุณสมบัติ) ที่รับผิดชอบในการทริกเกอร์บริบทและลบออก หากมีวัตถุประสงค์และไม่สามารถลบออกได้ ให้ตั้งค่าดัชนี z ให้ผู้ปกครองสูงกว่าองค์ประกอบพี่น้องเพื่อยกคอนเทนเนอร์ทั้งหมด ด้วยค่าดัชนี z ที่สูงกว่า คอนเทนเนอร์หลักจะย้ายไปด้านบน และคอนเทนเนอร์ย่อยจะปรากฏใกล้กับผู้ใช้มากขึ้น จากสิ่งที่เราเรียนรู้ในสถานการณ์ "The Submerged Dropdown" เราไม่สามารถย้ายเมนูแบบเลื่อนลงออกจากแถบนำทางได้ มันคงไม่สมเหตุสมผล อย่างไรก็ตาม เราสามารถเพิ่มค่า z-index ของคอนเทนเนอร์ .navbar ให้มากกว่าค่า z-index ขององค์ประกอบ .content ได้ .navbar { พื้นหลัง: #333; /* ดัชนี z: 1; */ ดัชนี z: 3; ตำแหน่ง: ญาติ; }

ด้วยการเปลี่ยนแปลงนี้ เมนู .dropdown จะปรากฏด้านหน้าเนื้อหาโดยไม่มีปัญหาใดๆ ดูสถานการณ์ปากกาที่ 2: ดรอปดาวน์ที่จมอยู่ใต้น้ำ (โซลูชัน) [แยกออก] โดย Shoyombo Gabriel Ayomide ลองใช้พอร์ทัลหากใช้กรอบงาน ในเฟรมเวิร์ก เช่น React หรือ Vue พอร์ทัลเป็นคุณสมบัติที่ช่วยให้คุณเรนเดอร์ส่วนประกอบนอกลำดับชั้นพาเรนต์ปกติใน DOM พอร์ทัลเปรียบเสมือนอุปกรณ์เคลื่อนย้ายมวลสารสำหรับส่วนประกอบของคุณ ช่วยให้คุณสามารถเรนเดอร์ HTML ของคอมโพเนนต์ได้ทุกที่ในเอกสาร (โดยทั่วไปจะอยู่ใน document.body) ในขณะเดียวกันก็รักษาการเชื่อมต่อทางตรรกะกับพาเรนต์ดั้งเดิมสำหรับอุปกรณ์ประกอบฉาก สถานะ และเหตุการณ์ต่างๆ วิธีนี้เหมาะอย่างยิ่งสำหรับการหลบหนีกับดักบริบทแบบซ้อน เนื่องจากเอาต์พุตที่แสดงผลจะปรากฏภายนอกคอนเทนเนอร์พาเรนต์ที่มีปัญหาอย่างแท้จริง ReactDOM.createPortal( <คำแนะนำเครื่องมือ />, เอกสาร.ร่างกาย );

วิธีนี้ช่วยให้แน่ใจว่าเนื้อหาแบบเลื่อนลงของคุณไม่ได้ซ่อนอยู่หลังรายการหลัก แม้ว่ารายการหลักจะมีโอเวอร์โฟลว์: ซ่อนอยู่หรือดัชนี z ต่ำกว่าก็ตาม ในสถานการณ์ “เคล็ดลับเครื่องมือที่ถูกตัด” ที่เราดูไปก่อนหน้านี้ ฉันใช้พอร์ทัลเพื่อช่วยเหลือคำแนะนำเครื่องมือจากโอเวอร์โฟลว์: คลิปที่ซ่อนอยู่โดยการวางมันไว้ในเนื้อหาของเอกสารและวางตำแหน่งไว้เหนือทริกเกอร์ภายในคอนเทนเนอร์ ดูสถานการณ์ปากกา 3: เคล็ดลับเครื่องมือที่ถูกตัด (โซลูชัน) [แยกออก] โดย Shoyombo Gabriel Ayomide ขอแนะนำบริบทการซ้อนโดยไม่มีผลข้างเคียง วิธีการทั้งหมดที่อธิบายไว้ในส่วนก่อนหน้านี้มุ่งเป้าไปที่องค์ประกอบ "การแยกซ้อน" จากบริบทการซ้อนที่เป็นปัญหา แต่มีบางสถานการณ์ที่คุณต้องการหรือต้องการสร้างบริบทการซ้อนจริงๆ การสร้างบริบทการซ้อนใหม่นั้นเป็นเรื่องง่าย แต่วิธีการทั้งหมดมาพร้อมกับผลข้างเคียง นั่นคือ ยกเว้นการใช้การแยก: แยก เมื่อนำไปใช้กับองค์ประกอบ บริบทการซ้อนของลูกขององค์ประกอบนั้นจะถูกกำหนดโดยสัมพันธ์กับลูกแต่ละคนและภายในบริบทนั้น แทนที่จะได้รับอิทธิพลจากองค์ประกอบภายนอก ตัวอย่างคลาสสิกคือการกำหนดค่าลบให้กับองค์ประกอบนั้น เช่น ดัชนี z: -1 ลองนึกภาพคุณมีส่วนประกอบ .card คุณต้องการเพิ่มรูปทรงตกแต่งที่อยู่ด้านหลังข้อความของ .card แต่อยู่ด้านบนของพื้นหลังของการ์ด หากไม่มีบริบทการเรียงซ้อนบนการ์ด ดัชนี z: -1 จะส่งรูปร่างไปที่ด้านล่างของบริบทการซ้อนราก (ทั้งหน้า) สิ่งนี้ทำให้หายไปหลังพื้นหลังสีขาวของ .card: ดูดัชนี z ที่เป็นลบของปากกา (ปัญหา) [แยกออก] โดย Shoyombo Gabriel Ayomide เพื่อแก้ไขปัญหานี้ เราประกาศการแยก: แยกบนพาเรนต์ .card: ดูดัชนี z ที่เป็นลบของปากกา (สารละลาย) [แยกออก] โดย Shoyombo Gabriel Ayomide ตอนนี้ องค์ประกอบ .card เองกลายเป็นบริบทแบบเรียงซ้อน เมื่อองค์ประกอบลูก — รูปร่างตกแต่งที่สร้างขึ้นบน :ก่อนองค์ประกอบหลอก — มีดัชนี z: -1 องค์ประกอบจะไปที่ด้านล่างสุดของบริบทการซ้อนของพาเรนต์ โดยจะอยู่ด้านหลังข้อความและด้านบนของพื้นหลังของการ์ดอย่างสมบูรณ์แบบตามที่ตั้งใจไว้ บทสรุป ข้อควรจำ: ครั้งต่อไปที่ดัชนี z ของคุณดูเหมือนควบคุมไม่ได้ ก็จะเกิดบริบทการซ้อนที่ติดอยู่ อ้างอิง

บริบทการซ้อน (MDN) ดัชนี Z และบริบทการซ้อน (web.dev) “วิธีสร้างบริบทการซ้อนใหม่ด้วยคุณสมบัติการแยกใน CSS”, Natalie Pina “อะไรคือ Heck, z-index?”, Josh Comeau

อ่านเพิ่มเติมเกี่ยวกับ SmashingMag

“การจัดการ CSS Z-Index ในโครงการขนาดใหญ่”, Steven Frieson “ส่วนหัวที่เหนียวและองค์ประกอบที่มีความสูงเต็ม: การผสมผสานที่ยุ่งยาก”, Philip Braunen “การจัดการดัชนี Z ในเว็บแอปพลิเคชันแบบอิงคอมโพเนนต์”, Pavel Pomerantsev “คุณสมบัติ CSS Z-Index: รูปลักษณ์ที่ครอบคลุม”, 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