位置:固定元素位置:相对父级。哪个浏览器呈现正确?

时间:2015-02-18 04:58:59

标签: html css css3 css-position

我看到固定位置元素在相对定位的父级中的行为方式存在差异。根据我在网上找到的文档,FireFox和Chrome应该将元素固定到视口而不是父视图。但是,我发现如果我没有在固定元素上指定左/右值,它表现为静态和固定之间的某种混合,在某种意义上它是垂直固定到视口,但移动好像它是父元素中的静态元素。我无法找到围绕这些条件的任何官方/受尊敬的文档。他们基本上都陈述了如下内容:

  

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

Source

另一方面,

Safari似乎渲染它,因为它被描述为纯粹固定到视口的地方,无论我是否将父元素设置为相对而没有定义任何顶部/右侧/底部/左侧属性。如果你有机会通过点击从左边-100像素的青色div来尝试在Safari中试试。黄色条将固定在视口中:

http://jsfiddle.net/bbL8Lh4r/2/

那么哪个浏览器正确呈现这个?我的所有浏览器都已更新到最新版本。起初我认为Safari只是通过阅读文档才是正确的,但FireFox和Chrome都有相同的不同视图,它们似乎是静态和固定之间的混合。


HTML

<body>
    <aside>
        Blah
    </aside>

    <div class="container">
        <div class="nav">
            BLARGH
        </div>
    </div>
</body>

CSS

body,
aside,
.container,
.nav {
    margin:0;
    padding:0;
}

aside {
    background:red;
    width:30%;
    height:800px;
    float:left;
}

.container {
    position:relative;
    height:800px;
    width:70%;
    background:teal;
    float:right;
}

.container.stickied {
    left:-100px;
}

.container .nav {
    position:fixed;
    background:yellow;
    width:inherit;
}

2 个答案:

答案 0 :(得分:13)

这似乎是一个有趣的案例。让我们深入了解规范,了解正在发生的事情。


TL; DR: W3规范在此领域非常模糊/未定义,但似乎所有浏览器偏离规范,或者至少,它们是决定细节未定义。但是,四个主流浏览器(Firefox,Chrome,IE和Opera)的统一在于它们似乎都以相同的方式偏离规范 。 Safari绝对是这里的奇怪人物。


这就是CSS2.1规范在Chapter 9: Visual formatting model中所说的内容:

  
      
  1. 9.1.2 Containing blocks - 在CSS 2.1中,根据称为包含块的矩形框的边缘计算许多框位置和大小。通常,生成的框用作包含后代框的块;我们说一个盒子&#34;建立&#34;它的后代的包含块。短语&#34;包含块&#34;意味着&#34;盒子所在的容纳块,&#34;不是它产生的那个。
  2.   

这只是定义了包含块的内容。

  
      
  1. 9.3 Positioning Schemes - 绝对定位:在绝对定位模型中,完全从正常流中移除一个框,并为相应的块指定一个位置。
  2.   

这表示绝对定位元素相对于包含块定位。

  
      
  1. 9.6 Absolute Positioning - 在绝对定位模型中,框相对于其包含块显式偏移。 [...]此规范中对绝对定位元素(或其框)的引用意味着元素的position属性具有值absolute或{ {1}}。
  2.   

这表示绝对定位元素包含fixed元素以及position:fixed;元素。

  
      
  1. 9.6.1 Fixed Positioning - 固定定位是绝对定位的子类别。唯一的区别是,对于固定位置框,包含块由视口建立。
  2.   

这表示position: absolute;元素具有视口(嗯,不是字面上的视口,而是具有与视口相同的尺寸和位置的框)作为其包含框。稍后将通过 10.1 Definition of containing block

中的规范对此进行备份
  

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

建立

(如果您不熟悉视口的内容,那么它就是屏幕上的窗口或其他查看区域,用户可通过该区域查看文档&#34;。视口的尺寸是初始包含块的基础。整个HTML内容(position: fixed;<html>等)都位于视口定义的初始包含块中。)

因此,应用了<body>的{​​{1}}元素应该包含一个等于视口的包含块,或者包含块


现在确定<div class="nav">元素属性的第一步已经完成,我们可以确定浏览器的行为方式。

CSS2.1规范有这样说:

  
      
  1. 9.7 Relationships between 'display', 'position', and 'float' - 否则,如果&#39;位置&#39;有绝对的价值&#39;或者&#39;固定&#39;,该框绝对定位,计算值为&#39;浮动&#39;是&#39;无&#39;,并根据下表设置显示。盒子的位置将由顶部&#39;右边&#39;底部&#39;底部确定。并且&#39;离开&#39;属性和包含块的框。
  2.   

这基本上告诉我们,对于绝对定位的元素position: fixed;.nav),忽略任何position: fixed;属性,{{1} } elements(以及其他)设置为position: absolute;,并且元素根据其float<div>display: block;和/或{{的框偏移值定位1}}与初始包含块(视口)结合使用。

  
      
  1. 9.3.2 Box offsets: 'top', 'right', 'bottom', 'left' - 如果一个元素的位置是&#39; property的值不是&#39; static&#39;。定位元素生成定位框,根据四个属性布局:顶部,右侧,底部,左侧。
  2.   

这只是重申了top应根据其盒子偏移定位的事实。

虽然它在几个地方说如果两个相反的偏移值是right,那么它们被设置为零,CSS2.1似乎没有指定如何用两个{定位元素的情况{1}}和bottom,值为零。但是, CSS Box Alignment Module Level 3 确实提到该值设置为&#34; start&#34;,其定义为:

  

将对齐主体与对齐容器的起始边缘齐平对齐。

这应该意味着元素位于包含块的左上角,对于left元素,它应该与视口相同。但是,我们可以看到,对于所有主流浏览器,情况并非如此。主要浏览器的似乎是按照规范的指示将<div class="nav">包含块设置为视口的块。相反,它们的行为似乎在autoleft之间的行为应该相同。

总而言之,当您在规范中使用这么多证据时,答案很明确:right元素应该有一个包含在视口中的包含块。同样清楚的是,供应商都决定以自己的方式填写模型的一个模糊部分,与此声明相冲突或完全无视此声明。最有可能发生的事情是,一个浏览器实现了他们的解释(IE7是第一个支持position: fixed;,我相信,不久之后是Firefox 2.0),其余部分随之而来。

答案 1 :(得分:2)

阅读W3C规范,我会说Chrome / FF中的行为实际上是正确的:

Fixed Positioning

  

框的位置是根据&#34;绝对&#34;计算的。模型,但另外,该框是相对于某些参考固定的。

相对于包含块的绝对模型位置:

Absolute Positioning

  

使用顶部,右侧,底部和左侧属性指定框的位置(可能还有大小)。这些属性指定相对于包含块的框的偏移量。

编辑:对于固定位置元素,containing block被定义为视口:

  

如果元素位于:fixed&#39;,则在连续媒体的情况下由视口建立包含块

但是,如果所有定位属性都设置为auto,我无法找到确切的auto应该导致的任何定义。因此,父级&#39; s如果没有给出其他位置,position定义固定元素的初始位置。此外,按指定滚动时,元素相对于视口保持固定。如果父母移动,固定元素应该随之移动它的初始位置;如果您更改left属性,则与您希望它移动的相同。

如果使用其父级移动块是不正确的,那么首先根据该父级定位它是不正确的。唯一的选择是将其放置在视口的左上角,以获取auto的属性。如果是这种情况,所有浏览器都会实现规范错误,Safari只会有一个错误且不一致的实现。

值得注意的是,无论父元素是否相对定位,都会出现展示行为。