固定位置,但相对于容器

2011-07-23 css position css-position fixed

我正在尝试修复div以便始终使用以下方法将其固定在屏幕顶部:

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

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

我知道position:absolute可用于相对于div固定元素,但是当您向下滚动页面时,该元素消失且不会像position:fixed那样粘在顶部。

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

Answers

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

长答案:使用“固定”定位的问题是它会使元素脱离流动 。因此无法相对于其父对象重新定位,因为好像它没有父对象。但是,如果容器的宽度是已知的固定宽度,则可以使用以下方法:

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

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

编辑(03/2015):

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

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

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

如果希望它居中,也可以这样做:

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

演示:

jsFiddle:仅水平居中
jsFiddle:水平和垂直居中
原始荣誉归用户aaronk6指出,在此答案中向我指出

我不久前做了类似的事情。我刚接触JavaScript,因此可以肯定您可以做得更好,但这是一个起点:

function fixxedtext() {
    if (navigator.appName.indexOf("Microsoft") != -1) {
        if (document.body.offsetWidth > 960) {
            var width = document.body.offsetWidth - 960;
            width = width / 2;
            document.getElementById("side").style.marginRight = width + "px";
        }
        if (document.body.offsetWidth < 960) {
            var width = 960 - document.body.offsetWidth;
            document.getElementById("side").style.marginRight = "-" + width + "px";
        }
    }
    else {
        if (window.innerWidth > 960) {
            var width = window.innerWidth - 960;
            width = width / 2;
            document.getElementById("side").style.marginRight = width + "px";
        }
        if (window.innerWidth < 960) {
            var width = 960 - window.innerWidth;
            document.getElementById("side").style.marginRight = "-" + width + "px";
        }
    }
    window.setTimeout("fixxedtext()", 2500)
}

您将需要设置宽度,然后它获取窗口宽度并每隔几秒钟更改边距。我知道它很重,但是可以用。

我创建了这个jQuery插件来解决我在居中放置容器(表格数据)时遇到的类似问题,并且我希望在滚动列表时将标头固定到页面顶部,但我希望将其锚定到表格数据,因此它可以放在我放置容器的任何位置(居中,左,右),并且在水平滚动时还可以使其随页面左右移动。

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

https://github.com/bigspotteddog/ScrollToFixed

该插件的说明如下:

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

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

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

具体用法:

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

只需从固定位置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> 

#content div将位于父div所在的任何位置,但将固定在该位置。

检查一下:

<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title></title>
    </head>
    <body style="width: 1000px !important;margin-left: auto;margin-right: auto">
        <div style="width: 100px; height: 100px; background-color: #ccc; position:fixed;">
        </div>
        <div id="1" style="width: 100%; height: 600px; background-color: #800000">
        </div>
        <div id="2" style="width: 100%; height: 600px; background-color: #100000">
        </div>
        <div id="3" style="width: 100%; height: 600px; background-color: #400000">
        </div>
    </body>
</html>

我必须做一个广告,说我的客户想坐在内容区域之外。我只是简单地进行了以下操作,它就像一个魅力!

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

实现相对固定位置的另一种奇怪的解决方案是将容器转换为iframe,这样您的固定元素就可以固定在容器的视口而不是整个页面上。

实际上,这是可能的,并且被接受的答案仅涉及集中,这很简单。另外,您确实不需要使用JavaScript。

这将使您处理任何情况:

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

例如:

/* 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>

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

您可以尝试一下我的jQuery插件FixTo

用法:

$('#mydiv').fixTo('#centeredContainer');

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

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

检出侧边栏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>

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

我同意Graeme Blackwood的答案是可以接受的答案,因为它实际上可以解决问题,但应注意, 可以相对于其容器放置固定的元素。

我偶然发现申请时

-webkit-transform: translateZ(0);

相对于它,它相对于它是一个固定的子对象(而不是视口)。因此,我的固定元素lefttop属性现在相对于容器。

因此,我进行了一些研究,发现该问题已被Eric Meyer所涵盖,即使感觉像是“绝招”,事实证明,这是规范的一部分:

对于其布局由CSS box模型控制的元素,任何值 除无以外,其他变换均会创建两个 堆栈上下文和一个包含块。该对象充当 包含固定位置后代的块。

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

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

但...

问题在于实现似乎是错误的/创造性的,因为元素也停止表现为固定状态(即使该位似乎不属于规范的一部分)。

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

另一个有趣的(未记录)的事情是,当固定元素包含在转换后的元素内时,尽管它的topleft属性现在将与容器相关,但要尊重box-sizing属性,其滚动上下文将在元素,就像将box-sizing设置为border-box 。对于那里的一些创意,这可能会成为一种玩物:)

测试

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

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

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

有关更多详细信息, 请保持着陆!位置:WebKit中的粘性土地

使用纯CSS,您将无法做到;至少我没有。但是,您可以使用jQuery非常简单地做到这一点。我将解释我的问题,只需稍作更改即可使用它。

因此,一开始,我希望我的元素具有固定的顶部(从窗口顶部开始),并具有从父元素继承的左侧组件(因为父元素居中)。要设置左侧组件,只需将您的元素放入父元素,然后为父元素设置position:relative

然后,当滚动条位于顶部(y零滚动)时,您需要知道元素从顶部开始的数量。再次有两个选择。首先是静态的(一些数字),或者您必须从父元素中读取它。

在我的情况下,它离顶部静态像素有150像素。因此,当您看到150时,就是我们没有滚动时从顶部算起的元素数。

的CSS

#parent-element{position:relative;}
#promo{position:absolute;}

jQuery的

$(document).ready(function() { //This check window scroll bar location on start
    wtop=parseInt($(window).scrollTop());
    $("#promo").css('top',150+wtop+'px');

});
$(window).scroll(function () { //This is when the window is scrolling
    wtop=parseInt($(window).scrollTop());
    $("#promo").css('top',150+wtop+'px');
});

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

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

如此处许多人所述,一个键没有在fixed元素上设置任何位置设置(没有toprightbottomleft值)。

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

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

然后,我们使用margin-topmargin-left于其容器“移动”它们,就像此CSS一样:

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

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

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

这很容易(按照下面的HTML)

诀窍是不要在元素(div)的顶部或左侧使用“ position:fixed;”。 如果未指定这些内容,则“固定内容”元素将相对于封闭元素(带有“ position:relative;”的div)相对于浏览器窗口出现!

<div id="divTermsOfUse" style="width:870px; z-index: 20; overflow:auto;">
    <div id="divCloser" style="position:relative; left: 852px;">
        <div style="position:fixed; z-index:22;">
            <a href="javascript:hideDiv('divTermsOfUse');">
                <span style="font-size:18pt; font-weight:bold;">X</span>
            </a>
        </div>
    </div>
    <div>  <!-- container for... -->
         lots of Text To Be Scrolled vertically...
         bhah! blah! blah!
    </div>
</div>

上面的内容使我可以在带有垂直滚动的div中许多文本的顶部找到一个关闭的“ X”按钮。 “ X”位于适当位置(不会随着滚动文本一起移动,但是当用户调整浏览器窗口的宽度大小时,它确实会与封闭的div容器一起向左或向右移动!因此它是垂直“固定”的,但相对于水平包围元素!

在进行此工作之前,向下滚动文本内容时,“ X”会向上滚动并看不见。

抱歉,不提供我的javascript hideDiv()函数,但不必要地延长了这篇文章。我选择使其尽可能短。

如果您使用JavaScript,则有可能。在这种情况下,jQuery插件Sticky-Kit

我创建了一个jsfiddle来演示如何使用转换工作。

的HTML

<div class="left">
    Content
</div>
<div class="right">
<div class="fixedContainer">
    X
</div>
    Side bar
</div>

的CSS

body {
  margin: 0;
}
.left {
  width: 77%;
  background: teal;
  height: 2000px;
}
.right {
  width: 23%;
  background: yellow;
  height: 100vh;
  position: fixed;
  right: 0;
  top: 0;
}
.fixedContainer {
    background-color:#ddd;
    position: fixed;
    padding: 2em;
    //right: 0;
    top: 0%;
    transform: translateX(-100px);
}

jQuery的

$('.fixedContainer').on('click', function() {
    $('.right').animate({'width': '0px'});
  $('.left').animate({'width': '100%'});
});

https://jsfiddle.net/bx6ktwnn/1/

我有同样的问题,我们的团队成员之一给了我一个解决方案。 要允许div固定位置以及相对于其他div的位置,我们的解决方案是使用父容器包装固定div并滚动div。

<div class="container">
  <div class="scroll"></div>
  <div class="fix"></div>
</div>

的CSS

.container {
  position: relative;
  flex:1;
  display:flex;
}

.fix {
  prosition:absolute;
}

我的项目是带有Bootstrap 4的.NET ASP Core 2 MVC Angular 4模板。在第一行中将“ sticky-top”添加到主要应用程序组件html(即app.component.html)中,如下所示:

<div class='row sticky-top'>
    <div class='col-sm-12'>
        <nav-menu-top></nav-menu-top>
    </div>
</div>
<div class="row">
    <div class='col-sm-3'>
        <nav-menu></nav-menu>
    </div>
    <div class='col-sm-9 body-content'>
        <router-outlet></router-outlet>
    </div>
</div>

那是惯例还是我简化了?

2019解决方案:您可以使用position: sticky属性。

这是一个示例CODEPEN,演示了用法以及它与position: fixed不同之处position: fixed

其行为说明如下:

  1. 根据用户的滚动位置来定位具有粘性位置的元素。它基本上就像position: relative直到元素滚动到特定偏移量为止,在这种情况下,它变成位置:固定。向后滚动时,它将返回到其先前(相对)位置。

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

  3. 如果将其定义在某个容器内,则相对于该容器定位。如果容器有一些溢出(滚动),则取决于滚动偏移量,它会变为position:fixed。

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

/* html */

/* this div exists purely for the purpose of positioning the fixed div it contains */
<div class="fix-my-fixed-div-to-its-parent-not-the-body">

     <div class="im-fixed-within-my-container-div-zone">
          my fixed content
     </div>

</div>



/* css */

/* wraps fixed div to get desired fixed outcome */
.fix-my-fixed-div-to-its-parent-not-the-body 
{
    float: right;
}

.im-fixed-within-my-container-div-zone
{
    position: fixed;
    transform: translate(-100%);
}

是的,只要您不设置fixed元素的位置( topleft等)(尽管您仍然可以使用margin设置相对位置),这是可能的。西蒙·博斯(Simon Bos) 不久前发表了有关此事

但是,不要指望固定元素与非固定亲戚一起滚动。

在此处查看演示

当您使用position:fixed CSS规则并尝试应用top / left / right / bottom它将元素相对于窗口定位。

一种解决方法是使用margin属性,而不是top / left / right / bottom

Related