有没有一种方法可以使用CSS使子DIV的宽度比父DIV更宽?

330

有没有一种方法可以在父容器DIV中放置一个子DIV,使其宽度大于其父容器。子DIV的宽度需要与浏览器视口相同。

请参见下面的示例: enter image description here

子DIV必须保留为父div的子级。我知道我可以设置子div上的任意负边距来使其变宽,但我无法弄清楚如何使其基本上成为浏览器的100%宽度。

我知道我可以这样做:

.child-div{
    margin-left: -100px;
    margin-right: -100px;
}

但是我需要子元素和浏览器一样宽,而浏览器的宽度是动态的。

更新

谢谢你们的答案,目前最接近的答案是将子元素的 position 属性设置为 absolute,并将左右属性都设置为 0。

我下一个问题是父元素有 position: relative 属性,这意味着左右属性仍然相对于父级 div 而不是浏览器,请看这个示例:jsfiddle.net/v2Tja/2

我不能去掉父元素的 position: relative 属性,否则会影响其他东西。


你的需求并不是很合理。 "子div" 必须保持为父div的子元素,但是父div却有 position: relative?你需要 position: relative 做什么?我想我想问的是:你想做什么? - thirtydot
@Camsoft 你看到我在我的回答中的评论了吗?那对我有用,还请查看我的网站http://edocuments.co.uk/,它以不同的方式实现了你想要做的事情。 - Blowsie
1
@Camsoft 此外,您的解决方案中实际上不应该需要任何 jQuery / JS。 - Blowsie
15个回答

354

这是一个通用的解决方案,可以使子元素保持在文档流中:

.child {
  width: 100vw;
  position: relative;
  left: calc(-50vw + 50%);
}

我们将子元素的width设置为填充整个视口宽度,然后通过将其向左移动半个视口距离减去父元素宽度的50%以使其与屏幕边缘相遇。

Demo:

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  overflow-x: hidden;
}

.parent {
  max-width: 400px;
  margin: 0 auto;
  padding: 1rem;
  position: relative;
  background-color: darkgrey;
}

.child {
  width: 100vw;
  position: relative;
  left: calc(-50vw + 50%);

  height: 100px;
  border: 3px solid red;
  background-color: lightgrey;
}
<div class="parent">
  Pre
  <div class="child">Child</div>
  Post
</div>

vwcalc()的浏览器支持通常可以视为IE9及更高版本。

注意:这假定了盒子模型设置为border-box。如果没有设置border-box,则还必须减去填充和边框,使此解决方案变得混乱。

注意:建议隐藏你的滚动容器的水平溢出,因为某些浏览器可能会选择显示水平滚动条,尽管没有溢出。


4
我知道,它确实在IE9中起作用。+1很好。 - CatShoes
14
非常感谢,这正是我所需要的。我认为这个答案比被采纳的更好,因为它不会破坏文档的结构流程。 - Rémi
23
VW 不好用。如果你的页面有垂直滚动条,那么 100vw 将会出现水平滚动条。 - Sunny
2
似乎这只在一级下起作用。是否有一种方法可以使其不受子元素拥有多少父元素的影响而起作用? - mythofechelon
3
这是将更宽的子元素放入position: relative父元素的正确答案! - Hanfei Sun
显示剩余10条评论

140

使用绝对定位

.child-div {
    position:absolute;
    left:0;
    right:0;
}

14
好的,下一个问题是,如果父元素或其他祖先元素有布局,即 position: relative,请参见:http://jsfiddle.net/v2Tja/2/ - Camsoft
1
另外再加一个父级 div,将其 position 值设为 static,然后在其中再嵌套一个 div,将其 position 值设为 relative,你觉得这样怎么样?http://jsfiddle.net/blowsie/v2Tja/3/ - Blowsie
11
是否有一种方法可以使 .child-div 的高度保持自动,并且仍然正确地放置在下方? - Philippe Gilbert
2
请勿将父级 div 设置为 "overflow:hidden" ^^ - chris
1
最佳答案。没有滚动条问题。高跨浏览器兼容性。谢谢!!! - jMike
显示剩余2条评论

26

我为解决这个问题搜寻了很长时间。理想情况下,我们希望子元素大于父元素,但是事先并不知道父元素的约束条件。

最终我在这里找到了一个精彩的通用答案。 以下是它的原话:

这里的思路是:使用 left: 50% 将容器推到浏览器窗口的正中间,然后再使用负 -50vw 边距将其拉回到左侧边缘。

.child-div {
  width: 100vw;
  position: relative;
  left: 50%;
  right: 50%;
  margin-left: -50vw;
  margin-right: -50vw;
}

1
我发现如果我想让它占据视口宽度的90%,我可以使用上面的代码,但将宽度设置为90vw。此外,似乎margin-right在任何情况下都没有效果。 - Jason Dufair
不得不更改margin-left和right的值,因为我的包装器是视口宽度的80%。所以在我的情况下,它必须是margin-left:-10vw和margin-right:-10vw,然后它完美地工作了!谢谢! - Timotheus0106
2
这是一个非常出色的答案!谢谢。 - cullanrocks
这是一个非常聪明的答案,工作得很好! - Saunved Mutalik

8
Based on your suggestion (using negative margins), I have tried a similar method that uses percentage units to adjust for dynamic browser width:
HTML:
<div class="grandparent">
    <div class="parent">
        <div class="child">
            <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolore neque repellat ipsum natus magni soluta explicabo architecto, molestias laboriosam rerum. Tempore eos labore temporibus alias necessitatibus illum enim, est harum perspiciatis, sit, totam earum corrupti placeat architecto aut minus dignissimos mollitia asperiores sint ea. Libero hic laudantium, ipsam nostrum earum distinctio. Cum expedita, ratione, accusamus dicta similique distinctio est dolore assumenda soluta dolorem quisquam ex possimus aliquid provident quo? Enim tempora quo cupiditate eveniet aperiam.</p>
        </div>
    </div>
