'Transform3d' không hoạt động với vị trí: trẻ em cố định


140

Tôi có một tình huống trong đó, trong các trường hợp CSS bình thường, một div cố định sẽ được định vị chính xác nơi nó được chỉ định ( top:0px, left:0px).

Điều này dường như không được tôn trọng nếu tôi có cha mẹ có biến đổi transl3d. Tôi không nhìn thấy cái gì à? Tôi đã thử các tùy chọn chuyển đổi webkit khác như kiểu và biến đổi nguồn gốc nhưng không gặp may.

Tôi đã đính kèm một JSFiddle với một ví dụ mà tôi mong muốn hộp màu vàng nằm ở góc trên cùng của trang chứ không phải bên trong phần tử container.

Bạn có thể tìm thấy bên dưới một phiên bản đơn giản của fiddle:

#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>

Làm cách nào tôi có thể làm cho transl3d hoạt động với trẻ em có vị trí cố định?


Vấn đề tương tự cũng xảy ra với bộ lọc: stackoverflow.com/q/52937708/8620333
Temani Afif

Câu trả lời:


196

Điều này là do việc transformtạo ra một hệ tọa độ cục bộ mới, theo thông số W3C :

Trong không gian tên HTML, bất kỳ giá trị nào khác ngoài nonebiến đổi đều dẫn đến việc tạo cả bối cảnh xếp chồng và khối chứa. Đối tượng hoạt động như một khối chứa cho con cháu định vị cố định.

Điều này có nghĩa là định vị cố định trở thành cố định cho phần tử được chuyển đổi, thay vì chế độ xem.

Hiện tại không có một công việc xung quanh mà tôi biết.

Nó cũng được ghi lại trong bài viết của Eric Meyer: Không sửa các thành phần cố định với các biến đổi CSS .


Cảm ơn, tôi đã không nhận thấy rằng thông số kỹ thuật thực tế có thông tin đó ..... Tôi đoán rằng tôi đã nhận được tương đương với câu trả lời toán học: "theo định nghĩa" :)
Juan Carlos Moreno

3
@INT, tôi không nghĩ sẽ có cách giải quyết cho việc này. Có một trường hợp sử dụng chính cho việc không cho phép giải quyết: đầu vào do người dùng cung cấp có khả năng bao gồm các điều khiển bên ngoài khu vực được chỉ định của họ (nghĩ rằng một email độc hại thêm tùy chọn vào thanh công cụ gmail). Cách giải quyết tốt nhất sẽ là tránh các biến đổi trong thời điểm hiện tại nếu bạn sẽ sử dụng cố định từ bên trong nó.
saml

1
Sẽ không thiết lập thuộc tính hàng đầu CSS cho bất kỳ cửa sổ nào.scrollHeight là hoạt động? Bạn có thể phải hoàn toàn định vị nó là tốt, nhưng một cái gì đó như thế này có thể thực hiện được, không? (quá lười để thực sự kiểm tra ngay bây giờ)
Brad Orego

@bradorego bạn đã đúng, tôi vừa thêm mã tôi đã sử dụng.
UzumakiDev

Điều này vẫn còn thay đổi trong thông số kỹ thuật như tôi có thể nói. Xem Bug 16328 - Sử dụng "khối chứa" không khớp với định nghĩa CSS2.1 .
thứ ba

13

Tôi đã có một lần nhấp nháy trên điều hướng hàng đầu cố định của mình khi các mục trong trang đang sử dụng biến đổi, điều sau đây được áp dụng cho điều hướng hàng đầu của tôi đã giải quyết vấn đề nhảy / nhấp nháy:

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

Nhờ câu trả lời này trên SO


12

Như Bradoergo đã đề xuất, chỉ cần lấy cửa sổ scrollTopvà thêm nó vào vị trí tuyệt đối trên cùng như:

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);

Điều này làm việc cho tôi anyway.


3
Nó hoạt động! nhưng thay vì liên kết với "cửa sổ", tôi phải liên kết với div đang cuộn. Ngoài ra, các yếu tố cố định thấp thoáng.
tàu

JQuery phải làm gì ở đây?
FlorianB

Điều này có thể đã làm điều đó, nhưng như @train đã đề cập, nó nhấp nháy.
Etienne Dupuis

Vâng, điều này không cập nhật gần đủ nhanh để đủ sạch cho việc sử dụng của tôi: - / ý tưởng tốt tho
reid

Đây là một thực tế rất tệ, đừng thay đổi phong cách với js
Wannes

