CSS 我可以定位相对于父元素固定的元素吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5209814/
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-29 23:52:40  来源:igfitidea点击:

Can I position an element fixed relative to parent?

cssdom

提问by Jiew Meng

I find that when I position an element fixed, it doesn't matter if the parent is positioned relative or not, it will position fixed, relative to the window?

我发现当我定位一个固定的元素时,父元素是否相对定位并不重要,它会相对于窗口定位吗?

CSS

CSS

#wrapper { width: 300px; background: orange; margin: 0 auto; position: relative; }
#feedback { position: fixed; right: 0; top: 120px; }

HTML

HTML

<div id="wrapper">
    ...
    <a id="feedback" href="#">Feedback</a>
</div>

http://jsbin.com/ibesa3

http://jsbin.com/ibesa3

采纳答案by DuckMaestro

Let me provide answers to both possible questions. Note that your existing title (and original post) ask a question different than what you seek in your edit and subsequent comment.

让我回答两个可能的问题。请注意,您现有的标题(和原始帖子)提出的问题与您在编辑和后续评论中所寻求的不同。



To position an element "fixed" relative to a parent element, you want position:absoluteon the child element, and any position mode other than the default or static on your parent element.

要相对于父元素“固定”定位元素,您需要position:absolute在子元素上,以及父元素上除默认或静态之外的任何位置模式。

For example:

例如:

#parentDiv { position:relative; }
#childDiv { position:absolute; left:50px; top:20px; }

This will position childDivelement 50 pixels left and 20 pixels down relative to parentDiv's position.

这将使childDiv元素相对于 parentDiv 的位置向左 50 像素,向下 20 像素。



To position an element "fixed" relative to the window, you want position:fixed, and can use top:, left:, right:, and bottom:to position as you see fit.

位置“固定”相对于窗口元素,你想position:fixed,并且可以使用top:left:right:,和bottom:对的位置,你认为合适的。

For example:

例如:

#yourDiv { position:fixed; bottom:40px; right:40px; }

This will position yourDivfixed relative to the web browser window, 40 pixels from the bottom edge and 40 pixels from the right edge.

这将yourDiv相对于 Web 浏览器窗口进行固定,距底部边缘 40 像素,距右边缘 40 像素。

回答by Jon Adams

The CSS specification requires that position:fixedbe anchored to the viewport, not the containing positioned element.

CSS 规范要求position:fixed锚定到视口,而不是包含定位的元素。

If you must specify your coordinates relative to a parent, you will have to use JavaScript to find the parent's position relative to the viewport first, then set the child (fixed) element's position accordingly.

如果必须指定相对于父元素的坐标,则必须首先使用 JavaScript 找到父元素相对于视口的位置,然后相应地设置子(固定)元素的位置。

ALTERNATIVE: Some browsers have stickyCSS support which limits an element to be positioned within both its container and the viewport. Per the commit message:

替代方案:某些浏览器具有stickyCSS 支持,该支持限制元素定位在其容器和视口中。根据提交消息:

sticky... constrains an element to be positioned inside the intersection of its container box, and the viewport.

A stickily positioned element behaves like position:relative (space is reserved for it in-flow), but with an offset that is determined by the sticky position. Changed isInFlowPositioned() to cover relative and sticky.

sticky... 将元素限制在其容器框和视口的交集内。

粘性定位元素的行为类似于 position:relative(为流入的元素保留空间),但具有由粘性位置确定的偏移量。更改 isInFlowPositioned() 以覆盖相对和粘性。

Depending on your design goals, this behavior may be helpful in some cases. It is currently a working draft, and has decent support, aside from table elements. position: stickystill needs a -webkitprefix in Safari.

根据您的设计目标,此行为在某些情况下可能会有所帮助。它目前是一个工作草案,除了表格元素外,还有不错的支持。在 Safari 中position: sticky仍然需要一个-webkit前缀。

See caniusefor up-to-date stats on browser support.

有关浏览器支持的最新统计信息,请参阅caniuse

回答by Patrick McElhaney

2016 Update

2016年更新

It's now possible in modern browsers to position an element fixed relative to its container. An element that has a transform property acts as the viewport for any of its fixed position child elements.

现在可以在现代浏览器中定位相对于其容器固定的元素。具有 transform 属性的元素充当其任何固定位置子元素的视口。

Or as the CSS Transforms Moduleputs it:

或者如CSS Transforms Module所说:

For elements whose layout is governed by the CSS box model, any value other than none for the transform property also causes the element to establish a containing block for all descendants. Its padding box will be used to layout for all of its absolute-position descendants, fixed-position descendants, and descendant fixed background attachments.