</div>

CSS:

.child-div{
   margin: 0 -100%;
   padding: 0 -100%;
}

.parent {
    width: 60%;
    background-color: red;
    margin: 0 auto;
    padding: 50px;
    position:relative;
}

.grandparent {
        overflow-x:hidden;
        background-color: blue;
        width: 100%;
        position:relative;
    }

负边距会让内容流出父级DIV。因此,我设置了padding: 0 100%;将内容推回到子DIV的原始边界。
负边距还会使.child-div的总宽度扩展到浏览器视口之外,导致水平滚动。因此,我们需要通过在祖父级DIV(即父级Div的父级)中应用overflow-x: hidden来剪切超出的宽度: 这里是JSfiddle 我尝试过Nils Kaspersson的left: calc(-50vw + 50%);在Chrome和FF中运行得非常好(还不确定IE),直到我发现Safari浏览器无法正确处理它。希望他们能尽快修复这个问题,因为我实际上很喜欢这种简单的方法。
这也可能解决您所遇到的父级DIV元素必须为position:relative的问题。
这种解决方法的两个缺点是:
  • 需要额外的标记(例如祖先元素(就像旧的表格垂直对齐方法一样...)
  • 子DIV的左右边框永远不会显示,因为它们在浏览器视口之外。

如果您发现此方法存在任何问题,请告诉我。希望能帮到您。


6

Flexbox可以用三行CSS代码让一个子元素比其父元素更宽。

只需设置子元素的displaymargin-leftwidth属性。其中margin-left取决于子元素的width。公式为:

margin-left: calc(-.5 * var(--child-width) + 50%);

CSS变量可用于避免手动计算左边距。 示例1:手动计算

.parent {
  background-color: aqua;
  height: 50vh;
  margin-left: auto;
  margin-right: auto;
  width: 50vw;
}

.child {
  background-color: pink;
  display: flex;
}

.wide {
  margin-left: calc(-37.5vw + 50%);
  width: 75vw;
}

.full {
  margin-left: calc(-50vw + 50%);
  width: 100vw;
}
<div class="parent">
  <div>
    parent
  </div>
  <div class="child wide">
    75vw
  </div>
  <div class="child full">
    100vw
  </div>
</div>

示例#2:使用CSS变量

.parent {
  background-color: aqua;
  height: 50vh;
  margin-left: auto;
  margin-right: auto;
  width: 50vw;
}

.child {
  background-color: pink;
  display: flex;
  margin-left: calc(-.5 * var(--child-width) + 50%);
  width: var(--child-width);
}

.wide {
  --child-width: 75vw;
}

.full {
  --child-width: 100vw;
}
<div class="parent">
  <div>
    parent
  </div>
  <div class="child wide">
    75vw
  </div>
  <div class="child full">
    100vw
  </div>
</div>


4
我使用了这个:
HTML
<div class="container">
 <div class="parent">
  <div class="child">
   <div class="inner-container"></div>
  </div>
 </div>
</div>

CSS

.container {
  overflow-x: hidden;
}

.child {
  position: relative;
  width: 200%;
  left: -50%;
}

.inner-container{
  max-width: 1179px;
  margin:0 auto;
}

3

我尝试了您提供的一些解决方案。其中这一个:

margin: 0px -100%;
padding: 0 100%;

由于我们不需要额外的CSS来适应较小的屏幕,这是迄今为止最好的选择。我制作了一个CodePen来展示结果:我使用带有背景图像的父Div和具有内部内容的子Div。

https://codepen.io/yuyazz/pen/BaoqBBq


2
使子 div 与内容一样宽,尝试这样做:

使用以下代码:

.child{
    position:absolute;
    left:0;
    overflow:visible;
    white-space:nowrap;
}

2
我遇到了类似的问题。子元素的内容应保留在父元素中,而背景必须延伸到整个视口宽度。
我通过使子元素的position: relative并向其添加一个伪元素(:before),并将其设置为position: absolute; top: 0; bottom: 0; width: 4000px; left: -1000px;来解决此问题。 伪元素作为伪背景元素停留在实际子元素后面。这适用于所有浏览器(即使是IE8+和Safari 6+ - 没有测试旧版本)。
小例子fiddle:http://jsfiddle.net/vccv39j9/

这似乎可以工作,但它会导致浏览器显示一个水平滚动条,因为宽度为4000px。有什么解决方法可以使伪元素保持在视口的宽度内? - Aaron Hudon
当然,您必须将页面包装的div的body或设置为overflow-x: hidden - Seika85

1

在 Nils Kaspersson 的解决方案基础上,我也考虑了垂直滚动条的宽度。我使用 16px 作为示例,从视口宽度中减去此宽度。这将避免水平滚动条出现。

width: calc(100vw - 16px);
left: calc(-1 * (((100vw - 16px) - 100%) / 2));

1
我认为你需要减去的 16px 是因为浏览器的默认边距/填充导致了水平滚动条,而不是减去它,只需使用这个 html,body{ margin:0; padding:0 },这样你就不需要为 16px 进行额外的计算。 - Mi-Creativity
这是当页面内容较长并且超出折叠区域时,滚动条会自动出现的情况。当内容在折叠区域内时,这是不必要的。只有当我知道页面内容将会很长并且滚动条确实会出现时,我才会将16px添加到公式中。 - A-Zone
我认为它在移动设备上不会起作用。移动设备没有滚动条。 - hjchin

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