位置:当不指定左/上/右/下时固定-在FF/IE中期望的结果,但在Safari中没有

时间:2021-12-10 15:02:20

Sorry to have to ask yet another position:fixed related question, but reading through various other questions and forum threads hasn't helped me with this one.

很抱歉又问了一个问题:固定的相关问题,但是阅读其他的问题和论坛的帖子并没有帮我解决这个问题。

The code that follows is a simplified demonstration of how I have been using position:fixed in a project to date. My original (mis)understanding of position:fixed is that it initially fixes relative to the first positioned parent container, and thereafter remains in that position regardless of viewport scroll position. I now realise that is wrong: in fact, position:fixed positions relative to the outermost container (i.e. the html tag) and position:absolute positions relative to the first parent container that has a position other than static.

下面的代码是我如何使用position的简化演示:固定在一个项目中。我对位置的最初理解(错误)是:fixed最初是相对于第一个定位的父容器进行修复,然后不管viewport滚动位置如何,它都保持在这个位置。我现在意识到这是错误的:事实上,位置:相对于最外层容器(即html标记)的固定位置,以及位置:相对于具有非静态位置的第一个父容器的绝对位置。

Reading through various other questions on SO, I realise that the effect I was trying to achieve using position:fixed is one that many other people have tried to, but then realised is not possible with just CSS: That is, to position an element relative to a container, but then have it stay where it is relative to viewport when the page is scrolled.

阅读其他各种问题,我意识到,我试图影响实现使用位置:固定,其他许多人尝试过,但后来意识到不可能只有CSS:也就是说,一个元素位置相对于一个容器,然后呆在它是相对于视窗当滚动页。

What confuses me though is that the above is exactly what I seemed to have achieved - at least on FF and IE8. With the code example below, the "fixed right pane content" is initially positioned to the right of the red "centre scrollable content" box, and is vertically level with the top of the centre content. The centre content can be scrolled, but the right-hand content stays where it is, as if it initially positions statically in normal document flow but thereafter remains fixed to the viewport.

但让我困惑的是,上面的内容正是我所取得的成果——至少在FF和IE8上是如此。在下面的代码示例中,“固定右窗格内容”最初定位在红色的“中心可滚动内容”框的右侧,并与中心内容的顶部垂直。中心内容可以被滚动,但是右边的内容仍然保留在原来的位置,就好像它最初在正常的文档流中静态地定位,但是之后仍然固定在viewport。

I now realise that this appears to 'work' in IE8 and FF simply because I have not specified top/bottom/left/right attributes to the fixed element. If I do, then I realise that the fixed element immediately becomes positioned relative to the viewport.

我现在意识到,这在IE8和FF中似乎是有效的,仅仅是因为我没有为固定元素指定顶部/底部/左/右属性。如果我这样做了,那么我就会意识到,这个固定的元素会立即被定位到相对于viewport的位置。

I had assumed - perhaps dangerously - until now that if relative positions aren't specified, then position:fixed will by default place that element where it would normally be statically placed. At least FF and IE8 seem to be doing just that.

直到现在,我还假设——可能是危险的——如果没有指定相对位置,那么position:fixed will默认地将该元素放置在通常会被静态放置的位置。至少FF和IE8似乎就是这么做的。

Testing in Safari, however, shows that Safari seems to place that fixed element to the left of its container. In other words, without positioning, my position:fixed element is neither where it would be when statically placed, nor is it positioned at 0,0 relative to the viewport.

然而,在Safari中的测试显示,Safari似乎把这个固定的元素放在容器的左边。换句话说,没有定位,我的位置:fixed元素既不是静态放置时的位置,也不是相对于viewport在0,0处的位置。

Have I been relying on very poorly defined behaviour to date, and am I best resorting to a JavaScript solution after all to achieve this fixed positioning? Or, is this behaviour well-defined for IE / FF; and can someone explain the logic behind Safari's placement please?

到目前为止,我是否一直依赖于定义非常糟糕的行为,我是否最好还是求助于JavaScript解决方案来实现这个固定的定位?或者,这种行为是否定义为IE / FF;谁能解释一下Safari的布局背后的逻辑吗?

<style type="text/css">
  #content-centre {
    margin: 0 auto;
    width: 900px;
  }
  
  #header {
    height: 55px;
    position: fixed;
    top: 0;
    width: 990px;
  }
  
  #left-pane {
    position: fixed;
    top: 12px;
    border: 1px green solid;
  }
  
  #main-pane {
    left: 200px;
    position: relative;
    top: 66px;
    width: 760px;
    border: 1px yellow solid;
  }
  
  #container-1 {
    border-top: 1px solid #FFFFFF;
    float: right;
    min-width: 130px;
    padding-left: 20px;
    border: 1px blue solid;
  }
  
  #container-0 {
    margin-right: 20px;
    min-height: 470px;
    overflow: auto;
    padding: 10px 0;
    position: relative;
    border: 1px red solid;
  }
  
  .side-info-list-fixer {
    position: fixed;
  }
</style>

