'transform3d' ไม่ทำงานกับตำแหน่ง: แก้ไขลูก ๆ


140

ฉันมีสถานการณ์ที่ในสถานการณ์ CSS ปกติ div ที่ตายตัวจะถูกวางตำแหน่งอย่างที่มันถูกระบุไว้ ( top:0px, left:0px)

สิ่งนี้ดูเหมือนจะไม่ได้รับการเคารพถ้าฉันมีผู้ปกครองที่มีการแปลง translate3d ฉันไม่เห็นอะไรเหรอ? ฉันได้ลองใช้การแปลงเว็บอื่น ๆ อย่างมีสไตล์และเปลี่ยนตัวเลือกแหล่งกำเนิด แต่ก็ไม่มีโชค

ฉันแนบJSFiddleพร้อมกับตัวอย่างที่ฉันคาดว่ากล่องสีเหลืองจะอยู่ที่มุมด้านบนของหน้าแทนที่จะเป็นด้านในขององค์ประกอบคอนเทนเนอร์

คุณสามารถดูซอเวอร์ชันด้านล่างได้ง่ายขึ้น:

#outer {
    position:relative; 
    -webkit-transform:translate3d(0px, 20px , 0px); 
    height: 300px; 
    border: 1px solid #5511FF; 
    padding: 10px;
    background: rgba(100,180,250, .8); 
    width: 80%;
}
#middle{
    position:relative; 
    border: 1px dotted #445511; 
    height: 300px; 
    padding: 5px;
    background: rgba(250,10,255, .6);
}
#inner {
    position: fixed; 
    top: 0px;
    box-shadow: 3px 3px 3px #333; 
    height: 20px; 
    left: 0px;
    background: rgba(200,180,80, .8); 
    margin: 5px; 
    padding: 5px;
}
<div id="container">
    Blue: Outer, <br>
    Purple: Middle<br>
    Yellow: Inner<br>
    <div id="outer"> 
        <div id="middle">
            <div id="inner">
                Inner block
            </div>
        </div>
    </div>
</div>

ฉันจะทำให้ translate3d ทำงานกับเด็กที่มีตำแหน่งคงที่ได้อย่างไร


ปัญหาเดียวกันนี้เกิดขึ้นกับตัวกรองด้วยเช่นกัน: stackoverflow.com/q/52937708/8620333
Temani Afif

คำตอบ:


196

นี่เป็นเพราะการtransformสร้างระบบพิกัดท้องถิ่นใหม่ตามข้อกำหนด W3C :

ใน HTML เนมสเปซค่าใด ๆ นอกเหนือจากnoneการแปลงผลลัพธ์ในการสร้างทั้งบริบทการซ้อนและบล็อกที่มี วัตถุทำหน้าที่เป็นบล็อกที่มีสำหรับการสืบทอดตำแหน่งถาวร

ซึ่งหมายความว่าการจัดตำแหน่งแบบตายตัวจะถูกแก้ไขกับองค์ประกอบที่ถูกแปลงแทนที่จะเป็นวิวพอร์ต

ปัจจุบันยังไม่มีวิธีแก้ไขปัญหาที่ฉันทราบ

นอกจากนี้ยังมีการบันทึกไว้ในบทความของเอริคเมเยอร์: Un-แก้ไของค์ประกอบคงที่ด้วย CSS แปลง


ขอบคุณฉันไม่ได้สังเกตว่าข้อมูลจำเพาะที่แท้จริงมีข้อมูลนั้น ..... ฉันเดาว่าฉันได้เทียบเท่ากับคำตอบทางคณิตศาสตร์: "โดยคำจำกัดความ" :)
Juan Carlos Moreno

3
@INT ฉันไม่คิดว่าจะมีวิธีแก้ปัญหาสำหรับสิ่งนี้ มีกรณีการใช้งานที่สำคัญสำหรับการไม่อนุญาตให้มีการแก้ไขปัญหา: ผู้ใช้ที่ป้อนข้อมูลอาจครอบคลุมการควบคุมนอกพื้นที่ที่กำหนด (คิดว่าเป็นตัวเลือกการเพิ่มอีเมลที่เป็นอันตรายในแถบเครื่องมือ gmail) วิธีแก้ปัญหาที่ดีที่สุดคือหลีกเลี่ยงการเปลี่ยนรูปในขณะที่คุณกำลังใช้งานแก้ไขจากด้านใน
saml

