将“position: fixed”的div宽度设置为相对于父div的宽度

214
我尝试将一个固定位置的div设置为100%的宽度(相对于其父div),但是遇到了一些问题...
编辑: 第一个问题通过使用inherit得以解决,但仍然无法正常工作。我认为问题在于我使用了多个占据100%/inherit宽度的div。 你可以在jsfiddle更新中找到第二个问题:http://jsfiddle.net/4bGqF/7/
例如,狐狸
#container {
    width: 800px;
}

#fixed {
    position: fixed;
    width: 100%;
}

和 HTML

<div id="container">
    <div id="fixed">Sitename</div>
    <p>
        blaat
    </p>
</div>

或者您可以尝试一下:http://jsfiddle.net/4bGqF/

问题似乎是固定元素始终占据窗口/文档的宽度。有人知道如何解决吗?

我无法给我的固定元素设置固定宽度,因为我正在使用jScrollPane插件。它取决于内容是否有滚动条。

非常感谢!

PS:两个div的文本重叠在一起。这只是一个例子,所以并不重要。


请看我的答案,其中提供了一些关于“继承”以及如何使用max-width:inheritwidth:inherit保持容器/包含比例相同的响应式和可管理性的额外见解。 - aequalsb
11个回答

162

我不确定您的编辑后第二个问题是什么,但如果您将width:inherit应用于所有内部div,则可以解决问题:http://jsfiddle.net/4bGqF/9/

对于需要支持但不支持width: inherit的浏览器,您可能需要考虑使用JavaScript解决方案。


4
感谢夸赞这个非常简单的解决方案,尽管“width: inherit”不是我首先想到的东西。 - Bojangles
7
如果#container的宽度为50%,而其所在的div的宽度为100像素,则该问题该如何解决?(那么,#container的宽度将为50像素,并且固定宽度将是浏览器宽度的50%)。 - Kek
185
只有父元素以像素为单位设置了宽度,才能通过继承父元素的宽度来设置子元素的宽度。 - jahu
65
这个回答很糟糕...基本上等同于设置常量值,这并没有什么用。 - Jay
2
如果容器使用百分比宽度,该如何解决这个问题? - Vinícius Fagundes
显示剩余7条评论

103

固定位置有点棘手(实际上是不可能的),但是 position: sticky 很好地解决了这个问题:

<div class='container'>
  <header>This is the header</header>
  <section>
    ... long lorem ipsum
  </section>
</div>


body {
  text-align: center;  
}

.container {
  text-align: left;
  max-width: 30%;
  margin: 0 auto;
}


header {
  line-height: 2rem;
  outline: 1px solid red;
  background: #fff;
  padding: 1rem;

  position: sticky;
  top: 0;
}

查看CodePen示例


5
对于任何尝试创建一个“粘性页脚”的人,需要注意:它只在其后跟着一个兄弟元素时才能正常工作。因此,在此元素下添加一个空的 div 即可(您可能需要为底部 div 设置高度)。 - Alex von Brandenfels
这对我来说很有效,将我的导航设置为width=100%不会占满整个屏幕大小,而是相对于其容器。在这种情况下,position: fixed; 不是我所需要的。 - mike_s

71

正如许多人评论的那样,响应式设计通常通过百分比设置宽度。

width:inherit 将继承 CSS 宽度 而不是 计算宽度 -- 这意味着子容器继承了 width:100%

但我认为,响应式设计同样经常设置max-width,因此:

#container {
    width:100%;
    max-width:800px;
}
#contained {
    position:fixed;
    width:inherit;
    max-width:inherit;
}

这种方法非常满意地解决了我的问题,即使粘性菜单被“固定”时,也将其限制在原始父元素宽度内。

如果视口小于最大宽度,则父级和子级都将遵循width:100%。同样,当视口更宽时,两者都将遵循max-width:800px

这适用于我的响应式主题,我可以修改父容器而无需修改固定的子元素 - 简洁而灵活。

附:我个人认为IE6/7不使用inherit没有任何关系。


很棒的答案!在我的情况下,添加 min-width: inherit 就解决了问题。 - Bruno Monteiro
这适用于宽度以像素和百分比定义的父元素。在我看来应该是正确的答案。 - Mikel

15

你也可以通过jQuery来解决它:

var new_width = $('#container').width();
$('#fixed').width(new_width); 

这对我非常有帮助,因为我的布局是响应式的,而inherit解决方案对我不起作用!