对于布局由 CSS 框模型控制的元素,transform 属性的任何值除了 none 也会导致元素为所有后代建立一个包含块。其填充框将用于布局其所有绝对位置后代、固定位置后代和后代固定背景附件。

.context {
  width: 300px;
  height: 250px;
  margin: 100px;
  transform: translateZ(0);
}
.viewport {
  width: 100%;
  height: 100%;
  border: 1px solid black;
  overflow: scroll;
}
.centered {
  position: fixed;
  left: 50%;
  bottom: 15px;
  transform: translateX(-50%);
}
<div class="context">
  <div class="viewport">
    <div class="canvas">

      <table>
        <tr>
          <td>stuff</td>
          <td>stuff</td>
          <td>stuff</td>
          <td>stuff</td>
          <td>stuff</td>
          <td>stuff</td>
          <td>stuff</td>
          <td>stuff</td>
          <td>stuff</td>
          <td>stuff</td>
          <td>stuff</td>
          <td>stuff</td>
          <td>stuff</td>
        </tr>
        <tr>
          <td>stuff</td>
          <td>stuff</td>
          <td>stuff</td>
          <td>stuff</td>
          <td>stuff</td>
          <td>stuff</td>
          <td>stuff</td>
          <td>stuff</td>
          <td>stuff</td>
          <td>stuff</td>
          <td>stuff</td>
          <td>stuff</td>
          <td>stuff</td>
        </tr>

        <tr>
          <td>stuff</td>
          <td>stuff</td>
          <td>stuff</td>
          <td>stuff</td>
          <td>stuff</td>
          <td>stuff</td>
          <td>stuff</td>
          <td>stuff</td>
          <td>stuff</td>
          <td>stuff</td>
          <td>stuff</td>
          <td>stuff</td>
          <td>stuff</td>
        </tr>

        <tr>
          <td>stuff</td>
          <td>stuff</td>
          <td>stuff</td>
          <td>stuff</td>
          <td>stuff</td>
          <td>stuff</td>
          <td>stuff</td>
          <td>stuff</td>
          <td>stuff</td>
          <td>stuff</td>
          <td>stuff</td>
          <td>stuff</td>
          <td>stuff</td>
        </tr>
      </table>

      <button class="centered">OK</button>

    </div>
  </div>
</div>

回答by Даниил Пронин

first, set position: fixedand left: 50%, and second — now your start is a center and you can set new position with margin.

首先,设置position: fixedleft: 50%,然后——现在你的开始是一个中心,你可以用边距设置新的位置。

回答by Lifehack

I know this is super old but after not finding the (pure CSS) answer I was looking for I came up with this solution (partially abstracted from medium.com) and thought it might help others looking to do the same thing.

我知道这太旧了,但在没有找到我正在寻找的(纯 CSS)答案后,我想出了这个解决方案(部分从medium.com 中抽象出来),并认为它可能会帮助其他想做同样事情的人。

If you combine @DuckMaestro's answers you can position an element fixed relative to a parent (actually grandparent). Use position: absolute;to position an element inside a parent with position: relative;and then position: fixed;on an element inside the absolute positioned element like so:

如果您结合@DuckMaestro 的答案,您可以定位相对于父级(实际上是祖父级)固定的元素。用于position: absolute;在父元素内定位一个元素position: relative;,然后position: fixed;在绝对定位元素内的一个元素上,如下所示:

HTML

HTML

<div class="relative">
  <div class="absolute">
    <a class="fixed-feedback">This element will be fixed</a>
  </div>
</div>

CSS

CSS

.relative {
  margin: 0 auto;
  position: relative;
  width: 300px;
}

.absolute {
  position: absolute;
  right: 0;
  top: 0;
  width: 50px;
}

.fixed-feedback {
  position: fixed;
  top: 120px;
  width: 50px;
}

EXAMPLE

例子

Like @JonAdams said, the definition of position: fixedrequires the element to be positioned relative to the viewport but you can get around the horizontal aspect of that using this solution.

就像@JonAdams 所说的那样, 的定义position: fixed要求元素相对于视口定位,但您可以使用此解决方案绕过它的水平方面。

Note: This is different than just setting a rightor leftvalue on the fixed element because that would cause it to move horizontally when a window is resized.

注意:这与仅在固定元素上设置 arightleft值不同,因为这会导致它在调整窗口大小时水平移动。

回答by KXL

Here is an example of Jon Adams suggestion above in order to fix a div (toolbar) to the right hand side of your page element using jQuery. The idea is to find the distance from the right hand side of the viewport to the right hand side of the page element and to keep the right hand side of the toolbar there!

这是上面 Jon Adams 建议的示例,目的是使用 jQuery 将 div(工具栏)固定到页面元素的右侧。这个想法是找到从视口右侧到页面元素右侧的距离,并将工具栏的右侧保持在那里!

