如何让子div始终适应父div?

82

在不使用JavaScript的情况下,是否有一种方法可以使子div延伸到其父元素的边框,而不超出这些边框,当您事先无法知道父div的大小时?

以下是演示我的问题的样式/标记。如果您将其加载到浏览器中,您将看到#two#three超出了它们的父级#one,并导致滚动条出现。

我的问题不是滚动条,而是我需要学习如何告诉子div占据剩余的宽度或高度,而不是父级的全部高度或宽度。

<html>
   <head>
      <style>
         html,
         body {
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
         }
         .border {
            border: 1px solid black;
         }
         .margin {
            margin: 5px;
         }
         #one {
            width: 100%;
            height: 100%;
         }
         #two {
            width: 100%;
            height: 50px;
         }
         #three {
            width: 100px;
            height: 100%;
         }
      </style>
   </head>
   <body>
      <div id="one" class="border">
         <div id="two" class="border margin"></div>
         <div id="three" class="border margin"></div>
      </div>
   </body>
</html>

11个回答

27

我遇到了类似的问题,但是我的情况是,我在 div 中有内容,高度会超出父 div 的边界。当发生这种情况时,我希望它自动滚动。我通过使用以下代码来实现:

.vscrolling_container { height: 100%; overflow: auto; }

25

您可以使用display: inline-block;

希望对您有所帮助。


我尝试过这个方法,但它并没有解决 #two 和 #three 超出 #one 边界的问题。相反,将 'overflow' 添加到 #one 的样式中解决了这个问题。 - goldenriver4422

10
在你的例子中,你无法这样做: 5px边距 被添加到div#twodiv#three的边界框中,有效地使它们的宽度和高度为父元素的100% + 5像素,这将导致溢出。
您可以在父元素上使用 padding 来确保其边框内有5px的空间:
<style>
    html, body {width:100%;height:100%;margin:0;padding:0;}
    .border {border:1px solid black;}
    #one {padding:5px;width:500px;height:300px;}
    #two {width:100%;height:50px;}
    #three {width:100px;height:100%;}
</style>

编辑:在测试中,从div#two中删除width:100%实际上会使其作为div正常工作,因为div是块级元素,并且默认情况下始终填充其父元素的宽度。如果您想使用边距,这应该清除您的第一个情况。


1
或者,坚持使用百分比:使用百分比边距和百分比宽度/高度也可以解决问题,因为您正在使用相同的“单位”。不过,那个100%的高度会让您感到困扰,因为其中还有另一个子元素占用了父元素的一部分高度。 - ajm
这并不完全可行,#three中的height: 100%将始终溢出父容器。 - Matt Bridges
是的,就像我在评论中所说的那样,100%的高度每次都会溢出。在#two和#three上添加类似于2%边距,10%高度的#two和82%高度的#three之类的内容可能会奏效。 - ajm
正如所述,这并未解决使用垂直空间的子div的问题,从而将其他子元素推出父元素。 - Tim Sheiner

7
这个问题通常采用以下两种技术解决:
  1. 绝对定位
  2. 表格样式
根据您提供的HTML代码,以下是使用绝对定位的解决方案:

body #one {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  width: auto;
  height: auto;
}
body #two {
  width: auto;  
}
body #three {
  position: absolute;
  top: 60px;
  bottom: 0;
  height: auto;
}
<html>
<head>
<style>
html, body {width:100%;height:100%;margin:0;padding:0;}
.border {border:1px solid black;}
.margin { margin:5px;}
#one {width:100%;height:100%;}
#two {width:100%;height:50px;}
#three {width:100px;height:100%;}
</style>
</head>
<body>
 <div id="one" class="border">
  <div id="two" class="border margin"></div>
  <div id="three" class="border margin"></div>
 </div>
</body

尽管有人对此提出批评,但您始终可以直接使用表格、tr和td元素来完成工作。如果您更喜欢使用CSS,则没有类似于colspan的等效项,因此您可能最终会使用嵌套表格。以下是一个示例:

html, body {
  height: 100%;
  margin: 0;
  padding: 0;
  width: 100%;
}
#one {
  box-sizing: border-box;
  display: table;
  height: 100%;
  overflow: hidden;
  width: 100%;
  border: 1px solid black;
}
#two {
    box-sizing: border-box;
    display: table;
    height: 50px;
    padding: 5px;
    width: 100%;
}
#three {
  box-sizing: border-box;
  display: table;
  height: 100%;
  padding-bottom: 60px;
  padding-left: 5px;
  
}
#four {
  display: table-cell;
  border: 1px solid black;
}
#five {
  display: table-cell;
  width: 100px;
  border: 1px solid black;
}
#six {
  display: table-cell;  
}
<html>
 <div id="one">
     <div id="two">
            <div id="four"></div>
        </div>
        <div id="three">
            <div id="five"></div>
            <div id="six"></div>
        </div>
 </div>
  </html>


3

对于宽度,很简单,只需删除 width: 100% 规则。默认情况下,div 将会被拉伸以适应父容器。

高度不太简单。您可以使用类似等高列技巧的方法。

html, body {width:100%;height:100%;margin:0;padding:0;}
.border {border:1px solid black;}
.margin { margin:5px;}
#one {width:500px;height:300px; overflow: hidden;}
#two {height:50px;}
#three {width:100px; padding-bottom: 30000px; margin-bottom: -30000px;}

1
这个也截断了长的子div,但没有使它缩短以适应父级底部所期望的边距。 - Tim Sheiner

3
我觉得我有针对你的问题的解决方案,假设你可以在你的项目中使用flexbox。你想要做的是将#one设置为flexbox,使用display: flex并使用flex-direction: column使其成为列对齐方式。最初的回答:

html,
body {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
}

.border {
  border: 1px solid black;
}

.margin {
  margin: 5px;
}

#one {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
}

#two {
  height: 50px;
}

#three {
  width: 100px;
  height: 100%;
}
<html>

<head>
</head>

<body>
  <div id="one" class="border">
    <div id="two" class="border margin"></div>
    <div id="three" class="border margin"></div>
  </div>
</body>

</html>


2

你可以使用继承(inherit)

#one {width:500px;height:300px;}
#two {width:inherit;height:inherit;}
#three {width:inherit;height:inherit;}

我认为那样行不通。至少,如果你只做这些改变的话。 - thebrokencube
1
当使用这些样式时,我无法观察到与原始内容的任何变化。 - Tim Sheiner

2

请确保最外层的div具有以下CSS属性:

.outer {
  /* ... */
  height: auto;
  overflow: hidden;
  /* ... */
}

1
当我尝试这个时,子div并没有适应,而是被切掉了,或许还有其他更好的建议吗? - Surya

1

如果我理解你的意思正确,最简单的方法是将子元素浮动。例如:

#one { width: 500px; height: 1%; overflow: hidden; background: red; }
#two { float: left; width: 250px; height: 400px; background: aqua; }
#two { float: left; width: 250px; height: 200px; background: lime; }

在父元素上设置高度/宽度和溢出为auto或hidden会导致其包含任何浮动的子元素。

请注意,overflow:hidden;有时可能会导致内容被截断,这种情况下,您可能需要尝试这种替代方法:

http://www.positioniseverything.net/easyclearing.html


这会强制你设置包含元素的高度,而不是设置容器的高度并使包含元素拉伸以适应。 - Matt Bridges
这种方法有些可行,但是会截断较长子元素的底部,并不能让子元素“适应”父元素。 - Tim Sheiner

1

总的来说,我认为这个问题的答案是没有解决方案。想要实现我想要的行为,唯一的方法就是使用JavaScript。


看我的答案。我实际上提供了两种不同的方法来完成它。 - Ryan
通常情况下,表格可以轻松地完成div所需的跳跃操作。不幸的是,div在CSS中的设计非常糟糕。 - fyngyrz

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