我可以将元素相对于父元素定位吗?

Jie*_*eng 229 css dom

我发现当我将一个元素定位为固定时,如果父元素相对与否定位无关紧要,它将相对于窗口定位固定?

CSS

#wrapper { width: 300px; background: orange; margin: 0 auto; position: relative; }
#feedback { position: fixed; right: 0; top: 120px; }
Run Code Online (Sandbox Code Playgroud)

HTML

<div id="wrapper">
    ...
    <a id="feedback" href="#">Feedback</a>
</div>
Run Code Online (Sandbox Code Playgroud)

http://jsbin.com/ibesa3

Jon*_*ams 197

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

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

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

sticky ...约束要在其容器框和视口的交叉点内定位的元素.

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

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

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

  • 这不是一个好的解决方案,Chrome不再支持`-webkit-sticky`(除非您启用实验标记).它可能会在某个时候回来,但在官方支持之前,最好使用Grawl的解决方案. (8认同)
  • @Jon,如果您点击帖子的"编辑"注释后的日期时间,您实际上可以看到编辑历史记录. (3认同)
  • 现在我已经更新了这个答案,因为“ sticky”具有很好的支持。 (2认同)

Duc*_*tro 132

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


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

例如:

#parentDiv { position:relative; }
#childDiv { position:absolute; left:50px; top:20px; }
Run Code Online (Sandbox Code Playgroud)

这将childDiv相对于parentDiv的位置向左50像素和向下20像素定位元素.


要将元素相对于窗口定位为"固定",您position:fixed可以根据需要使用top:,left:right:,以及bottom:定位.

例如:

#yourDiv { position:fixed; bottom:40px; right:40px; }
Run Code Online (Sandbox Code Playgroud)

这将yourDiv相对于Web浏览器窗口固定,距底边40像素,右边40像素.

  • 哦,嗯...我实际上想模仿一个粘性按钮,当它定位绝对时,当我向下滚动时,它不粘...嗯 (82认同)
  • 不是OP要求的...... (37认同)
  • @jiewmeng希望他的子元素被"固定",这意味着当你向下滚动时,孩子仍然可以看到并且在屏幕上的同一位置. (20认同)
  • @Will会选择OP作为他的答案.显然他后来在某个阶段对他的问题进行了编辑.我并不急于删除这个答案,因为那里仍然有人发现它有用(8个赞成),并且是对问题标题的回答.OP应该选择不同的接受答案,如果不同的答案现在是更好的答案. (8认同)
  • 一直在寻找这个一个月左右,这是第一次实际解释超出"使用绝对和固定"或一些废话.+1 (6认同)
  • 虽然这个解决方案实际上可能使OP受益,但它没有回答标题中提出的问题.这个下面的答案要准确得多,应该标记为正确答案. (6认同)
  • @DuckMaestro用滚动条在溢出的div里面做什么呢?`position:absolute`将使它随之滚动. (3认同)

Дан*_*нин 61

首先,设置position: fixedleft: 50%,第二 - 现在你的开始是一个中心,你可以设置保证金的新头寸.


Pat*_*ney 55

2016年更新

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

.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%);
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

  • @Sean当父元素有一个滚动条并且你希望固定位置元素保留而父元素在它后面滚动时. (14认同)
  • 在IE11中不起作用 (3认同)
  • 当具有“绝对”定位的子元素在具有“相对”或“绝对”定位的父元素中表现相同时,为什么需要执行此操作? (3认同)
  • 我总是在它周围放置另一个div,并且绝对定位到外部div,然后让内部div具有滚动条.有时候你无法控制HTML,所以很高兴知道这个有用! (2认同)
  • 有一些不同的CSS属性具有此效果.另一种是"将改变:变换". (2认同)
  • 这应该是公认的答案 (2认同)

Lif*_*ack 12

我知道这是超级老了但是在找不到我想找的(纯CSS)答案之后我想出了这个解决方案(部分从medium.com中抽象出来)并认为它可能会帮助其他人做同样的事情.

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

HTML

<div class="relative">
  <div class="absolute">
    <a class="fixed-feedback">This element will be fixed</a>
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)

就像@JonAdams所说的那样,定义position: fixed要求元素相对于视口定位,但是你可以使用这个解决方案绕过横向方面.

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

  • 这似乎并不像你声称的那样工作。该元素仍然相对于视口定位“固定”,而不是包含元素。它的左/右位置没有改变,所以它保持在原来的位置,但在真正意义上,它并不是根据其父级固定的。看这个例子,我在父div上方添加了一个div。`div.fixed-feedback` 保持在距窗口顶部 120 像素的位置。http://codepen.io/anon/pen/LbvOaY (2认同)

KXL*_*KXL 10

以下是Jon Adams建议的示例,以便使用jQuery将div(工具栏)修复到页面元素的右侧.我们的想法是找到从视口右侧到页面元素右侧的距离,并保持工具栏的右侧!

HTML

<div id="pageElement"></div>
<div id="toolbar"></div>
Run Code Online (Sandbox Code Playgroud)

CSS

#toolbar {
    position: fixed;
}
....
Run Code Online (Sandbox Code Playgroud)

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();
});
Run Code Online (Sandbox Code Playgroud)

  • @Grawl ..JQuery诞生于处理疯狂!随着CSS的成熟和浏览器合规性的增长,我希望你是正确的. (16认同)

Ed *_*sky 10

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

css:

.level1 {
    position: relative;
}


.level2 {
    position: absolute;
}


.level3 {
    position: fixed;
    /* Do not set top / left! */
}
Run Code Online (Sandbox Code Playgroud)

html:

<div class='level1'>
    <div class='level2'>
        <div class='level3'>
            Content
        </div>
    </div>
</div>
Run Code Online (Sandbox Code Playgroud)

  • 这个答案应该在最上面 (4认同)

Sab*_*baz 7

这是一个旧帖子,但我会留下我的 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);
Run Code Online (Sandbox Code Playgroud)
#blbl{
  position:relative;
  height:200px;  
  overflow: auto;
  background: #eee;
}

#blbl > div{
  position:absolute; 
  padding:50px; 
  top:10px; 
  left:10px; 
  background: #f00
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)


笔记

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

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