HTML

HTML

<div id="pageElement"></div>
<div id="toolbar"></div>

CSS

CSS

#toolbar {
    position: fixed;
}
....

jQuery

jQuery

function placeOnRightHandEdgeOfElement(toolbar, pageElement) {
    $(toolbar).css("right", $(window).scrollLeft() + $(window).width()
    - $(pageElement).offset().left
    - parseInt($(pageElement).css("borderLeftWidth"),10)
    - $(pageElement).width() + "px");
}
$(document).ready(function() {
    $(window).resize(function() {
        placeOnRightHandEdgeOfElement("#toolbar", "#pageElement");
    });
    $(window).scroll(function () { 
        placeOnRightHandEdgeOfElement("#toolbar", "#pageElement");
    });
    $("#toolbar").resize();
});

回答by Sabaz

It's an old post but i'll leave here my javascript solution just in case someone need it.

这是一个旧帖子,但我会留下我的 javascript 解决方案,以防万一有人需要它。



// you only need this function
function sticky( _el ){
  _el.parentElement.addEventListener("scroll", function(){
    _el.style.transform = "translateY("+this.scrollTop+"px)";
  });
}


// how to make it work:
// get the element you want to be sticky
var el = document.querySelector("#blbl > div");
// give the element as argument, done.
sticky(el);
#blbl{
  position:relative;
  height:200px;  
  overflow: auto;
  background: #eee;
}

#blbl > div{
  position:absolute; 
  padding:50px; 
  top:10px; 
  left:10px; 
  background: #f00
}
<div id="blbl" >
    <div><!-- sticky div --></div> 

    <br><br><br><br><br><br><br><br><br><br><br><br><br>
    <br><br><br><br><br><br><br><br><br><br><br><br><br>
    <br><br><br><br><br><br><br><br><br><br><br><br><br>
    <br><br><br><br><br><br><br><br><br><br><br><br><br>
</div>



Notes

笔记

  1. I used transform: translateY(@px)because it should be lightweight to compute, high-performance-animations

  2. I only tried this function with modern browsers, it won't work for old browsers where vendors are required (and IE of course)

  1. 我使用了transform: translateY(@px)因为它应该是轻量级计算的高性能动画

  2. 我只在现代浏览器上尝试过这个功能,它不适用于需要供应商的旧浏览器(当然还有 IE)

回答by Ed Kolosovsky

This solution works for me! Reference to the original detailed answer: https://stackoverflow.com/a/11833892/5385623

这个解决方案对我有用!参考原文详细回答:https: //stackoverflow.com/a/11833892/5385623

css:

css:

.level1 {
    position: relative;
}


.level2 {
    position: absolute;
}


.level3 {
    position: fixed;
    /* Do not set top / left! */
}

html:

html:

<div class='level1'>
    <div class='level2'>
        <div class='level3'>
            Content
        </div>
    </div>
</div>

回答by illinoistim

I know this is an older post, but I think a good example of what Jiew Meng was trying to do can already be found on this site. Check out the side menu located here: https://stackoverflow.com/faq#questions. Looking at it without getting into it too deep, I can tell javascript attaches a fixed position once the scrolling hits below the anchor tag and removes the fixed positioning if the scrolling goes above that same anchor tag. Hopefully, that will get someone started in the right direction.

我知道这是一篇较旧的帖子,但我认为在这个网站上已经可以找到 Jiew Meng 试图做的一个很好的例子。查看位于此处的侧边菜单:https: //stackoverflow.com/faq#questions。看着它而不深入它,我可以告诉 javascript 在滚动到达锚标记下方时附加一个固定位置,如果滚动超过同一锚标记,则删除固定位置。希望这能让某人朝着正确的方向开始。

回答by sajtdavid

With multiple divs I managed to get a fixed-y and absolute-x divs. In my case I needed a div on left and right sides, aligned to a centered 1180px width div.

通过多个 div,我设法获得了固定 y 和绝对 x div。在我的情况下,我需要在左侧和右侧有一个 div,与居中的 1180px 宽度 div 对齐。

    <div class="parentdiv" style="
        background: transparent;
        margin: auto;
        width: 100%;
        max-width: 1220px;
        height: 10px;
        text-align: center;">
        <div style="
            position: fixed;
            width: 100%;
            max-width: 1220px;">
            <div style="
                position: absolute;
                background: black;
                height: 20px;
                width: 20px;
                left: 0;">
            </div>
            <div style="
                width: 20px;
                height: 20px;
                background: blue;
                position: absolute;                                           
                right: 0;">
            </div>
        </div>
    </div>