4

Trong Firefox và Safari, bạn có thể sử dụng position: sticky;thay vì position: fixed;nhưng nó sẽ không hoạt động trong các trình duyệt khác. Cho rằng bạn cần javascript.


2
Định vị dính là kết hợp giữa định vị tương đối và cố định và thực sự thử nghiệm , tôi khuyên bạn nên tránh điều này, vì nó chưa chuẩn.
Farside

1
AFAIK trên Firefox và Safari bạn chỉ cần sử dụng position:fixedvà nó sẽ hoạt động như mong đợi.
oriadam

@oriadam không, tôi có một vấn đề khi phụ huynh sử dụng transl3d và vị trí cố định của trẻ em đang bay xung quanh trong một số trường hợp. Sẽ cố gắng sử dụng stickytrong khi nó đã được hỗ trợ bởi các trình duyệt chính: caniuse.com/#feat=css-sticky
Lukas Liesis

stickycó thể là một giải pháp, nó hoạt động ở trình duyệt hiện đại.
aboutqx

3

Theo tôi, phương pháp tốt nhất để giải quyết vấn đề này là áp dụng cùng một bản dịch, nhưng phá vỡ những đứa trẻ cần được sửa chữa khỏi yếu tố cha mẹ (dịch) của chúng; và sau đó áp dụng dịch cho một div bên trong position: fixedtrình bao bọc.

Các kết quả trông giống như thế này (trong trường hợp của bạn):

<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>

Mã thông báo: https://jsfiddle.net/hju4nws1/

Mặc dù điều này có thể không lý tưởng cho một số trường hợp sử dụng, thông thường nếu bạn đang sửa lỗi div, bạn có thể ít quan tâm đến yếu tố nào là cha mẹ của nó / nơi nó nằm trong cây thừa kế trong DOM của bạn và dường như giải quyết được hầu hết vấn đề đau đầu - trong khi vẫn cho phép cả hai translateposition: fixedsống hòa thuận (tương đối).


0

Tôi chạy qua cùng một vấn đề. Sự khác biệt duy nhất là phần tử của tôi với 'vị trí: đã sửa' có các thuộc tính kiểu 'trên cùng' và 'bên trái' được đặt từ JS. Vì vậy, tôi đã có thể áp dụng một sửa chữa:

var oRect = oElement.getBoundingClientRect();

oRect đối tượng sẽ chứa thực (liên quan đến xem cổng) trên và tọa độ trái. Vì vậy, bạn có thể điều chỉnh các thuộc tính oEuity.style.top và oEuity.style.left thực tế của mình.


Điều này hoạt động trên IE và Chrome, nhưng không phải trên trình duyệt tiêu chuẩn Android. Bên trái là một số nhưng nó luôn được vẽ ở vị trí 0
Adaptabi

0

Tôi có một thanh bên vải tắt sử dụng -webkit-Transform: translate3d. Điều này đã ngăn tôi đặt một chân trang cố định trên trang. Tôi đã giải quyết vấn đề bằng cách nhắm mục tiêu một lớp trên trang html được thêm vào thẻ khi khởi tạo thanh bên và sau đó viết một css: không đủ điều kiện để trạng thái "-webkit-Transform: none;" vào thẻ html khi lớp đó không có trên thẻ html. Hy vọng điều này sẽ giúp ai đó ngoài kia với vấn đề tương tự!


0

Cố gắng áp dụng biến đổi ngược lại cho phần tử con:

<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

Thêm một lớp động trong khi phần tử biến đổi. $('#elementId').addClass('transformed'). Sau đó tiếp tục khai báo trong 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 
}

sau đó

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

sau đó

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

Bây giờ position: fixedkhi được cung cấp một giá trị a topvà thuộc z-indextính trên một phần tử con, nó sẽ hoạt động tốt và cố định cho đến khi phần tử cha biến đổi. Khi chuyển đổi được hoàn nguyên, phần tử con bật lên như cố định một lần nữa. Điều này sẽ giảm bớt tình huống nếu bạn thực sự đang sử dụng một thanh bên điều hướng để bật và đóng khi nhấp chuột và bạn có một bộ tab sẽ giữ được độ dính khi bạn cuộn xuống trang.


-1

Một cách để giải quyết vấn đề này là áp dụng cùng một biến đổi cho phần tử cố định:

<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
Lỗi trên IE không tồn tại ở vị trí đầu tiên
oriadam
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.