不与位置一起工作的“转换3d”: 固定的子级

我遇到过这样的情况,在正常的 CSS 环境中,一个固定的 div 将被精确地放置在指定的位置(top:0pxleft:0px)。

如果我有一个具有转换3d 转换的父节点,那么这似乎不受尊重。我没看到什么吗?我已经尝试了其他类似 webkit 的样式转换和转换原点选项,但没有运气。

我附加了一个 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>

我如何使翻译3D 工作与固定位置的儿童?

94175 次浏览

这是因为 transform创建了一个新的本地坐标系,如 W3C 规范所示:

在 HTML 命名空间中,转换的任何值(none除外)都会导致创建堆栈上下文和包含块。该对象充当固定定位子代的包含块。

这意味着固定定位变成固定到转换的元素,而不是视口。

据我所知,目前还没有解决办法。

它也被记录在 Eric Meyer 的文章 用 CSS 变换去除固定元素中。

我碰到了同样的问题。唯一的区别是,我的元素的“ position: fix”的“ top”和“ left”样式属性是从 JS 设置的。因此,我能够应用一个修复:

var oRect = oElement.getBoundingClientRect();

ORect 对象将包含 真的(相对于视图端口)顶部和左侧坐标。因此可以调整实际的 oElement.style.top 和 oElement.style.left 属性。

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

不管怎样,这对我有用。

当页面中的项目正在使用转换时,我的固定顶部导航有一个闪烁,下面应用到顶部导航解决了跳跃/闪烁问题:

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

感谢 SO 上的这个答案

处理这个问题的一种方法是对固定元素应用相同的转换:

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

在 Firefox 和 Safari 中,你可以使用 position: sticky;而不是 position: fixed;,但是在其他浏览器中无法工作。为此你需要 javascript。

我有一个离开画布的侧边栏,它使用-webkit-change: transate3d。这使我无法在页面上放置固定的页脚。我解决这个问题的方法是: 在 html 页面上定位一个类,该类在边栏初始化时被添加到标记中,然后在 html 标记中不存在该类时,编写一个 css: not 修饰符来状态“-webkit-change: none;”到 html 标记中。希望这能帮助那些有同样问题的人!

尝试对子元素应用相反的转换:

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

在我看来,处理这个问题的最佳方法是应用相同的翻译,但是将需要修改的子元素从它们的父元素(翻译)中分离出来; 然后将翻译应用到 position: fixed包装器中的 div。

结果如下(在您的例子中) :

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

https://jsfiddle.net/hju4nws1/

虽然这对于某些用例来说可能并不理想,但通常如果你正在修复一个 div,你可能不太关心它的父元素是什么/它在 DOM 的继承树中的位置,而且似乎解决了大部分的难题——同时仍然允许 translateposition: fixed保持(相对)和谐。

添加一个动态类,而元素 forms.$('#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);
}
}

现在,如果在子元素上提供了 topz-index属性值,那么 position: fixed就可以正常工作并保持不变,直到父元素发生转换。当转换恢复时,子元素将再次弹出为固定值。如果你实际上使用一个导航侧边栏,点击一下就可以打开和关闭,并且你有一个标签集,当你向下滚动页面时,它应该保持粘性,那么这应该会使情况变得容易一些。