1
จะไม่ตั้งค่าคุณลักษณะ CSS บนให้เป็นหน้าต่างใดๆscrollHeightใช้งานได้หรือไม่ คุณอาจต้องวางตำแหน่งอย่างแน่นอนเช่นกัน แต่สิ่งนี้ควรจะเป็นไปได้ใช่ไหม? (ขี้เกียจเกินกว่าที่จะทดสอบได้จริงตอนนี้)
แบรดโอรีโก

@ bradorego คุณพูดถูกฉันเพิ่งเพิ่มรหัสที่ฉันใช้
Uzumaki

นี่ยังคงเป็นฟลักซ์ในสเป็คเท่าที่ฉันสามารถบอกได้ ดูข้อผิดพลาด 16328 - การใช้ "มีบล็อก" ไม่ตรงกับคำนิยาม
สาม

13

ฉันมีการกะพริบบน nav คงที่ของฉันเมื่อรายการในหน้ากำลังใช้การแปลงต่อไปนี้นำไปใช้กับ nav ด้านบนของฉันแก้ไขปัญหาการกระโดด / ริบหรี่:

#fixedTopNav {
    position: fixed;
    top: 0;
    transform: translateZ(0);
    -webkit-transform: translateZ(0);
}

ขอบคุณคำตอบนี้บน SO


12

ตามที่แนะนำของ Bradoergo เพียงแค่รับหน้าต่างscrollTopและเพิ่มไปยังตำแหน่งสูงสุดอย่างเช่น:

function fix_scroll() {
  var s = $(window).scrollTop();
  var fixedTitle = $('#fixedContainer');
  fixedTitle.css('position','absolute');
  fixedTitle.css('top',s + 'px');
}fix_scroll();

$(window).on('scroll',fix_scroll);

มันใช้งานได้สำหรับฉัน


3
มันได้ผล! แต่แทนที่จะผูกกับ "หน้าต่าง" ฉันต้องผูกกับ div ที่กำลังเลื่อน นอกจากนี้องค์ประกอบคงที่กะพริบ
ฝึกอบรม

jQuery ต้องทำอะไรที่นี่?
FlorianB

สิ่งนี้สามารถทำได้ แต่เช่นเดียวกับ @train ที่กล่าวถึงมันจะกะพริบ
Etienne Dupuis

ใช่นี่ไม่ได้อัปเดตเร็วพอที่จะสะอาดพอสำหรับการใช้งานของฉัน: - / ความคิดที่ดีดังนั้น
reid

นี่คือการปฏิบัติที่เลวร้ายมากไม่ได้ทำการเปลี่ยนแปลงอย่างมีสไตล์ด้วย js
Wannes

4

ใน Firefox และ Safari คุณสามารถใช้position: sticky;แทนposition: fixed;แต่จะไม่ทำงานในเบราว์เซอร์อื่น เพื่อที่คุณจะต้องมีจาวาสคริปต์


2
ตำแหน่งปักหมุดเป็นลูกผสมของตำแหน่งสัมพัทธ์และตำแหน่งคงที่และเป็นการทดลองจริง ๆฉันขอแนะนำให้หลีกเลี่ยงสิ่งนี้เนื่องจากยังไม่ได้มาตรฐาน
Farside

1
AFAIK บน Firefox และ Safari คุณสามารถใช้งานได้position:fixedและจะทำงานได้ตามที่คาดหวัง
oriadam

@oriadam ไม่ฉันมีปัญหาเมื่อผู้ปกครองใช้ translate3d และตำแหน่งคงที่ของเด็กกำลังบินไปมาในบางกรณี จะพยายามใช้งานstickyในขณะที่เบราว์เซอร์หลักได้รับการสนับสนุนอยู่แล้ว: caniuse.com/#feat=css-sticky
Lukas Liesis

stickyอาจเป็นวิธีแก้ปัญหามันทำงานได้ที่เบราว์เซอร์ที่ทันสมัย
aboutqx

3

ในความคิดของฉันวิธีที่ดีที่สุดในการจัดการกับสิ่งนี้คือการใช้การแปลแบบเดียวกัน แต่แยกเด็กที่ต้องการแก้ไขจากองค์ประกอบหลัก (แปล) ของผู้ปกครอง จากนั้นใช้การแปลกับ div ภายในposition: fixedwrapper

ผลลัพธ์มีลักษณะเช่นนี้ (ในกรณีของคุณ):

<div style='position:relative; border: 1px solid #5511FF; 
            -webkit-transform:translate3d(0px, 20px , 0px); 
            height: 100px; width: 200px;'> 

</div>
<div style='position: fixed; top: 0px; 
            box-shadow: 3px 3px 3px #333; 
            height: 20px; left: 0px;'>
    <div style='-webkit-transform:translate3d(0px, 20px, 0px);'>
        Inner block
    </div>
</div>

