Position:fixed 个元素在 position:relative 个父元素中。哪个浏览器正确呈现?
Position:fixed element within a position:relative parent. Which browser renders correctly?
我发现固定位置元素在相对定位的父项中的行为方式存在差异。根据我在网上找到的文档,FireFox 和 Chrome 应该将元素固定到视口而不是父元素。但是,我发现如果我没有在固定元素上指定 left/right 值,它的行为会混合静态和固定,因为它垂直固定在视口上,但就像移动一样它是父元素中的静态元素。我找不到关于这些条件的任何 official/respected 文档。他们基本上都是这样说的:
Fixed Positioning
Do not leave space for the element. Instead, position it at a specified position relative to the screen's viewport and don't move it when scrolled. When printing, position it at that fixed position on every page.
另一方面,Safari 似乎按照所描述的那样渲染它,它完全固定在视口上,无论我是否将父元素设置为 relative 而没有定义任何 top/right/bottom/left 属性。如果有机会,请在 Safari 中尝试一下,方法是单击蓝绿色 div,它位于距左侧 -100 像素的位置。黄色条将固定在视口上:
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;
}
这似乎是一个有趣的案例。让我们深入研究规范以了解发生了什么。
TL;DR: W3 规范在这方面很关键 vague/undefined,但似乎 所有浏览器 都有偏差从规范中,或者至少,他们在细节未定义的地方做出了决定。然而,四种主要浏览器(Firefox、Chrome、IE 和 Opera)的统一之处在于它们似乎都以同样的方式偏离规范。 Safari 绝对是这里的怪人。
这是 CSS2.1 规范在 Chapter 9: Visual formatting model 中必须说的:
- 9.1.2 Containing blocks - In CSS 2.1, many box positions and sizes are calculated with respect to the edges of a rectangular box called a containing block. In general, generated boxes act as containing blocks for descendant boxes; we say that a box "establishes" the containing block for its descendants. The phrase "a box's containing block" means "the containing block in which the box lives," not the one it generates.
这只是定义了包含块是什么。
- 9.3 Positioning Schemes - Absolute positioning: In the absolute positioning model, a box is removed from the normal flow entirely and assigned a position with respect to a containing block.
这表示 绝对定位的元素 是相对于包含块定位的。
- 9.6 Absolute Positioning - In the absolute positioning model, a box is explicitly offset with respect to its containing block. [...] References in this specification to an absolutely positioned element (or its box) imply that the element's
position
property has the value absolute
or fixed
.
这表示 绝对定位元素 包括 position:fixed;
元素以及 position: absolute;
元素。
- 9.6.1 Fixed Positioning - Fixed positioning is a subcategory of absolute positioning. The only difference is that for a fixed position box, the containing block is established by the viewport.
这表示 position: fixed;
元素具有视口(好吧,不是字面上的视口,而是与视口具有相同尺寸和位置的框)作为它们的包含框。 10.1 Definition of containing block 中的规范稍后对此进行了支持:
If the element has 'position: fixed', the containing block is established by the viewport [...]
(如果您不熟悉视口是什么,它是 "a window or other viewing area on the screen through which users consult a document"。视口的尺寸是 初始包含块 的基础。整个您的 HTML 内容(<html>
、<body>
等)驻留在由视口定义的初始包含块中。)
因此,应用了 position: fixed;
的 <div class="nav">
元素应该有一个等于视口的包含块,或者 初始包含块 。
现在确定 .nav
元素属性的第一步已经完成,我们可以确定浏览器的行为方式。
CSS2.1 规范是这样说的:
- 9.7 Relationships between 'display', 'position', and 'float' - Otherwise, if 'position' has the value 'absolute' or 'fixed', the box is absolutely positioned, the computed value of 'float' is 'none', and display is set according to the table below. The position of the box will be determined by the 'top', 'right', 'bottom' and 'left' properties and the box's containing block.
这基本上是在告诉我们,对于绝对定位的元素(position: fixed;
或position: absolute;
),任何float
属性都会被忽略, <div>
元素(以及其他)设置为 display: block;
,并且元素根据其框偏移值 top
、right
、bottom,
定位and/or left
结合初始包含块(视口)。
- 9.3.2 Box offsets: 'top', 'right', 'bottom', 'left' - An element is said to be positioned if its 'position' property has a value other than 'static'. Positioned elements generate positioned boxes, laid out according to four properties: top, right, bottom, left.
这只是重申了 <div class="nav">
应该根据其框偏移定位的事实。
虽然好几个地方都说如果两个相反的offset值是auto
,那么就置零,CSS2.1好像没有具体说明怎么定位的情况left
和 right
值为零的元素。 CSS Box Alignment Module Level 3,但是,确实提到了将值设置为"start",其定义为:
Aligns the alignment subject to be flush with the alignment container’s start edge.
这应该意味着元素位于包含块的左上角,对于 position: fixed;
元素,它应该与视口相同。但是,我们可以看到,对于所有主流浏览器来说,情况并非如此。 None 的主要浏览器似乎按照规范的指示将 position: fixed;
的包含块设置为视口的包含块。相反,它们都表现得好像 position: fixed;
和 position: absolute;
之间的行为应该相同。
总而言之,当您在规范自己的话中有这么多证据时,答案很明确:position: fixed;
元素应该有一个包含块设置为视口。同样清楚的是,供应商都决定以他们自己的方式填写规范中的模糊部分,与此声明冲突或完全忽略此声明。最有可能发生的是一个浏览器实现了它们的解释(我相信 IE7 是第一个支持 position: fixed;
,紧随其后的是 Firefox 2.0),其余的紧随其后。
阅读 W3C 规范,我会说 Chrome/FF 中的行为实际上是正确的:
The box's position is calculated according to the "absolute" model, but in addition, the box is fixed with respect to some reference.
模型相对于包含块的绝对位置:
The box's position (and possibly size) is specified with the top, right, bottom, and left properties. These properties specify offsets with respect to the box's containing block.
编辑:对于固定位置元素,containing block 定义为视口:
If the element has 'positioned: fixed', the containing block is established by the viewport in the case of continuous media
但是,在所有定位属性都设置为 auto
的情况下,我无法找到 auto
应该产生的确切结果的任何定义。因此,父级的位置定义了初始位置如果没有给出其他位置,则固定元素的位置。此外,如指定的那样,元素在滚动时确实相对于视口保持固定。如果父元素移动,则固定元素应随其初始位置一起移动;如果您更改 left
属性.
,则与您期望它移动的相同
如果将方块与其父方块一起移动是不正确的,那么首先基于该父方块定位方块也是不正确的。唯一的选择是将其放置在 auto
属性视口的左上角。如果是这种情况,所有浏览器都错误地实现了规范,Safari 只是有一个错误且不一致的实现。
值得注意的是,无论父元素是否相对定位,都会出现表现出的行为。
我发现固定位置元素在相对定位的父项中的行为方式存在差异。根据我在网上找到的文档,FireFox 和 Chrome 应该将元素固定到视口而不是父元素。但是,我发现如果我没有在固定元素上指定 left/right 值,它的行为会混合静态和固定,因为它垂直固定在视口上,但就像移动一样它是父元素中的静态元素。我找不到关于这些条件的任何 official/respected 文档。他们基本上都是这样说的:
Fixed Positioning Do not leave space for the element. Instead, position it at a specified position relative to the screen's viewport and don't move it when scrolled. When printing, position it at that fixed position on every page.
另一方面,Safari 似乎按照所描述的那样渲染它,它完全固定在视口上,无论我是否将父元素设置为 relative 而没有定义任何 top/right/bottom/left 属性。如果有机会,请在 Safari 中尝试一下,方法是单击蓝绿色 div,它位于距左侧 -100 像素的位置。黄色条将固定在视口上:
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;
}
这似乎是一个有趣的案例。让我们深入研究规范以了解发生了什么。
TL;DR: W3 规范在这方面很关键 vague/undefined,但似乎 所有浏览器 都有偏差从规范中,或者至少,他们在细节未定义的地方做出了决定。然而,四种主要浏览器(Firefox、Chrome、IE 和 Opera)的统一之处在于它们似乎都以同样的方式偏离规范。 Safari 绝对是这里的怪人。
这是 CSS2.1 规范在 Chapter 9: Visual formatting model 中必须说的:
- 9.1.2 Containing blocks - In CSS 2.1, many box positions and sizes are calculated with respect to the edges of a rectangular box called a containing block. In general, generated boxes act as containing blocks for descendant boxes; we say that a box "establishes" the containing block for its descendants. The phrase "a box's containing block" means "the containing block in which the box lives," not the one it generates.
这只是定义了包含块是什么。
- 9.3 Positioning Schemes - Absolute positioning: In the absolute positioning model, a box is removed from the normal flow entirely and assigned a position with respect to a containing block.
这表示 绝对定位的元素 是相对于包含块定位的。
- 9.6 Absolute Positioning - In the absolute positioning model, a box is explicitly offset with respect to its containing block. [...] References in this specification to an absolutely positioned element (or its box) imply that the element's
position
property has the valueabsolute
orfixed
.
这表示 绝对定位元素 包括 position:fixed;
元素以及 position: absolute;
元素。
- 9.6.1 Fixed Positioning - Fixed positioning is a subcategory of absolute positioning. The only difference is that for a fixed position box, the containing block is established by the viewport.
这表示 position: fixed;
元素具有视口(好吧,不是字面上的视口,而是与视口具有相同尺寸和位置的框)作为它们的包含框。 10.1 Definition of containing block 中的规范稍后对此进行了支持:
If the element has 'position: fixed', the containing block is established by the viewport [...]
(如果您不熟悉视口是什么,它是 "a window or other viewing area on the screen through which users consult a document"。视口的尺寸是 初始包含块 的基础。整个您的 HTML 内容(<html>
、<body>
等)驻留在由视口定义的初始包含块中。)
因此,应用了 position: fixed;
的 <div class="nav">
元素应该有一个等于视口的包含块,或者 初始包含块 。
现在确定 .nav
元素属性的第一步已经完成,我们可以确定浏览器的行为方式。
CSS2.1 规范是这样说的:
- 9.7 Relationships between 'display', 'position', and 'float' - Otherwise, if 'position' has the value 'absolute' or 'fixed', the box is absolutely positioned, the computed value of 'float' is 'none', and display is set according to the table below. The position of the box will be determined by the 'top', 'right', 'bottom' and 'left' properties and the box's containing block.
这基本上是在告诉我们,对于绝对定位的元素(position: fixed;
或position: absolute;
),任何float
属性都会被忽略, <div>
元素(以及其他)设置为 display: block;
,并且元素根据其框偏移值 top
、right
、bottom,
定位and/or left
结合初始包含块(视口)。
- 9.3.2 Box offsets: 'top', 'right', 'bottom', 'left' - An element is said to be positioned if its 'position' property has a value other than 'static'. Positioned elements generate positioned boxes, laid out according to four properties: top, right, bottom, left.
这只是重申了 <div class="nav">
应该根据其框偏移定位的事实。
虽然好几个地方都说如果两个相反的offset值是auto
,那么就置零,CSS2.1好像没有具体说明怎么定位的情况left
和 right
值为零的元素。 CSS Box Alignment Module Level 3,但是,确实提到了将值设置为"start",其定义为:
Aligns the alignment subject to be flush with the alignment container’s start edge.
这应该意味着元素位于包含块的左上角,对于 position: fixed;
元素,它应该与视口相同。但是,我们可以看到,对于所有主流浏览器来说,情况并非如此。 None 的主要浏览器似乎按照规范的指示将 position: fixed;
的包含块设置为视口的包含块。相反,它们都表现得好像 position: fixed;
和 position: absolute;
之间的行为应该相同。
总而言之,当您在规范自己的话中有这么多证据时,答案很明确:position: fixed;
元素应该有一个包含块设置为视口。同样清楚的是,供应商都决定以他们自己的方式填写规范中的模糊部分,与此声明冲突或完全忽略此声明。最有可能发生的是一个浏览器实现了它们的解释(我相信 IE7 是第一个支持 position: fixed;
,紧随其后的是 Firefox 2.0),其余的紧随其后。
阅读 W3C 规范,我会说 Chrome/FF 中的行为实际上是正确的:
The box's position is calculated according to the "absolute" model, but in addition, the box is fixed with respect to some reference.
模型相对于包含块的绝对位置:
The box's position (and possibly size) is specified with the top, right, bottom, and left properties. These properties specify offsets with respect to the box's containing block.
编辑:对于固定位置元素,containing block 定义为视口:
If the element has 'positioned: fixed', the containing block is established by the viewport in the case of continuous media
但是,在所有定位属性都设置为 auto
的情况下,我无法找到 auto
应该产生的确切结果的任何定义。因此,父级的位置定义了初始位置如果没有给出其他位置,则固定元素的位置。此外,如指定的那样,元素在滚动时确实相对于视口保持固定。如果父元素移动,则固定元素应随其初始位置一起移动;如果您更改 left
属性.
如果将方块与其父方块一起移动是不正确的,那么首先基于该父方块定位方块也是不正确的。唯一的选择是将其放置在 auto
属性视口的左上角。如果是这种情况,所有浏览器都错误地实现了规范,Safari 只是有一个错误且不一致的实现。
值得注意的是,无论父元素是否相对定位,都会出现表现出的行为。