位置:一个位置内的固定元素:相对父。哪个浏览器呈现正确? [英] Position:fixed element within a position:relative parent. Which browser renders correctly?

查看:81
本文介绍了位置:一个位置内的固定元素:相对父。哪个浏览器呈现正确?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我看到固定位置元素在相对定位的父级中如何行为的差异。根据我在线找到的文档,FireFox和Chrome应该将元素修复到视口,而不是父。然而,我发现,如果我不在固定元素上指定一个左/右值,它的行为在静态和固定之间的一种混合,在某种意义上,它是垂直固定的视口,但移动,就像它父元素中的静态元素。我找不到任何官方/尊重的文档,围绕这些条件。它们都基本上描述如下:


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




另一方面,Safari似乎将其它描述了它是固定的纯粹的视口,无论我设置一个父元素为相对没有定义任何top / right / bottom / left属性。尝试在Safari中,如果你有一个机会,点击teal div它的位置从左边-100像素。黄色栏将保持固定在视口上:



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



那么哪个浏览器正确呈现这些内容呢?我所有的浏览器已更新到最新。起初我认为Safari是正确的阅读文档,但FireFox和Chrome都有相同的不同的视图,它似乎是一个静态和固定的混合。



< hr>

HTML

 < body& 
< aside>
Blah
< / aside>

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






CSS p>

  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规范在这方面非常模糊/未定义,似乎所有浏览器偏离规格,或至少,他们做出了一个决定,其中的细节未定义。但是,其中四个主要的浏览器(Firefox,Chrome,IE和Opera)是统一的,因为它们似乎都以同样的方式偏离了规范 =http://www.w3.org/TR/CSS2/visuren.html =noreferrer>第9章:视觉格式模型:



< blockquote>


  1. 9.1.2包含块 - 在CSS 2.1中,许多框位置和大小都是相对于称为包含块的矩形框的边缘计算的。通常,生成的框充当后代框的包含块;我们说一个框建立其后代的包含块。


这只是定义了包含块是什么。



    < 9.3定位计划 - 绝对定位:在绝对定位模型中,一个方框从正常流程中完全移除,并为包含块指定一个位置。


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



  1. 9.6绝对定位 - 在绝对定位模型中,一个框相对于其包含块显式偏移。 [...]本说明书中对绝对定位的元素(或其框)的引用意味着元素的 position 属性具有值绝对固定


这说明绝对定位的元素包括 position:fixed; 元素以及 :absolute; 元素。



  1. a href =http://www.w3.org/TR/CSS2/visuren.html#fixed-positioning =noreferrer> 9.6.1固定位置 - 固定位置是绝对定位的子类。唯一的区别是,对于固定位置框,包含块由视口确定。


这说明 position:fixed; 元素具有视口(嗯,不是字面上的视口,但是具有与视口相同的尺寸和位置的盒子) 。稍后将按照 10.1定义中的规范进行备份 : : :

如果元素有'position:fixed' viewport [...]


(如果你不熟悉视口是什么, 初始包含块的基础视口的尺寸是整个HTML内容(< html> < body> 等)驻留在由视口定义的此初始包含块中。)

因此,< div class =nav> 元素与 position:fixed; 到它应该有一个等于视口或初始包含块的块。






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



CSS2.1规范可以说:



  1. a href =http://www.w3.org/TR/CSS21/visuren.html#dis-pos-flo =noreferrer> 9.7'display','position'和'float'之间的关系 - 否则,如果'position'的值为'absolute'或'fixed',则该框绝对定位,'float'的计算值为'none',并根据下表。框的位置将由top,right,bottom和left属性和框的包含块确定。


这基本上告诉我们,对于绝对定位的元素 position:fixed; 或 position:absolute; ),any float 属性被忽略,< div> 元素(其他)设置为 display:block; 并且该元素根据 top right bottom ,和/或与初始包含块(视口)组合。



< blockquote>


  1. 9.3.2框偏移:'top','right','bottom','left' - 如果元素的'position'属性具有除静态之外的值。




p>这只是重申一个事实,< div class =nav> 应该根据其框偏移量。



虽然它在几个地方说,如果两个相反的偏移值是 auto ,然后它们设置为零,CSS2.1似乎没有指定如何定位具有 left right 值为零的元素的情况。 CSS框对齐模块级别3 ,但是提及的值设置为开始,定义为:


将对齐对象与对齐容器的起始边缘对齐。


