位置:固定在位置:固定:哪个浏览器正确?

时间:2016-11-11 15:24:48

标签: html css css-position

将固定元素放在另一个固定元素中的行为在Chrome / Safari和Firefox中表现不同。

This answer explains well the expected behavior对于相对的内部的固定div,以及此MDN is pretty clear

  

固定定位不要为元素留出空间。相反,将其放置在相对于屏幕视口的指定位置,并在滚动时不要移动它。打印时,将其放在每页的固定位置。

我不明白Firefox正在使用固定div中的固定div做什么。我期望的是,子元素在悬停时与包装器一起移动。



.wrapper, .header {
  position:fixed;
  width:320px;
}

.wrapper:hover{
  left:0px;
}
.wrapper{
  width:320px;
  height:100%;
  background:white;
  overflow:scroll;
  left:-200px;
  transition: all ease-out .3s;
}
ul {
  margin-top:120px;
}
 .header {
   background:rgba(255,255,255,0.9);
}

body{
  background:gray;

<div class="wrapper">
  <div class="header">
    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repudiandae vitae a, itaque commodi, odio et. Excepturi, obcaecati? Architecto repellendus omnis mollitia animi rem quasi at, odit aperiam voluptatibus voluptates earum!
  </div>
  <ul>
    <li>
      Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusantium quam maiores, voluptas facere, iste quis iusto reiciendis delectus, quod blanditiis tempora. Earum voluptatum dicta quae, explicabo placeat at rerum assumenda!
    </li>
    <li>
      Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusantium quam maiores, voluptas facere, iste quis iusto reiciendis delectus, quod blanditiis tempora. Earum voluptatum dicta quae, explicabo placeat at rerum assumenda!
    </li>
    <li>
      Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusantium quam maiores, voluptas facere, iste quis iusto reiciendis delectus, quod blanditiis tempora. Earum voluptatum dicta quae, explicabo placeat at rerum assumenda!
    </li>
    <li>
      Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusantium quam maiores, voluptas facere, iste quis iusto reiciendis delectus, quod blanditiis tempora. Earum voluptatum dicta quae, explicabo placeat at rerum assumenda!
    </li>
  </ul>
</div>
&#13;
&#13;
&#13;

有什么想法?我正在寻找一种解决方法,以便在浏览器之间实现一致性。

编辑:更有趣?

添加此功能会在FF上出现更多故障:

.header:hover{
  height:200px;
}

在悬停时,它会触发重绘,然后FF重新计算元素的位置。

使用FF 46.0.1,Chrome 54.0.2840.71和Safari版本9.1.1(11601.6.17)进行的测试。 注意:我已阅读this question

2 个答案:

答案 0 :(得分:5)

要查看所需行为的两种解决方法,请向下滚动水平线规则。

11/18/16更新 - CSSWG回复我说它应该创建一个新的堆叠环境:

  

You're right, this was supposed to be merged into the positioning spec as well - reflected now. Thanks.

关于哪个浏览器正确无误:

fixed位置元素应始终相对于视口放置,特别是在10.1中建立position: fixed元素包含块"by the viewport" 0.3:

  

如果元素的位置为:fixed&#39;,则包含的块由视口[...]

建立

这个包含块正式称为&#34; initial包含块&#34;。

9.3.1也支持这一点,对于普通的非分页媒体(如此),

  

[...]对于手持,投影,屏幕,tty和tv媒体类型,该框相对于视口是固定的,滚动时不会移动

您的代码中发生的是您在悬停时更改父元素的left属性的值,并且您也希望子元素也可以移动。但是,子元素(正确)不移动。

10.3.7

  

为了计算静态位置,固定定位元素的包含块是初始包含块而不是视口。

(这里的静态位置表示元素放置在正常流程中的位置)。

它还说:

  

[If]&#39; left&#39;并且&#39;对&#39;是&#39; auto&#39;和#&#39;宽度&#39;不是&#39; auto&#39;,[...] set&#39; left&#39;到静态位置,否则设置“正确”#39;到静态位置。然后解决'左'&#39; (如果&#39;指示是&#39; rtl&#39;)或&#39;正确&#39; (如果&#39;方向&#39;是&#39; ltr&#39;)。

我相信,这解释了为什么子position: fixed元素最初设置为left: -200px;的位置,如果它是position: static,则该元素在其父元素中的位置。

此时,看起来您认为父的新left值应移动子元素,我假设,或者是因为您期望新的left属性由孩子继承(不是left的工作方式),或者你希望它重新流动文件,这在:hover上没有发生据我回忆;浏览器仅在:hover重新绘制,它不会更改文档流,但确实会更改元素的外观(例如background-color,{{1} },opacity等)。

所以......除非在临时状态(如visibility: hidden;)或游戏中的过渡/动画中有伪选择器改变属性,否则重新绘制的元素不应该移动。

在这种情况下,Chrome和Safari似乎正在做一些不同于规范建议的事情;它们要么导致完全重新流,要么设置:hover个元素来继承祖先的position: fixed属性。根据Oriol下面链接的CSS Working Group draft,如果你愿意,这似乎在董事会之上。但是,在规范更新之前,它仍然是非标准行为。

  • 长话短说,Chrome和Safari现在错误,但最终一旦规范更新,它们就会正确,Firefox将不得不更新其渲染行为。

left div继承您的新.header属性,因为这就是Chrome的行为方式,这就是您寻求的行为。我还调整了left的宽度,以便它不会覆盖.header上的滚动条:

&#13;
&#13;
.wrapper
&#13;
.wrapper, .header {
  position: fixed;
}

.wrapper:hover {
  left:0px;
}
.wrapper{
  width:320px;
  height:100%;
  background:white;
  overflow:scroll;
  left:-200px;
  transition: all ease-out .3s;
}
ul {
  margin-top:120px;
}
.header {
  background:rgba(255,255,255,0.9);
  left: inherit;
  width: 303px;
}

body{
  background:gray;
}
&#13;
&#13;
&#13;

答案 1 :(得分:-2)

所以,我认为由于Firefox中left的实现存在错误而出现了问题。

当鼠标悬停在.wrapper时,.header应从其父left获得新的.wrapper值,即0px 在将鼠标悬停.wrapper时,应使用其父.header中的left值计算.wrapper的左侧位置,因为left没有给出明确的.header:hover 1}}。

我认为这是由于Firefox中的错误。如果您使用 Firebug 默认开发人员工具激活.wrapper伪类.header,则put URL "http://apihost.com/document.html?name=value"的左侧位置会保持为在Chrome中(但突然)。

在Firefox 49.0.2和Chrome 54.0.2840.71上进行了测试