<div id="content-centre">

  <div id="header">
  </div>

  <div id="left-pane">
    Fixed left pane content
  </div>


  <div id="main-pane">
    <div id="page-module-containers">

      <div id="container-1">
        <div class="side-info-list-fixer"> Fixed right pane content </div>
      </div>

      <div id="container-0">
        <p>Centre scrollable content</p>
        <p>Centre scrollable content</p>
        <p>Centre scrollable content</p>
        <p>Centre scrollable content</p>
        <p>Centre scrollable content</p>
        <p>Centre scrollable content</p>
        <p>Centre scrollable content</p>
        <p>Centre scrollable content</p>
        <p>Centre scrollable content</p>
        <p>Centre scrollable content</p>
        <p>Centre scrollable content</p>
        <p>Centre scrollable content</p>
        <p>Centre scrollable content</p>
        <p>Centre scrollable content</p>
        <p>Centre scrollable content</p>
        <p>Centre scrollable content</p>
        <p>Centre scrollable content</p>
        <p>Centre scrollable content</p>
        <p>Centre scrollable content</p>
        <p>Centre scrollable content</p>
        <p>Centre scrollable content</p>
        <p>Centre scrollable content</p>
        <p>Centre scrollable content</p>
        <p>Centre scrollable content</p>
        <p>Centre scrollable content</p>
        <p>Centre scrollable content</p>
        <p>Centre scrollable content</p>
        <p>Centre scrollable content</p>
        <p>Centre scrollable content</p>
        <p>Centre scrollable content</p>
        <p>Centre scrollable content</p>
        <p>Centre scrollable content</p>
      </div>

    </div>
  </div>

</div>

3 个解决方案

#1


17  

I believe the answer you're looking for is as follows...

我相信你在寻找的答案如下……

The position of an element does not default to 0,0. It's position is set by default relative to the containing element, therefor in your example, "#container-1" has a padding-left: 20px whereas the rest of the padding is set to 0 making the "default" position of the element 20px left of the wall of #container-1 and the top is 0px from the top of #container-1.

元素的位置不默认为0,0。它的位置设置默认情况下相对于包含元素,因此在你的例子中,“#容器1”有一个padding-left:20 px而剩下的填充设置为0的“默认”元素的位置20 px左#容器1和墙的顶部是0 px的#容器1。

The default position of this element by default and my viewport not scrolled would be 63px from the top and the left is obviously dependent on the width of your browser. However, if you do not override the top and left, they are already defined by the rendering engine as the top:63px, left:893px.

默认情况下,这个元素的默认位置和我的viewport没有展开,从顶部到左边是63px,这显然取决于浏览器的宽度。但是,如果不覆盖顶部和左侧,则呈现引擎已经将它们定义为顶部:63px,左侧:893px。

Then on window resize, that position is adjusted to reflect the position based on the viewport so as you scroll down the position is changed to keep it fixed.

然后,在窗口调整大小时,该位置将根据viewport进行调整,以便当您向下滚动时,位置将被更改为保持不变。

So, by simply adding "position:fixed;" your properties would (as far as the browser is concerned) be as follows:

因此,只需添加“position:fixed”,您的属性(就浏览器而言)将如下:

position:fixed;
top:63px; // defined by default during browser rendering in some browsers (based on scroll position on load)
left:893px; // defined by default during browser rendering in some browsers (based on scroll position / width of browser at time of load)

Also, IE6 and the likes, do not support position:fixed at all. http://fiddle.jshell.net/uaE4g/4/show/

另外,IE6和类似的软件不支持立场:完全固定。http://fiddle.jshell.net/uaE4g/4/show/

I hope this helps!

我希望这可以帮助!

#2


0  

I'm seeing similar results in safari 5, and not in safari 6.

我在safari 5上看到了类似的结果,但在safari 6上没有。

across browsers, it seems to work like this:

在不同的浏览器中,它似乎是这样工作的:

if one of the position's properties is not defined on a fixed element, the initial value of that property is as the same as if the object was static. it seems.

如果位置的某个属性没有在固定的元素上定义,则该属性的初始值与该对象是静态的一样。似乎。

after page load, it stays behaving as if it was static. so if i fix an element vertically, but not horizontally, i can scroll up and down and the element remains fixed, but if i scroll sideways the elements scrolls along with the page.

在页面加载之后,它保持静态的状态。所以如果我垂直地固定一个元素,而不是水平地,我可以上下滚动元素保持不变,但是如果我横向滚动元素和页面一起滚动。

but in safari 5, if the element is within an container that has positioning, it seems to behave as you describe: the initial value is the same as if it were static, but afterwards it remains fixed on that position.

但是在safari 5中,如果元素位于有位置的容器中,那么它的行为似乎与您描述的一样:初始值与它是静态的一样,但是之后它仍然固定在那个位置上。

your 'side-info-list-fixer' is within 'main-pane', which has position:relative. take that off and you might see the same behaviour as in safari 6 and most other browsers.

你的“侧边信息列表”在“主窗格”中,它的位置是:相对的。去掉它,您可能会看到与safari 6和大多数其他浏览器相同的行为。

