css z-index หายไปหลังจาก webkit แปลง translate3d


98

ฉันมีองค์ประกอบ div สองตำแหน่งที่ทับซ้อนกัน ทั้งสองได้ตั้งค่าดัชนี z ผ่าน css ฉันใช้การtranslate3dแปลง webkit เพื่อทำให้องค์ประกอบเหล่านี้เคลื่อนไหวออกจากหน้าจอจากนั้นกลับเข้าสู่หน้าจอ หลังจากที่เปลี่ยนองค์ประกอบไม่เคารพชุดของz-indexค่า

ใครช่วยอธิบายได้ไหมว่าเกิดอะไรขึ้นกับ z-index / stack-order ขององค์ประกอบ div เมื่อฉันทำการแปลง webkit และอธิบายสิ่งที่ฉันสามารถทำได้เพื่อรักษาลำดับสแต็กขององค์ประกอบ div

นี่คือข้อมูลเพิ่มเติมเกี่ยวกับวิธีการแปลงร่าง

ก่อนการแปลงแต่ละองค์ประกอบจะได้รับค่าการเปลี่ยน webkit สองค่าที่กำหนดผ่าน css (ฉันใช้ jQuery เพื่อ.css()เรียกใช้ฟังก์ชัน:

element.css({ '-webkit-transition-duration': duration + 's' });
element.css({ '-webkit-transition-property': '-webkit-transform' });

จากนั้นองค์ประกอบจะเคลื่อนไหวโดยใช้ translate3d -webkit-transform:

element.css({ '-webkit-transform': 'translate3d(' + hwDelta + 'px, 0, -1px)' });

Btw ฉันได้ลองตั้งค่าพารามิเตอร์ที่ 3 เป็นค่าtranslate3dที่แตกต่างกันหลายค่าเพื่อพยายามทำซ้ำลำดับสแต็กในพื้นที่ 3 มิติ แต่ก็ไม่โชคดี

นอกจากนี้เบราว์เซอร์ iPhone / iPad และ Android ก็เป็นเบราว์เซอร์เป้าหมายของฉันที่รหัสนี้ต้องใช้ ทั้งสองรองรับการเปลี่ยน webkit


โพสต์ลิงค์เพื่อดูตัวอย่างได้ไหม
Littlemad

1
ฉันพบปัญหาเดียวกัน ฉันมีแท็ก <iframe> หนึ่งแท็กที่มีสไตล์องค์ประกอบภายใน "-webkit-transform: translate3d (0,0,0)" เพื่อบังคับให้มีการเร่งความเร็ว 3 มิติ ปรากฎว่าเฟรมภายนอกที่มีดัชนี z สูงกว่าจะถูกซ่อนไว้โดยองค์ประกอบ iframe ภายในเสมอ เพียงแค่ซ่อนภาพฉันสามารถ "คลิก" ที่องค์ประกอบภายนอกที่มองไม่เห็นได้ สิ่งนี้เกิดขึ้นเฉพาะใน Mobile Safari
Morgan Cheng

ฉันใช้เวลา 10 ชั่วโมงเพื่อหาว่านั่นคือสิ่งที่ทำให้รหัสของฉันใช้ไม่ได้ Ugh
Dikeneko

คำตอบ:


52

สิ่งนี้อาจเกี่ยวข้องกับ: https://bugs.webkit.org/show_bug.cgi?id=61824

โดยทั่วไปเมื่อคุณใช้การแปลง 3 มิติบนแกน z ดัชนี z จะไม่สามารถคำนวณได้อีกต่อไป (ตอนนี้คุณอยู่ในระนาบการแสดงผล 3 มิติใช้ค่า z ที่แตกต่างกัน) หากคุณต้องการที่จะเปลี่ยนกลับไปใช้การแสดงผลแบบ 2D transform-style: flat;สำหรับองค์ประกอบของเด็กใช้


13
โดยทั่วไปเมื่อคุณใช้การแปลง 3 มิติบนแกน z ดัชนี z จะไม่สามารถนำมาคำนวณได้อีกต่อไป (ตอนนี้คุณอยู่ในระนาบการแสดงผล 3 มิติใช้ค่า z ที่แตกต่างกัน) หากคุณต้องการที่จะเปลี่ยนกลับไปใช้การแสดงผลแบบ 2D transform-style: flat;สำหรับองค์ประกอบของเด็กใช้
samy-delux

2
ดังนั้นในโหมด "pres-3d" เราต้องใช้แกน z ของการแปลงเพื่อกำหนดลำดับและในโหมดแบนเราควรใช้ z-index ข้อผิดพลาดคือ z-index บนซาฟารีเสียเมื่อรวมกับการแปลงแบบเร่ง HW
Steven Lu

1
ไม่ทำงาน ใช้ได้เฉพาะเมื่อฉันลบสไตลส์แบบเคลื่อนไหวตามชั้นเรียน
fdrv

44

สิ่งนี้เกี่ยวข้องกับข้อบกพร่องที่ระบุโดย samy-delux สิ่งนี้ควรส่งผลต่อองค์ประกอบใด ๆ ที่อยู่ในตำแหน่งสัมบูรณ์หรือสัมพัทธ์ ในการแก้ไขปัญหาคุณสามารถใช้คำสั่ง css ต่อไปนี้กับทุกองค์ประกอบที่อยู่ในตำแหน่งนี้และเป็นสาเหตุของปัญหา:

-webkit-transform: translate3d(0,0,0);

สิ่งนี้จะนำการแปลงไปใช้กับองค์ประกอบโดยไม่ต้องทำการแปลงจริง แต่ส่งผลต่อลำดับการแสดงผลดังนั้นจึงอยู่เหนือองค์ประกอบที่ทำให้เกิดปัญหา


เมื่อใช้ Chrome (35.0.1916.114 ม.) ฉันพบว่าถ้าฉันไม่มีกฎนี้หลังจากที่องค์ประกอบถูกพลิก [transform: roty (180deg)] แสดงว่าตัวจัดการการคลิก jQuery ไม่ทำงานกับองค์ประกอบนั้นอีกต่อไป นอกจากนี้หลังจากพลิกแล้วมีปัญหาเกี่ยวกับสิ่งประดิษฐ์ที่ถูกทิ้งไว้บนหน้าจอและโดยเฉพาะอย่างยิ่งหากมีการเปลี่ยนแปลงความทึบเว้นแต่จะมี translate3d! บทความนี้ช่วยให้sitepoint.com/fix-chrome-animation-flash-bug
Philip Murphy

2
สิ่งนี้ช่วยแก้ปัญหาที่เหนียวมากสำหรับฉันเกี่ยวกับองค์ประกอบคงที่สององค์ประกอบหนึ่งที่มีองค์ประกอบที่เปลี่ยนเป็น 3 มิติ องค์ประกอบที่เปลี่ยนเป็น 3 มิติโดยทั่วไปจะล้นและนั่งทับองค์ประกอบอื่น ๆ จนกว่าจะใช้การแก้ไขด้านบน
Collin James

1
ไม่ทำงาน ใช้ได้เฉพาะเมื่อฉันลบสไตลส์แบบเคลื่อนไหวตามชั้นเรียน
fdrv

12

ช้าไปหน่อย แต่ลองใส่องค์ประกอบที่สูญเสียดัชนี Z ของพวกเขาวางสิ่งต่อไปนี้ฉันมีปัญหาเมื่อทำสิ่ง Parallax เมื่อเร็ว ๆ นี้และสิ่งนี้ช่วยได้อย่างมาก

transform-style: preserve-3d;

ซึ่งจะช่วยประหยัดการวาง

transform: translate3d(0,0,0);

ในองค์ประกอบอื่น ๆ ที่ทำให้ GPU เครียดมากขึ้น


1
เมื่อองค์ประกอบของคุณเป็น 3 มิติฉันไม่คาดหวังว่าการเปลี่ยนแปลงจะทำให้ GPU เครียดมากขึ้น ต้องทำการคำนวณอยู่ดี คุณอิงกับสิ่งนี้?
Micros

7

รอชมตัวอย่างครับ

คุณเคยลองแปลงร่าง (1) หรือยัง? ฉันจำได้ว่ามีปัญหาที่คล้ายกันและฉันต้องจัดเรียงลำดับ html ขององค์ประกอบใหม่และใช้การแปลงที่ฉันไม่ต้องการเพียงเพราะดัชนี z ของการใช้การแปลงเปลี่ยนไป

ถ้าฉันไม่ผิดพลาดทุกครั้งที่คุณใช้การแปลงมันจะกลายเป็นดัชนี z สูงสุดที่มีและเรียงลำดับตามองค์ประกอบที่ใกล้ที่สุดของ html คือจุดเริ่มต้นของแท็ก จากบนลงล่าง

ฉันหวังว่าการช่วยเหลือนี้


6

z-index จะทำงานกับ div ที่เปลี่ยนรูปแบบ 3 มิติหากคุณจัดรูปแบบองค์ประกอบที่วางซ้อนกันได้ด้วย -webkit-transform: translateZ(0px);

Snippet บน codepen -> http://codepen.io/mrmoje/pen/yLIul

ในตัวอย่างปุ่มstack upและstack downเพิ่มและลดดัชนี z ของส่วนท้าย (+/- 1) เทียบกับองค์ประกอบที่หมุนแล้ว (ในกรณีนี้คือ img)


ไม่สามารถคลิกสแต็กอัพได้อีก
clevertension

เฮ้ @Moje ฉันยังสงสัยเกี่ยวกับปัญหานี้ สแต็กอัพยังไม่สามารถคลิกได้อีก
alchuang

เหตุใดฉันจึงไม่คิดที่จะเพิ่ม z-index เชิงลบให้กับองค์ประกอบที่แปล ขอบคุณ
จะ

3

ฉันไม่สามารถจำลองปัญหาที่คุณอธิบายไว้ที่นี่ได้ ไม่ว่าฉันจะทำอะไรค่าดัชนี z จะยังคงอยู่ตลอดการแปลงทั้งหมด ฉันกำลังทดสอบโดยใช้ Chromium (Google Chrome)

อาร์กิวเมนต์ที่สามของฟังก์ชัน translate3d จัดการกับแกน z ขององค์ประกอบ แนวคิดนี้คล้ายกับ แต่ไม่เหมือนกับดัชนี z ... องค์ประกอบที่มีแกน z ต่ำกว่าจะอยู่ภายใต้องค์ประกอบที่มีค่าสูงกว่า

ฉันรู้ว่าคุณลองใช้ค่าของอาร์กิวเมนต์ที่สามเพื่อให้ตรงกับดัชนี z ที่คุณต้องการ แต่ปัญหาคือแกน z ดูเหมือนจะไม่เปลี่ยนแปลงในระหว่างการเคลื่อนไหว CSS3 ในตัวอย่างต่อไปนี้องค์ประกอบที่ถูกวางไว้ควรอยู่ด้านบน แต่ #element_a จะอยู่ด้านบน

ถ้าฉันเพิ่ม z-index ให้กับทั้งตัวเลือกปกติและตัวเลือก: hover ดูเหมือนว่าจะใช้งานได้และอนุญาตให้องค์ประกอบที่โฮเวอร์อยู่บนสุด

แม้ว่าจะไม่ใช่สิ่งที่คุณกำลังมองหา แต่พฤติกรรมนี้เป็นวิธีแก้ปัญหา คุณเพียงแค่ต้องใช้ translate3d และ z-index เพื่อกำหนดลำดับสำหรับการเรนเดอร์เริ่มต้น

<style>
    div {
        width: 300px;
        height: 150px;
        background-color: white;
        border: 5px outset gray;
        float: left;
        margin: 20px;
        -webkit-transition: 2s;
    }

    #element_a {
        -webkit-transform: translate3d(0, 0, 50px);
    }
    #element_b {
        -webkit-transform: translate3d(0, 0, 100px);
    }

    #element_a:hover {
        -webkit-transform: translate3d(100px, 0, 60px);
    }

    #element_b:hover {
        -webkit-transform: translate3d(-100px, 0, -60px);
    }
</style>
<body>
    <div id="element_a">
        <img src="http://www.google.com/intl/en_com/images/srpr/logo3w.png">
    </div>
    <div id="element_b">
        <img src="http://www.google.com/intl/en_com/images/srpr/logo3w.png">
    </div>
</body>

2
สิ่งนี้ได้ผลสำหรับฉัน - ขอบคุณ! ฉันเพิ่มสิ่งต่อไปนี้ในองค์ประกอบที่ฉันต้องการให้เป็น 'ด้านหน้า': -webkit-transform: translate3d (0, 0, 1px);
Sam Dutton

0

อีกวิธีหนึ่งคือคุณสามารถสร้างองค์ประกอบหลักและใช้การเปลี่ยนอื่น ๆ ทั้งหมดที่เกี่ยวข้อง:

# Apply transitions to a parent div
<div>
  # This image z-index -1 
  <img src="foo"/>

  # This image z-index -3
  <img src="bar"/>

  #This image z-index -2
  <img src="gg"/>
</div>

JsFiddle

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.