CSS 固定位置但相对于容器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6794000/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 01:04:49  来源:igfitidea点击:

Fixed position but relative to container

csspositioncss-positionfixed

提问by Zach Nicodemous

I am trying to fix a divso it always sticks to the top of the screen, using:

我正在尝试修复 adiv以便它始终粘在屏幕顶部,使用:

position: fixed;
top: 0px;
right: 0px;

However, the divis inside a centered container. When I use position:fixedit fixes the divrelative to the browser window, such as it's up against the right side of the browser. Instead, it should be fixed relative to the container.

但是,div它位于居中的容器内。当我使用position:fixed它时,它会修复div相对于浏览器窗口的位置,例如它位于浏览器的右侧。相反,它应该相对于容器固定。

I know that position:absolutecan be used to fix an element relative to the div, but when you scroll down the page the element vanishes and doesn't stick to the top as with position:fixed.

我知道这position:absolute可用于修复相对于 的元素div,但是当您向下滚动页面时,该元素会消失并且不会像position:fixed.

Is there a hack or workaround to achieve this?

是否有黑客或解决方法来实现这一目标?

采纳答案by Joseph Marikle

Short answer: no.(It is now possible with CSS transform. See the edit below)

简短的回答:没有。(现在可以使用 CSS 转换。请参阅下面的编辑)

Long answer: The problem with using "fixed" positioning is that it takes the element out of flow. thus it can't be re-positioned relative to its parent because it's as if it didn't have one. If, however, the container is of a fixed, known width, you can use something like:

长答案:使用“固定”定位的问题在于它会将元素移出 flow。因此它不能相对于它的父级重新定位,因为它好像没有一个。但是,如果容器具有固定的已知宽度,则可以使用以下内容:

#fixedContainer {
  position: fixed;
  width: 600px;
  height: 200px;
  left: 50%;
  top: 0%;
  margin-left: -300px; /*half the width*/
}

http://jsfiddle.net/HFjU6/1/

http://jsfiddle.net/HFjU6/1/

Edit (03/2015):

编辑(03/2015):

This is outdated information. It is now possible to center content of an dynamic size (horizontally and vertically) with the help of the magic of CSS3 transform. The same principle applies, but instead of using margin to offset your container, you can use translateX(-50%). This doesn't work with the above margin trick because you don't know how much to offset it unless the width is fixed and you can't use relative values (like 50%) because it will be relative to the parent and not the element it's applied to. transformbehaves differently. Its values are relative to the element they are applied to. Thus, 50%for transformmeans half the width of the element, while 50%for margin is half of the parent's width. This is an IE9+ solution

这是过时的信息。现在可以借助 CSS3 转换的魔力将动态大小的内容(水平和垂直)居中。同样的原则适用,但不是使用边距来抵消您的容器,您可以使用translateX(-50%). 这不适用于上述边距技巧,因为除非宽度固定,否则您不知道偏移多少,并且您不能使用相对值(例如50%),因为它将相对于父元素而不是它所在的元素应用于。 transform行为不同。它的值是相对于它们所应用的元素而言的。因此,50%fortransform表示元素宽度的一半,而50%for margin 是父元素宽度的一半。这是一个IE9+的解决方案

Using similar code to the above example, I recreated the same scenario using completely dynamic width and height:

使用与上述示例类似的代码,我使用完全动态的宽度和高度重新创建了相同的场景:

.fixedContainer {
    background-color:#ddd;
    position: fixed;
    padding: 2em;
    left: 50%;
    top: 0%;
    transform: translateX(-50%);
}

If you want it to be centered, you can do that too:

如果你想让它居中,你也可以这样做:

.fixedContainer {
    background-color:#ddd;
    position: fixed;
    padding: 2em;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
}

Demos:

演示:

jsFiddle: Centered horizontally only
jsFiddle: Centered both horizontally and vertically
Original credit goes to user aaronk6for pointing it out to me in this answer

jsFiddle:仅水平居中
jsFiddle:水平和垂直居中
原始功劳归于用户aaronk6此答案中向我指出的

回答by Graeme Blackwood

Actually this is possible and the accepted answer only deals with centralising, which is straightforward enough. Also you really don't need to use JavaScript.

实际上这是可能的,并且公认的答案仅涉及集中化,这很简单。此外,您真的不需要使用 JavaScript。

This will let you deal with any scenario:

这将让您处理任何情况:

Set everything up as you would if you want to position: absolute inside a position: relative container, and then create a new fixed position div inside the div with position: absolute, but do notset its top and left properties. It will then be fixed wherever you want it, relative to the container.

设置好一切,你会如果你要的位置:位置内绝对的:相对的容器,然后创建一个DIV中一个新的固定位置格position: absolute,但没有设置它的顶部和左侧属性。然后它会被固定在你想要的地方,相对于容器。

For example:

例如:

/* Main site body */
.wrapper {
    width: 940px;
    margin: 0 auto;
    position: relative; /* Ensure absolute positioned child elements are relative to this*/
}

/* Absolute positioned wrapper for the element you want to fix position */
.fixed-wrapper {
    width: 220px;
    position: absolute;
    top: 0;
    left: -240px; /* Move this out to the left of the site body, leaving a 20px gutter */
}

/* The element you want to fix the position of */
.fixed {
    width: 220px;
    position: fixed;
    /* Do not set top / left! */
}
<div class="wrapper">
    <div class="fixed-wrapper">
        <div class="fixed">
            Content in here will be fixed position, but 240px to the left of the site body.
        </div>
    </div>
</div>

Sadly, I was hoping this thread might solve my issue with Android's WebKitrendering box-shadow blur pixels as margins on fixed position elements, but it seems it's a bug.
Anyway, I hope this helps!

可悲的是,我希望这个线程可以解决我的问题,Android 的WebKit将框阴影模糊像素渲染为固定位置元素的边距,但这似乎是一个错误。
无论如何,我希望这会有所帮助!

回答by Francesco Frapporti

Yes, according to the specs, there is a way.

是的,根据规范,有一种方法。

While I agree that Graeme Blackwood's should be the accepted answer, because it practically solves the issue, it should be noted that a fixed element canbe positioned relatively to its container.

虽然我同意 Graeme Blackwood 应该是公认的答案,因为它实际上解决了这个问题,但应该注意的是,固定元素可以相对于其容器定位。

I noticed by accident that when applying

我偶然注意到在申请时

-webkit-transform: translateZ(0);

to the body, it made a fixed child relative to it (instead of the viewport). So my fixed elements leftand topproperties were now relative to the container.

到身体,它相对于它(而不是视口)做了一个固定的孩子。所以我的固定元素lefttop属性现在是相对于容器的。

So I did some research, and found that the issue was already been covered by Eric Meyerand even if it felt like a "trick", turns out that this is part of the specifications:

所以我做了一些研究,发现Eric Meyer已经涵盖了这个问题,即使感觉像是一个“伎俩”,事实证明这是规范的一部分:

For elements whose layout is governed by the CSS box model, any value other than none for the transform results in the creation of both a stacking context and a containing block. The object acts as a containing block for fixed positioned descendants.

对于布局受 CSS 盒模型控制的元素,转换的任何值都会导致创建堆叠上下文和包含块。该对象充当固定定位后代的包含块。

http://www.w3.org/TR/css3-transforms/

http://www.w3.org/TR/css3-transforms/

So, if you apply any transformation to a parent element, it will become the containing block.

因此,如果对父元素应用任何转换,它将成为包含块。

But...

但...

The problem is that the implementation seems buggy/creative, because the elements also stop behaving as fixed (even if this bit doesn't seem to be part of specification).

问题是实现看起来有缺陷/有创意,因为元素也不再像固定一样运行(即使这一点似乎不是规范的一部分)。

The same behavior will be found in Safari, Chrome and Firefox, but not in IE11 (where the fixed element will still remain fixed).

在 Safari、Chrome 和 Firefox 中会发现相同的行为,但在 IE11 中则不会(其中固定元素仍将保持固定)。

Another interesting (undocumented) thing is that when a fixed element is contained inside a transformed element, while its topand leftproperties will now be related to the container, respecting the box-sizingproperty, its scrolling context will extend over the border of the element, as if box-sizing was set to border-box. For some creative out there, this could possibly become a plaything :)

另一个有趣(未记录)的事情是,当一个固定元素包含在一个转换元素中时,虽然它的topleft属性现在将与容器相关,尊重该box-sizing属性,它的滚动上下文将延伸到元素的边界上,就好像框-sizing 设置为border-box. 对于一些有创意的人来说,这可能会成为一种玩物:)

TEST

测试

回答by Shadow_boi

