Safari中的CSS变换和固定定位

6
我在使用固定定位、CSS转换容器和Safari时遇到了问题。我试图在模态框内点击一个项目以显示下拉列表。模态框带有CSS transform。为了确保下拉列表始终显示在模态框上方,我将其定位为固定位置(使用 JS 计算lefttop 值)。
在Chrome、Firefox和Opera中,它按预期工作,但Safari表现出奇怪的行为。根据W3C:

任何计算值(computed value)除了none for the transform都会导致创建一个层叠上下文(stacking context)和包含块(containing block)。该对象作为固定定位后代元素的包含块。

因此,CSS转换容器内的固定定位元素应该相对于该容器定位,而不是相对于视口定位。但是似乎Safari并没有像这样运行。请查看此示例:

$(document).ready(function() {
  $(".show-liste").click(function() {
    $(".liste").show();
  });
});
.modale {
  height: 50px;
  overflow-y: scroll;
  transform: translate(100px);
}

ul {
  position: fixed;
  left: 0px;
  top: 0px;
}



/* --- Purely style related stuff ---- */

body {
  font-size: 80%;
}
.modale {
  position: absolute;
  top: 50px;
  padding: 60px;
  background-color: white;
  border: 1px solid #ccc;
  box-shadow: 2px 2px 2px #ddd;
}
button {
  width: 200px;
}
ul {
  list-style-type: none;
  margin-top: 0;
  padding-left: 0;
  width: 200px;
  display: none;
  box-shadow: 2px 2px 2px #ddd;
}
li {
  background: white;
  padding: 10px 20px;
  border: 1px solid #eee;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="modale">
  <div class="row">
    <div>
      <button class="show-liste">Open dropdown</button>
      <ul class="liste">
        <li>Choice 1</li>
        <li>Choice 2</li>
        <li>Choice 3</li>
        <li>Choice 4</li>
        <li>Choice 5</li>
      </ul>
    </div>
  </div>
</div>

你有没有想过如何解决这个问题?有没有任何polyfill或方法可以解决这个问题?使用绝对定位是我想避免的解决方案,因为它会涉及将列表移动到文档的主体级别,然后处理它的创建/销毁、附加模型(我正在使用AngularJS)、事件等。那真的是我的最后一招。


你的代码片段出现了一些奇怪的问题。这里是相同代码的jsFiddle链接 - Blazemonger
根据W3C的描述,position: fixed应该始终相对于浏览器视口定位,而不是像absolute一样相对于包含元素定位。因此,Firefox和Chrome正在偏离官方规范,而Safari认为其行为是“正确的”。 - Blazemonger
在CSS3转换模块出现之前确实是这样的情况。现在,CSS3转换后的项目成为“固定定位后代元素的包含块”(http://www.w3.org/TR/css3-transforms/#transform-property)。 - Pierre-Adrien
1
CSS3变换仍然是一个工作草案,这可能解释了不一致性。发现这个答案可能会有所帮助。 - Blazemonger
你有没有考虑在Safari中使用iframe来解决这个问题? - Blazemonger
1个回答

3

我相信,使用 position:absolute 代替 position:fixed,可以实现所需的跨浏览器行为。


当然可以。我一直在寻找其他解决方案,因为我正在处理的项目需要更多的工作来使用“position: absolute”来定位元素(需要将DOM节点复制到根级别,注意其生命周期、事件等,这会导致其他问题)。我完全忘记提到这一点了,我会更新我的问题。 - Pierre-Adrien
你根本不需要移动DOM节点。将fixed更改为absolute会将.liste绝对定位在.modale内,就像你想要的那样。 - Blazemonger
很抱歉,我的代码片段不准确。我忘了提到我的模态窗口具有固定高度和 overflow:scroll(这就是为什么如果我想使用 absolute 定位它,我需要使用 fixed 或将 .liste 移动到文档根目录)。我再次修复了我的初始问题。对此再次道歉! - Pierre-Adrien

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接