这意味着元素位于包含块的左上角,对于 position :fixed; 元素,应该与视口相同。但是,我们可以看到对于所有主流浏览器,情况并非如此的主要浏览器似乎正在按照规范的要求将 position:fixed; 的包含块设置为视口的。相反,它们都在 position:fixed; position:absolute; 之间的行为应该是相同的。 / p>

总之,当你在规范自己的话中有这么多证据时,答案很清楚: position:fixed; 元素应该具有设置到视口的包含块。还有一点很清楚,供应商都决定以自己的方式填写规范的一个模糊的部分,与之冲突,或者直接忽略这个声明。最有可能发生的是一个浏览器实现了它们的解释(IE7是第一个支持 position:fixed; ,我相信,Firefox 2.0后很快)休息。


I am seeing a discrepancy in how fixed position elements behave within a relatively positioned parent. According to the docs I am finding online, FireFox and Chrome should fix the element to the viewport and not the parent. However, I am finding that if I do not specify a left/right value on a fixed element, it behaves in a sort of mix between static AND fixed, in the sense that it's fixed vertically to the viewport, but moves as if it were a static element within the parent element. I can't find any official/respected documentation surrounding these conditions. They all basically state something like the following:

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.

Source

Safari on the other hand, seems to render it as it is described where it's fixed purely to the viewport, no matter if I set a parent element to relative without any top/right/bottom/left properties defined. Try it out in Safari if you have a chance by clicking on the teal div which positions it -100 pixels from the left. The yellow bar will stay fixed to the viewport:

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

So which browser is rendering this correctly? All my browsers have been updated to the latest. At first I thought Safari was the right one just by reading the docs, but FireFox and Chrome both share the same different view where it seems to be a hybrid between static and fixed.


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

解决方案

This appears to be an interesting case. Let's take a deep dive into the specifications to find out what's going on.


TL;DR: The W3 specification is critically vague/undefined in this area, but it appears that all browsers deviate from the spec, or at least, they made a decision where details were undefined. However, four of the major browsers (Firefox, Chrome, IE, and Opera) are united in that they all seem to deviate from the spec in the same way. Safari is definitely the odd man out here.


This is what the CSS2.1 spec has to say in Chapter 9: Visual formatting model:

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

This just defines what a containing block is.

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

This says absolutely positioned elements are positioned with respect to a containing block.

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

This says absolutely positioned elements include position:fixed; elements as well as position: absolute; elements.

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

And this says position: fixed; elements have the Viewport (well, not literally the viewport, but a box with the same dimensions and positions as the viewport) as their containing box. This is backed up later by the spec in 10.1 Definition of containing block:

If the element has 'position: fixed', the containing block is established by the viewport [...]

(If you aren't familiar with what the viewport is, it is "a window or other viewing area on the screen through which users consult a document". The viewport's dimensions are the basis for the initial containing block. The entirety of your HTML content (<html>, <body>, etc.) resides within this initial containing block defined by the viewport.)

Therefore, the <div class="nav"> element with position: fixed; applied to it should have a containing block equal to the Viewport, or the initial containing block.


Now that the first step of determining the properties of the .nav element is complete, we can determine how the browsers are supposed to behave.

The CSS2.1 spec has this to say:

  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.

This is basically telling us that, for absolutely positioned elements (position: fixed; or position: absolute;), any float properties are ignored, that <div> elements (among others) are set to display: block;, and that the element is positioned according to its box offset values of top, right, bottom, and/or left in combination with the initial containing block (the viewport).

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

This just reaffirms the fact that <div class="nav"> should be positioned according to its box offsets.

Although it says in several places that if two opposing offset values are auto, then they are set to zero, CSS2.1 doesn't seem to specify the case for how to position elements with both left and right values of zero. CSS Box Alignment Module Level 3, however, does mention that the value is set to "start", which is defined as:

Aligns the alignment subject to be flush with the alignment container’s start edge.

This should mean the element is positioned at the top-left of the containing block, which, for position: fixed; elements, should be the same as the viewport. However, we can see that, for all major browsers, this is not the case. None of the major browsers seem to be setting the position: fixed;'s containing block to that of the viewport as instructed by the spec. Instead, they are all acting as if behavior should be identical between position: fixed; and position: absolute;.

In summation, when you have this much evidence in the spec's own words, the answer is clear: position: fixed; elements should have a containing block set to the viewport. What's also clear is that the vendors have all decided to fill-in a vague part of the spec in their own way, conflicting with, or outright ignoring this declaration. What is most likely to have happened is that one browser implemented their interpretation (IE7 was the first to support position: fixed;, I believe, followed shortly by Firefox 2.0) and the rest followed.

这篇关于位置:一个位置内的固定元素:相对父。哪个浏览器呈现正确?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