The answer is yes, as long as you don't set left: 0or right: 0after you set the div position to fixed.

答案是肯定的,只要你不设置left: 0或者right: 0在你将div位置设置为fixed之后。

http://jsfiddle.net/T2PL5/85/

http://jsfiddle.net/T2PL5/85/

Checkout the sidebar div. It is fixed, but related to the parent, not to the window view point.

检查侧边栏 div。它是固定的,但与父级相关,而不是与窗口视点相关。

body { background: #ccc; }

.wrapper {
    margin: 0 auto;
    height: 1400px;
    width: 650px;
    background: green;
}

.sidebar {
    background-color: #ddd;
    float: left;
    width: 300px;
    height: 100px;
    position: fixed;
}

.main {
    float: right;
    background-color: yellow;
    width: 300px;
    height: 1400px;
}

<div class="wrapper">wrapper
    <div class="sidebar">sidebar</div>
    <div class="main">main</div>
</div>

回答by PoseLab

position: stickythat is a new way to position elements that is conceptually similar to position: fixed. The difference is that an element with position: stickybehaves like position: relativewithin its parent, until a given offset threshold is met in the viewport.

position: sticky这是一种定位元素的新方法,在概念上类似于position: fixed. 不同之处在于,元素在其父元素中的position: sticky行为类似于position: relative其父元素,直到在视口中满足给定的偏移阈值。

In Chrome 56 (currently beta as of December 2016, stable in Jan 2017) position: sticky is now back.

在 Chrome 56(目前是 2016 年 12 月的测试版,2017 年 1 月稳定)中的位置:粘性现在又回来了。

https://developers.google.com/web/updates/2016/12/position-sticky

https://developers.google.com/web/updates/2016/12/position-sticky

More details are in Stick your landings! position: sticky lands in WebKit.

更多细节在坚持你的着陆!位置:WebKit 中的粘性区域

回答by Pransh Tiwari

2019 SOLUTION: You can use position: stickyproperty.

2019 解决方案:您可以使用position: sticky财产。

Here is an example CODEPENdemonstrating the usage and also how it differs from position: fixed.

这是一个示例CODEPEN演示了用法以及它与position: fixed.

How it behaves is explained below:

它的行为解释如下:

  1. An element with sticky position is positioned based on the user's scroll position. It basically acts like position: relativeuntil an element is scrolled beyond a specific offset, in which case it turns into position: fixed. When it is scrolled back it gets back to its previous (relative) position.

  2. It effects the flow of other elements in the page ie occupies a specific space on the page(just like position: relative).

  3. If it is defined inside some container, it is positioned with respect to that container. If the container has some overflow(scroll), depending on the scroll offset it turns into position:fixed.

  1. 具有粘性位置的元素根据用户的滚动位置进行定位。它基本上就像position: relative一个元素滚动超过特定偏移量,在这种情况下它变成位置:固定。当它向后滚动时,它会回到之前的(相对)位置。

  2. 它影响页面中其他元素的流动,即占据页面上的特定空间(就像position: relative)。

  3. 如果它是在某个容器内定义的,则它相对于该容器进行定位。如果容器有一些溢出(滚动),根据滚动偏移它变成位置:固定。

So if you want to achieve the fixed functionality but inside a container, use sticky.

因此,如果您想在容器内实现固定功能,请使用粘性。

回答by bigspotteddog

I have created this jQuery plugin to solve a similar issue I was having where I had a centered container (tabular data), and I wanted the header to fix to the top of the page when the list was scrolled, yet I wanted it anchored to the tabular data so it would be wherever I put the container (centered, left, right) and also allow it to move left and right with the page when scrolled horizontally.

我创建了这个 jQuery 插件来解决一个类似的问题,我有一个居中的容器(表格数据),我希望在滚动列表时将标题固定到页面顶部,但我希望它锚定到表格数据,所以它可以放在我放置容器的任何地方(居中、向左、向右),并且还允许它在水平滚动时随页面向左和向右移动。

Here is the link to this jQuery plugin that may solve this problem:

这是这个 jQuery 插件的链接,可以解决这个问题:

https://github.com/bigspotteddog/ScrollToFixed

https://github.com/bigspotteddog/ScrollToFixed

The description of this plugin is as follows:

这个插件的描述如下:

This plugin is used to fix elements to the top of the page, if the element would have scrolled out of view, vertically; however, it does allow the element to continue to move left or right with the horizontal scroll.

此插件用于将元素固定到页面顶部,如果元素会垂直滚动到视图之外;但是,它确实允许元素随着水平滚动继续向左或向右移动。

Given an option marginTop, the element will stop moving vertically upward once the vertical scroll has reached the target position; but, the element will still move horizontally as the page is scrolled left or right. Once the page has been scrolled back down passed the target position, the element will be restored to its original position on the page.

给定一个选项 marginTop,一旦垂直滚动到达目标位置,元素将停止垂直向上移动;但是,当页面向左或向右滚动时,元素仍将水平移动。一旦页面向下滚动超过目标位置,元素将恢复到页面上的原始位置。

This plugin has been tested in Firefox 3/4, Google Chrome 10/11, Safari 5, and Internet Explorer 8/9.

此插件已在 Firefox 3/4、Google Chrome 10/11、Safari 5 和 Internet Explorer 8/9 中测试。

Usage for your particular case:

用于您的特定情况:

<script src="scripts/jquery-1.4.2.min.js" type="text/javascript"></script>
<script src="scripts/jquery-scrolltofixed-min.js" type="text/javascript"></script>

$(document).ready(function() {
    $('#mydiv').scrollToFixed();
});

回答by hobberwickey

Just take the top and left styles out of the fixed position div. Here's an example

只需将顶部和左侧样式从固定位置 div 中取出即可。这是一个例子

<div id='body' style='height:200%; position: absolute; width: 100%; '>
    <div id='parent' style='display: block; margin: 0px auto; width: 200px;'>
        <div id='content' style='position: fixed;'>content</div>
    </div>
</div> 

The #content div will be sit wherever the parent div sits, but will be fixed there.

#content div 将位于父 div 所在的位置,但将固定在那里。

回答by Eric K

I had to do this with an advertisement that my client wanted to sit outside of the content area. I simply did the following and it worked like a charm!

我不得不用我的客户想要坐在内容区域之外的广告来做到这一点。我只是做了以下事情,它就像一个魅力!

<div id="content" style="position:relative; width:750px; margin:0 auto;">
  <div id="leftOutsideAd" style="position:absolute; top:0; left:-150px;">
    <a href="#" style="position:fixed;"><img src="###" /></a>
  </div>
</div>

回答by ScottS

Two HTML elements and pure CSS (modern browsers)

两个 HTML 元素和纯 CSS(现代浏览器)

See this jsFiddle example.Resize and see how the fixed elements even move with the floated elements they are in. Use the inner-most scroll bar to see how the scroll would work on a site (fixed elements staying fixed).

请参阅此 jsFiddle 示例。调整大小并查看固定元素如何与它们所在的浮动元素一起移动。使用最里面的滚动条查看滚动在站点上的工作方式(固定元素保持固定)。

As many here have stated, one key is not setting any positional settings on the fixedelement (no top, right, bottom, or leftvalues).

由于这里的许多人所指出的,一个密钥不上设置任何位置设置fixed元素(无toprightbottom,或left值)。

Rather, we put all the fixed elements (note how the last box has four of them) first in the box they are to be positioned off of, like so:

相反,我们将所有固定元素(注意最后一个盒子有四个)首先放在它们要定位的盒子中,如下所示:

<div class="reference">
  <div class="fixed">Test</div>
  Some other content in.
</div>

Then we use margin-topand margin-leftto "move" them in relation to their container, something like as this CSS does:

然后我们使用margin-topandmargin-left相对于它们的容器“移动”它们,就像这个 CSS 所做的那样:

.fixed {
    position: fixed;
    margin-top: 200px; /* Push/pull it up/down */
    margin-left: 200px; /* Push/pull it right/left */
}

Note that because fixedelements ignore all other layout elements, the final container in our fiddlecan have multiple fixedelements, and still have all those elements related to the top left corner. But this is only true if they are all placed first in the container, as this comparison fiddle shows that if dispersed within the container content, positioning becomes unreliable.

请注意,因为fixed元素会忽略所有其他布局元素,所以我们小提琴中的最终容器可以包含多个fixed元素,并且仍然包含与左上角相关的所有元素。但这只有在它们都首先放置在容器中时才是正确的,因为这个比较小提琴表明,如果分散在容器内容中,则定位变得不可靠

Whether the wrapper is static, relative, or absolutein positioning, it does not matter.

包装器在定位上是静态的相对的还是绝对的,都没有关系。