ดัชนี z คืออะไร? ดัชนี Z เป็นคุณสมบัติ CSS ที่ให้คุณวางตำแหน่งองค์ประกอบ HTML ในเลเยอร์ที่ทับซ้อนกัน ดูเหมือนง่ายในตอนแรก แต่เรียบง่ายอย่างหลอกลวง
มีกฎแปลก ๆ ที่ไม่เป็นธรรมชาติบางอย่างที่ทำให้ไม่เป็นไปตามที่ต้องการ แม้ว่าคุณจะตั้งค่าดัชนี z เป็น 999999!
บทความนี้จะอธิบายโดยละเอียดเกี่ยวกับสาเหตุที่พบบ่อยที่สุดสี่ประการที่ดัชนี z ใช้งานไม่ได้สำหรับคุณ คุณจะได้เรียนรู้วิธีใช้ CSS เพื่อนำองค์ประกอบมาไว้ด้านหน้าหรือด้านหลังองค์ประกอบอื่นๆ
1. องค์ประกอบในบริบทการเรียงซ้อนเดียวกันจะแสดงตามลำดับลักษณะที่ปรากฏ โดยมีองค์ประกอบหลังอยู่ด้านบนขององค์ประกอบเดิม
ในตัวอย่างแรกของเรา เรามีเลย์เอาต์ที่ค่อนข้างเรียบง่ายซึ่งประกอบด้วยองค์ประกอบหลัก 3 อย่าง:
- รูปแมว
- บล็อกสีขาวพร้อมข้อความ
- อีกรูปแมวตัวเดียวกัน
นี่คือมาร์กอัป HTML สำหรับสิ่งนั้น:
<div class="cat-top"></div>
<div class="content__block">
Meow meow meow...
</div>
<div class="cat-bottom"></div>
ในเลย์เอาต์นี้ เราต้องการให้บล็อกข้อความสีขาวอยู่ด้านบนของแมวทั้งสองตัว
ในการพยายามบรรลุเป้าหมาย เราได้เพิ่มระยะขอบเชิงลบบางส่วนให้กับ CSS สำหรับรูปภาพแมวทั้งสอง เพื่อให้ซ้อนทับบล็อกสีขาวเล็กน้อย:
.cat-top {
margin-bottom: -110px;
}
.cat-bottom {
float: right;
margin-top: -120px;
}
อย่างไรก็ตาม ดูเหมือนว่า:
ดู Pen Z-index:#1:set position, #2:natural stacking order, #3:CSS properties by Jessica (@thecodercoder) on CodePen.
แมวตัวแรกถูกวางไว้ใต้บล็อกเนื้อหาสีขาว อย่างที่เราต้องการ แต่รูปแมวตัวที่สองวางอยู่บนบล็อก!
ทำไมสิ่งนี้จึงเกิดขึ้น
สาเหตุของพฤติกรรมนี้เกิดจากลำดับการเรียงซ้อนตามธรรมชาติ บนหน้าเว็บ โดยพื้นฐานแล้วหลักเกณฑ์เหล่านี้จะกำหนดองค์ประกอบที่จะอยู่ด้านบนและด้านล่าง
แม้ว่าองค์ประกอบจะไม่ได้ตั้งค่าดัชนี z แต่ก็มีเหตุผลและเหตุผลที่องค์ประกอบจะอยู่ด้านบน
ในกรณีของเรา ไม่มีองค์ประกอบใดที่มีค่าดัชนี z ดังนั้นลำดับการเรียงซ้อนจึงถูกกำหนดโดยลำดับของรูปลักษณ์ ตามกฎนี้ องค์ประกอบที่มาภายหลังในมาร์กอัปจะอยู่ด้านบนขององค์ประกอบที่อยู่ข้างหน้า
(คุณสามารถอ่านหลักเกณฑ์การเรียงซ้อนเพิ่มเติมได้ที่ Mozilla Developer Network ที่นี่)
ในตัวอย่างของเรากับแมวและกลุ่มสีขาว พวกเขาปฏิบัติตามกฎนี้ นั่นเป็นสาเหตุที่แมวตัวแรกอยู่ใต้องค์ประกอบบล็อกสีขาว และบล็อกสีขาวอยู่ใต้แมวตัวที่สอง
โอเค การจัดลำดับทำได้ดีและดี แต่เราจะแก้ไข CSS เพื่อให้แมวตัวที่สองอยู่ใต้บล็อกสีขาวได้อย่างไร
มาดูเหตุผลที่สอง:
2. องค์ประกอบไม่ได้กำหนดตำแหน่งไว้
แนวทางอื่นๆ ที่กำหนดลำดับการเรียงซ้อนคือองค์ประกอบมีตำแหน่งที่กำหนดไว้หรือไม่
ในการกำหนดตำแหน่งขององค์ประกอบ ให้เพิ่ม CSS position
คุณสมบัติเป็นอย่างอื่นที่ไม่ใช่ static
เช่น relative
หรือ absolute
. (คุณสามารถอ่านเพิ่มเติมเกี่ยวกับเรื่องนี้ในบทความนี้ที่ฉันเขียน)
ตามกฎนี้ องค์ประกอบที่วางตำแหน่งจะแสดงบนองค์ประกอบที่ไม่มีตำแหน่ง
ดังนั้นการตั้งค่าบล็อกสีขาวเป็น position: relative
และการปล่อยให้องค์ประกอบแมวทั้งสองไม่มีตำแหน่งจะทำให้บล็อกสีขาวอยู่ด้านบนของแมวในลำดับการซ้อน
นี่คือลักษณะที่ปรากฏ – คุณสามารถเล่นกับ Codepen ด้านบนได้
วู้ฮู้!
สิ่งต่อไปที่เราต้องการจะทำคือหมุนแมวตัวล่างกลับหัวโดยใช้ transform
คุณสมบัติ. ด้วยวิธีนี้ แมวทั้งสองจะอยู่ใต้บล็อกสีขาว โดยมีเพียงหัวที่ยื่นออกมา
แต่การทำเช่นนี้อาจทำให้ z-index
- ความสับสนที่เกี่ยวข้อง เราจะแก้ไขปัญหาและแนวทางแก้ไขในตอนต่อไป
3. การตั้งค่าคุณสมบัติ CSS บางอย่าง เช่น ความทึบหรือการแปลงจะทำให้องค์ประกอบอยู่ในบริบทการสแต็กใหม่
ดังที่เราได้กล่าวไปแล้ว เราต้องการพลิกแมวตัวล่างกลับด้าน เพื่อให้บรรลุสิ่งนี้ เราจะเพิ่ม transform: rotate(180deg)
.
.cat-bottom {
float: right;
margin-top: -120px;
transform: rotate(180deg);
}
แต่สิ่งนี้ทำให้แมวตัวล่างปรากฏขึ้นบนบล็อกสีขาวอีกครั้ง!
นี่มันเกิดอะไรขึ้น
คุณอาจพบปัญหานี้ไม่บ่อยนัก แต่อีกแง่มุมหนึ่งของลำดับการเรียงซ้อนคือคุณสมบัติ CSS บางอย่างเช่น transform
หรือ opacity
จะใส่องค์ประกอบลงในบริบทการเรียงซ้อนแบบใหม่
ความหมายก็คือการเพิ่ม transform
ไปที่ .cat-bottom
องค์ประกอบทำให้มันทำงานราวกับว่ามี z-index
จาก 0 แม้ว่าจะไม่มี position
หรือ z-index
ตั้งเลย! (W3.org มีเอกสารที่ให้ข้อมูลแต่ค่อนข้างแน่นหนาเกี่ยวกับวิธีการทำงานกับ opacity
ทรัพย์สิน)
จำไว้ว่าเราไม่เคยเพิ่ม z-index
ค่าให้กับบล็อกสีขาวเท่านั้น position: relative
. เท่านี้ก็เพียงพอแล้วที่จะวางบล็อกสีขาวไว้บนแมวที่ไม่มีตำแหน่ง
แต่เนื่องจาก .bottom-cat
องค์ประกอบทำหน้าที่ราวกับว่ามันอยู่ในตำแหน่งที่ค่อนข้างมี z-index: 0
, แปลงร่างได้วางตำแหน่งไว้บนบล็อกสีขาว
วิธีแก้ไขคือตั้งค่า position: relative
และกำหนด z-index
. อย่างชัดเจน บนบล็อกสีขาวอย่างน้อย คุณสามารถไปอีกขั้นหนึ่งและตั้งค่า position: relative
และ z-index
. ที่ต่ำกว่า ในส่วนของแมวเพื่อความปลอดภัยเป็นพิเศษ
.content__block {
position: relative;
z-index: 2;
}
.cat-top, .cat-bottom {
position: relative;
z-index: 1;
}
ในความเห็นของฉัน การทำเช่นนี้จะช่วยแก้ปัญหาส่วนใหญ่ ถ้าไม่ใช่ปัญหาดัชนี z พื้นฐานทั้งหมด
ตอนนี้ มาดูเหตุผลสุดท้ายของเราที่ z-index
. ของคุณ ไม่ทำงาน อันนี้ซับซ้อนกว่าเล็กน้อย เพราะมันเกี่ยวข้องกับองค์ประกอบหลักและลูก
4. องค์ประกอบอยู่ในบริบทการสแต็กที่ต่ำกว่าเนื่องจากระดับดัชนี z ของพาเรนต์
ลองดูตัวอย่างโค้ดของเราสำหรับสิ่งนี้:
ดูดัชนี Z ของปากกา:#4 บริบทการสแต็กที่แตกต่างกันโดยเจสสิก้า (@thecodercoder) บน CodePen
นี่คือสิ่งที่เรามี:หน้าเว็บง่ายๆ ที่มีเนื้อหาปกติ และแท็บด้านข้างสีชมพูที่ระบุว่า "ส่งความคิดเห็น" ซึ่งวางไว้ที่ด้านบนของเนื้อหา
จากนั้น เมื่อคุณคลิกที่รูปแมว หน้าต่างโมดอลที่มีพื้นหลังสีเทาโปร่งใสจะเปิดขึ้น
อย่างไรก็ตาม แม้ในขณะที่หน้าต่างโมดอลเปิดอยู่ แท็บด้านข้างก็ยังอยู่ด้านบนของโอเวอร์เลย์สีเทา เราต้องการให้แสดงโอเวอร์เลย์เหนือทุกสิ่ง รวมถึงแท็บด้านข้างด้วย
มาดู CSS สำหรับองค์ประกอบที่เป็นปัญหากัน:
.content {
position: relative;
z-index: 1;
}
.modal {
position: fixed;
z-index: 100;
}
.side-tab {
position: fixed;
z-index: 5;
}
องค์ประกอบทั้งหมดมีการกำหนดตำแหน่ง และแท็บด้านข้างมี z-index
จาก 5 ซึ่งวางตำแหน่งไว้ด้านบนขององค์ประกอบเนื้อหา ซึ่งอยู่ที่ z-index: 1
.
จากนั้น modal จะมี z-index: 100
ซึ่ง ควร วางไว้บนแถบด้านข้างที่ z-index: 5
. แต่การซ้อนทับแบบโมดอลจะอยู่ใต้แท็บด้านข้างแทน
ทำไมสิ่งนี้จึงเกิดขึ้น
ก่อนหน้านี้ เราได้กล่าวถึงปัจจัยบางอย่างที่เข้าสู่บริบทการสแต็ก เช่น หากองค์ประกอบมีการกำหนดตำแหน่ง ตลอดจนลำดับในมาร์กอัป
แต่อีกแง่มุมหนึ่งของบริบทการสแต็กคือองค์ประกอบย่อยถูกจำกัดให้อยู่ในบริบทการซ้อนของพาเรนต์
มาดูองค์ประกอบทั้งสามที่เป็นปัญหากันดีกว่า
นี่คือมาร์กอัปที่เรามี:
<section class="content">
<div class="modal"></div>
</section>
<div class="side-tab"></div>
เมื่อดูที่มาร์กอัป เราจะเห็นว่าองค์ประกอบเนื้อหาและแท็บด้านข้างเป็นพี่น้องกัน นั่นคือมีอยู่ในระดับเดียวกันในมาร์กอัป (ซึ่งแตกต่างจากระดับดัชนี z) และโมดอลเป็นองค์ประกอบลูกขององค์ประกอบเนื้อหา
เนื่องจาก modal อยู่ภายในองค์ประกอบเนื้อหา z-index
จาก 100 มีผลภายในองค์ประกอบหลักเท่านั้น ซึ่งเป็นองค์ประกอบเนื้อหา ตัวอย่างเช่น หากมีองค์ประกอบย่อยอื่นๆ ที่เป็นพี่น้องกับโมดอล z-index
ค่าต่างๆ จะวางไว้บนหรือข้างใต้กัน
แต่ z-index
ค่าขององค์ประกอบลูกเหล่านั้นไม่ได้มีความหมายอะไรนอกองค์ประกอบหลัก เนื่องจากองค์ประกอบเนื้อหาหลักมี z-index
ตั้งค่าเป็น 1.
ดังนั้นลูกๆ ของมัน รวมทั้งกิริยาช่วย ไม่สามารถแยกออกจาก z-index
ระดับ.
(คุณสามารถจดจำได้ด้วยคำอุปมาที่น่าสลดใจเล็กน้อยนี้:เด็กสามารถถูกพ่อแม่จำกัดและไม่สามารถหลุดพ้นจากพวกเขาได้)
มีวิธีแก้ไขปัญหานี้สองสามข้อ:
วิธีแก้ปัญหา:ย้าย modal ออกนอก เนื้อหาพาเรนต์และลงในบริบทการสแต็กหลักของเพจ
มาร์กอัปที่แก้ไขแล้วจะมีลักษณะดังนี้:
<section class="content"></section>
<div class="modal"></div>
<div class="side-tab"></div>
ตอนนี้องค์ประกอบโมดอลเป็นองค์ประกอบพี่น้องกับอีกสองคน สิ่งนี้ทำให้องค์ประกอบทั้งสามอยู่ในบริบทการสแต็กเดียวกันกับองค์ประกอบ ดังนั้นแต่ละระดับดัชนี z ขององค์ประกอบเหล่านี้จะส่งผลต่อกันและกัน
ในบริบทการซ้อนแบบใหม่นี้ องค์ประกอบจะแสดงตามลำดับต่อไปนี้จากบนลงล่าง:
- โมดอล (
z-index: 100
) - แถบด้านข้าง (
z-index: 5
) - เนื้อหา (
z-index: 1
)
วิธีแก้ไขทางเลือก:ลบการวางตำแหน่งจากเนื้อหา ดังนั้นจึงไม่ จำกัดดัชนี z ของโมดอล
หากคุณไม่ต้องการหรือไม่สามารถเปลี่ยนมาร์กอัป คุณสามารถแก้ไขปัญหานี้ได้โดยลบ position
การตั้งค่าจากองค์ประกอบเนื้อหา:
.content {
// No position set
}
.modal {
position: absolute;
z-index: 100;
}
.side-tab {
position: absolute;
z-index: 5;
}
เนื่องจากตอนนี้องค์ประกอบเนื้อหาไม่มีตำแหน่งแล้ว จะไม่จำกัด z-index
ของ modal อีกต่อไป ค่า. ดังนั้นโมดอลแบบเปิดจะถูกวางไว้ที่ด้านบนขององค์ประกอบแท็บด้านข้าง เนื่องจากมี z-index
ที่สูงกว่า จาก 100
แม้ว่าจะใช้งานได้ แต่ฉันจะไปหาวิธีแก้ปัญหาแรกเป็นการส่วนตัว
เพราะหากคุณต้องวางตำแหน่งองค์ประกอบเนื้อหาด้วยเหตุผลบางอย่างในอนาคต องค์ประกอบดังกล่าวจะจำกัดลำดับของโมดอลอีกครั้งในบริบทการซ้อน
โดยย่อ
ฉันหวังว่าคุณจะพบว่าบทช่วยสอนนี้มีประโยชน์! โดยสรุป ปัญหาส่วนใหญ่เกี่ยวกับดัชนี z สามารถแก้ไขได้โดยปฏิบัติตามหลักเกณฑ์ 2 ข้อนี้:
- ตรวจสอบว่าองค์ประกอบมีการกำหนดตำแหน่งและตัวเลขดัชนี z ในลำดับที่ถูกต้อง
- ตรวจสอบให้แน่ใจว่าคุณไม่มีองค์ประกอบหลักที่จำกัด
z-index
ระดับของลูกๆ
แหล่งข้อมูล:
- W3.org:ความโปร่งใส:คุณสมบัติ 'ทึบ'
- W3.org:การระบุระดับสแต็ก
- เครือข่ายนักพัฒนา Mozilla:บริบทการซ้อน
- PhilipWalton.com:สิ่งที่ไม่มีใครบอกคุณเกี่ยวกับดัชนี Z
- นิตยสารยอดเยี่ยม:คุณสมบัติ CSS ดัชนี Z