2
回答不好,如果你调整窗口大小,它会出问题。 - Jay
3
确实应该有一个 window.onresize 事件处理程序。 - twistedpixel
这是实现的方法。可以将其封装成一个函数setWidth(),然后在“load”和“resize”窗口事件监听器上调用它。 - woodz
这对我很有效!我遇到了一个问题,父元素的宽度为25%,因此使用width:inherit会使每个子元素的宽度为25%。 - Troy Riemer

15

使用以下CSS:

#container {
    width: 400px;
    border: 1px solid red;
}

#fixed {
    position: fixed;
    width: inherit;
    border: 1px solid green;
}

#fixed 元素将继承其父元素的宽度,因此它的宽度将是父元素宽度的100%。


1
除了IE6-7不支持inherit,不确定这是否有影响。 - Thomas Shields
非常感谢。我在示例中尝试时有效,但在我的代码中无效...无论如何,这是我在这里提出的问题的答案。可能还有另一个原因导致它不起作用...但还是感谢! - Dnns
2
没有明确设置宽度的块级元素无法正常工作。 - tylik

8

固定定位是指所有元素都相对于视口定义,因此position:fixed始终如此。请尝试在子div上使用position:relative。 (我意识到您可能需要固定定位的其他原因,但如果这样-您不能真正使用JS使宽度与父元素匹配,而不使用inherit


2
@Downvoter - 你能解释一下吗?我对于被踩没有任何问题,但是我想知道为什么,这样我就可以在未来改进我的回答了。 - Thomas Shields
1
你的解释很好,但是你说“如果没有JS,你不能真正使宽度与其父元素匹配”。虽然在某些情况下(通过使用inherit)是可能的。 - Dnns
哦,当然。我忘记了继承,因为我经常针对IE,只有IE9+支持它。 - Thomas Shields
1
即使是微软也希望IE消失了——考虑到这篇原始文章有多老,我认为可以说IE的问题已经不重要了。如果没有特别的支持IE的需求,强烈建议不要支持它——除非你按小时计费! - aequalsb

5
对于使用jQuery实现粘性页眉,我对jQuery仍在学习中,下面的CSS设置可以起作用。
header.sticky{
    position: fixed;
    border-radius: 0px;
    max-height: 70px;
    z-index: 1000;
    width: 100%;
    max-width: inherit;
}

标题栏位于最大宽度为1024的包装div内。


4

我们在修复一个大型应用的重绘问题时,发现了一个小技巧。

在父元素上使用 -webkit-transform: translateZ(0);。当然,这只适用于Chrome浏览器。

http://jsfiddle.net/senica/bCQEa/

-webkit-transform: translateZ(0);

3
这解决了宽度问题,但是相对于视口,它使子元素不再固定。 - V Maharajh
1
抱歉给你点了踩,因为这完全违背了position:fixed的用途。 - trusktr
我认为你没有读清楚问题。问题是如何使一个div相对于具有“fixed”位置的父元素。“THAT TOO”也是反固定位置的。而我的回答明确表示了“hack”。当它让你更接近解决方案时,它并不会违背初衷。 - Senica Gonzalez

3

这个问题有一个简单的解决方案。

我对父级div使用了fixed位置,并对内容设置了max-width。

您无需过多考虑其他容器,因为固定位置仅与浏览器窗口相关。

       .fixed{
            width:100%;
            position:fixed;
            height:100px;
            background: red;
        }

        .fixed .content{
            max-width: 500px;
            background:blue;
            margin: 0 auto;
            text-align: center;
            padding: 20px 0;
        }
<div class="fixed">
  <div class="content">
     This is my content
  </div>
</div>


2

这个解决方案满足以下条件:

  1. 可以在父元素上使用百分比宽度
  2. 窗口大小调整后仍然有效
  3. 标题下面的内容永远不会无法访问

据我所知,如果没有Javascript,这些条件是无法满足的(很遗憾)。

这个解决方案使用了jQuery,但也可以轻松转换为原生JS:

function fixedHeader(){
  $(this).width($("#wrapper").width());
  $("#header-filler").height($("#header-fixed").outerHeight());
}

$(window).resize(function() {
  fixedHeader();
});

fixedHeader();
#header-fixed{
  position: fixed;
  background-color: white;
  top: 0;
}
#header-filler{
  width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="wrapper">
<div id="header-fixed">
  This is a nifty header! works even when resizing the window causing a line break
</div>
<div id="header-filler"></div>

[start fluff]<br>
a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>
a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>
a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>
[end fluff]

</div>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接