i dont know whats correct and wether you should depend on these features ...

我不知道什么是对的,你是否应该依赖这些特征……

$2c, *-pike

2美元c *派克

#3


0  

I had the same requirement, to position an element fixed at it's natural (default) static position with relation to the viewport. I ended up using this simple jQuery function.

我有相同的要求,将一个元素固定在它的自然(默认)静态位置与视口之间。最后我使用了这个简单的jQuery函数。

function SetFixedPositioning(element) {
    var currentOffset = $(element).offset();
    $(element).css("position", "fixed");
    $(element).offset(currentOffset);           
}

Use it like this:

使用它是这样的:

SetFixedPosition($("#element-to-position"));

My use case was a second level navigation menu that flowed into the document, then was fixed at that position.

我的用例是一个二级导航菜单流入文档,然后被固定在那个位置。

#1


17  

I believe the answer you're looking for is as follows...

我相信你在寻找的答案如下……

The position of an element does not default to 0,0. It's position is set by default relative to the containing element, therefor in your example, "#container-1" has a padding-left: 20px whereas the rest of the padding is set to 0 making the "default" position of the element 20px left of the wall of #container-1 and the top is 0px from the top of #container-1.

元素的位置不默认为0,0。它的位置设置默认情况下相对于包含元素,因此在你的例子中,“#容器1”有一个padding-left:20 px而剩下的填充设置为0的“默认”元素的位置20 px左#容器1和墙的顶部是0 px的#容器1。

The default position of this element by default and my viewport not scrolled would be 63px from the top and the left is obviously dependent on the width of your browser. However, if you do not override the top and left, they are already defined by the rendering engine as the top:63px, left:893px.

默认情况下,这个元素的默认位置和我的viewport没有展开,从顶部到左边是63px,这显然取决于浏览器的宽度。但是,如果不覆盖顶部和左侧,则呈现引擎已经将它们定义为顶部:63px,左侧:893px。

Then on window resize, that position is adjusted to reflect the position based on the viewport so as you scroll down the position is changed to keep it fixed.

然后,在窗口调整大小时,该位置将根据viewport进行调整,以便当您向下滚动时,位置将被更改为保持不变。

So, by simply adding "position:fixed;" your properties would (as far as the browser is concerned) be as follows:

因此,只需添加“position:fixed”,您的属性(就浏览器而言)将如下:

position:fixed;
top:63px; // defined by default during browser rendering in some browsers (based on scroll position on load)
left:893px; // defined by default during browser rendering in some browsers (based on scroll position / width of browser at time of load)

Also, IE6 and the likes, do not support position:fixed at all. http://fiddle.jshell.net/uaE4g/4/show/

另外,IE6和类似的软件不支持立场:完全固定。http://fiddle.jshell.net/uaE4g/4/show/

I hope this helps!

我希望这可以帮助!

#2


0  

I'm seeing similar results in safari 5, and not in safari 6.

我在safari 5上看到了类似的结果,但在safari 6上没有。

across browsers, it seems to work like this:

在不同的浏览器中,它似乎是这样工作的:

if one of the position's properties is not defined on a fixed element, the initial value of that property is as the same as if the object was static. it seems.

如果位置的某个属性没有在固定的元素上定义,则该属性的初始值与该对象是静态的一样。似乎。

after page load, it stays behaving as if it was static. so if i fix an element vertically, but not horizontally, i can scroll up and down and the element remains fixed, but if i scroll sideways the elements scrolls along with the page.

在页面加载之后,它保持静态的状态。所以如果我垂直地固定一个元素,而不是水平地,我可以上下滚动元素保持不变,但是如果我横向滚动元素和页面一起滚动。

but in safari 5, if the element is within an container that has positioning, it seems to behave as you describe: the initial value is the same as if it were static, but afterwards it remains fixed on that position.

但是在safari 5中,如果元素位于有位置的容器中,那么它的行为似乎与您描述的一样:初始值与它是静态的一样,但是之后它仍然固定在那个位置上。

your 'side-info-list-fixer' is within 'main-pane', which has position:relative. take that off and you might see the same behaviour as in safari 6 and most other browsers.

你的“侧边信息列表”在“主窗格”中,它的位置是:相对的。去掉它,您可能会看到与safari 6和大多数其他浏览器相同的行为。

i dont know whats correct and wether you should depend on these features ...

我不知道什么是对的,你是否应该依赖这些特征……

$2c, *-pike

2美元c *派克

#3


0  

I had the same requirement, to position an element fixed at it's natural (default) static position with relation to the viewport. I ended up using this simple jQuery function.

我有相同的要求,将一个元素固定在它的自然(默认)静态位置与视口之间。最后我使用了这个简单的jQuery函数。

function SetFixedPositioning(element) {
    var currentOffset = $(element).offset();
    $(element).css("position", "fixed");
    $(element).offset(currentOffset);           
}

Use it like this:

使用它是这样的:

SetFixedPosition($("#element-to-position"));

My use case was a second level navigation menu that flowed into the document, then was fixed at that position.

我的用例是一个二级导航菜单流入文档,然后被固定在那个位置。