JSFiddle: https://jsfiddle.net/hju4nws1/

ในขณะที่สิ่งนี้อาจไม่เหมาะสำหรับบางกรณีการใช้งานโดยทั่วไปถ้าคุณกำลังแก้ไข div คุณอาจไม่สนใจว่าองค์ประกอบใดคือแม่ / ที่อยู่ในต้นไม้ที่สืบทอดใน DOM ของคุณและดูเหมือนว่าจะแก้ปัญหาส่วนใหญ่ได้ - ในขณะที่ยังคงให้ทั้งสองtranslateและposition: fixedอยู่ในความสามัคคี (ญาติ)


0

ฉันเจอปัญหาเดียวกัน ความแตกต่างเพียงอย่างเดียวคือองค์ประกอบของฉันที่มี 'ตำแหน่ง: แก้ไข' มีคุณสมบัติสไตล์ 'ด้านบน' และ 'ซ้าย' ที่ตั้งค่าจาก JS ดังนั้นฉันสามารถใช้การแก้ไข:

var oRect = oElement.getBoundingClientRect();

วัตถุ oRect จะมีพิกัดที่แท้จริง (สัมพันธ์กับการดูพอร์ต) ด้านบนและด้านซ้าย ดังนั้นคุณสามารถปรับคุณสมบัติ oElement.style.top และ oElement.style.left ที่แท้จริงได้


สิ่งนี้ใช้ได้กับ IE และ Chrome แต่ไม่ใช่ในเบราว์เซอร์มาตรฐาน Android ด้านซ้ายเป็นตัวเลข แต่จะวาดเสมอในตำแหน่งที่ 0
Adaptabi

0

ฉันมี canvas sidebar ที่ใช้ -webkit-transform: translate3d นี่เป็นการป้องกันไม่ให้ฉันวางส่วนท้ายคงที่บนหน้า ฉันแก้ไขปัญหาด้วยการกำหนดเป้าหมายคลาสในหน้า html ที่เพิ่มไปยังแท็กเมื่อเริ่มต้นของแถบด้านข้างแล้วเขียน css: ไม่ใช่ตัวระบุสถานะ "-webkit-transform: none;" ไปยังแท็ก html เมื่อไม่มีคลาสนั้นบนแท็ก html หวังว่านี่จะช่วยให้ใครบางคนที่นั่นด้วยปัญหาเดียวกันนี้!


0

ลองใช้การแปลงตรงกันข้ามกับองค์ประกอบย่อย:

<div style='position:relative; border: 1px solid #5511FF; 
            -webkit-transform:translate3d(0px, 20px , 0px); 
            height: 100px; width: 200px;'> 
    <div style='position: fixed; top: 0px; 
                -webkit-transform:translate3d(-100%, 0px , 0px); 
                box-shadow: 3px 3px 3px #333; 
                height: 20px; left: 0px;'>
        Inner block
    </div>
</div>

0

เพิ่มคลาสแบบไดนามิกในขณะที่องค์ประกอบแปลง $('#elementId').addClass('transformed'). จากนั้นไปประกาศใน css

.translat3d(@x, @y, @z) { 
     -webkit-transform: translate3d(@X, @y, @z); 
             transform: translate3d(@x, @y, @z);
      //All other subsidaries as -moz-transform, -o-transform and -ms-transform 
}

แล้วก็

#elementId { 
      -webkit-transform: none; 
              transform: none;
}

แล้วก็

.transformed {
    #elementId { 
        .translate3d(0px, 20px, 0px);
    }
}

ตอนนี้position: fixedเมื่อได้รับค่าa topและz-indexคุณสมบัติขององค์ประกอบลูกเพียงแค่ทำงานได้ดีและคงที่จนกว่าองค์ประกอบหลักจะเปลี่ยน เมื่อการแปลงกลับเป็นองค์ประกอบลูกก็จะกลับมาเหมือนเดิมอีกครั้ง สิ่งนี้จะช่วยลดสถานการณ์ได้หากคุณใช้แถบข้างการนำทางที่สลับเปิดและปิดเมื่อคลิกและคุณมีชุดแท็บที่ควรค้างไว้ในขณะที่คุณเลื่อนหน้าลง


-1

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

<br>
<div style='position:relative; border: 1px solid #5511FF; 
            -webkit-transform:translate3d(0px, 20px , 0px); 
            height: 100px; width: 200px;'> 
    <div style='position: fixed; top: 0px; 
                -webkit-transform:translate3d(0px, 20px , 0px); 
                box-shadow: 3px 3px 3px #333; 
                height: 20px; left: 0px;'>
        Inner block
    </div>
</div>

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