使用HTML/CSS,我如何制作一个宽度和/或高度为其父元素的100%且仍具有适当填充或边距的元素?

所谓“恰当”,我的意思是,如果我的父元素是200px高,并且我指定height=100%,padding=5px,我会期望得到一个190px高的元素,其所有边的border=5px都在父元素的中心。

现在,我知道这不是标准盒子模型指定的工作方式(尽管我想知道为什么,确切地说……),所以显而易见的答案不起作用:

#myDiv {
    width: 100%
    height: 100%;
    padding: 5px;
}

但在我看来,必须有某种方法能够可靠地为任意大小的父母产生这种效果。有人知道完成这项(看似简单)任务的方法吗?

哦,我对IE兼容性不是很感兴趣,所以(希望)这会让事情变得更容易。

编辑:既然有人要求举一个例子,这里是我能想到的最简单的例子:

<html style="height: 100%">
    <body style="height: 100%">
        <div style="background-color: black; height: 100%; padding: 25px"></div>
    </body>
</html>

接下来的挑战是让黑框在所有边缘都显示25像素的填充,而页面不会增长到需要滚动条的程度。


这是CSS的一个彻头彻尾的白痴——我还没有理解其中的原因(如果有人知道,请解释)。

100%表示容器高度的100%,其中添加了任何边距、边框和填充。因此,实际上不可能获得一个填充其父级并且具有边距、边框或填充的容器。

另外,众所周知,浏览器之间的设置高度也不一致。


自从我发布这篇文章以来,我学到的另一件事是,百分比是相对于容器长度的,也就是说,它的宽度,这使得百分比对于高度来说更没有价值。

如今,vh和vw视口单元更有用,但对于除了顶级容器之外的任何其他对象来说仍然不是特别有用。


根据w3c规范,高度是指可视区域的高度,例如在1280x1024像素分辨率的监视器上,100%高度=1024像素。

最小高度是指包含内容的页面的总高度,因此在内容大于1024px的页面上最小高度:100%将拉伸以包含所有内容。

另一个问题是,除了ie6之外,大多数现代浏览器都在高度和宽度上添加了填充和边框(ie6实际上很符合逻辑,但不符合规范)。这就是所谓的盒子模型。因此,如果您指定

min-height: 100%;
padding: 5px; 

它实际上会给你100%+5px+5px的高度。要解决这个问题,您需要一个包装容器。

<style>
    .FullHeight { 
       height: auto !important; /* ie 6 will ignore this */
       height: 100%;            /* ie 6 will use this instead of min-height */
       min-height: 100%;        /* ie 6 will ignore this */
    }

    .Padded {
       padding: 5px;
    }
</style>

<div class="FullHeight">
   <div class="Padded">
      Hello i am padded.
   </div
</div>

我通过阅读“PRO HTML和CSS设计模式”学会了如何做这些事情。display:block是div的默认显示值,但我喜欢使其显式。容器必须是正确的类型;位置属性是固定的、相对的或绝对的。

.拉伸到边距{显示:块;位置:绝对;高度:自动;底部:0;顶部:0;左:0;右:0;页边空白:20px;边距底部:20px;右边距:80px;左边距:80px;背景色:绿色;}<div class=“stretchedToMargin”>你好,世界</div>

被Nooshu的评论弄糊涂了


解决方案是完全不使用高度和宽度!使用顶部、左侧、右侧和底部连接内框,然后添加边距。

.box{margin:8px;位置:绝对;顶部:0;左侧:0;右侧:0;底部:0}<div class=“box”style=“background:black”><div class=“box”style=“background:green”><div class=“box”style=“background:lightblue”>这将显示三个嵌套框。尝试调整浏览器大小以查看它们是否保持正确嵌套。</div></div></div>


CSS3中有一个新属性,您可以使用它来更改长方体模型计算宽度/高度的方式,称为长方体大小。

通过将此属性设置为值“border box”,可以在添加填充或边框时使应用它的任何元素都不会拉伸。如果你定义了100px宽,10px填充的东西,它仍然是100px宽。

box-sizing: border-box;

有关浏览器支持,请参阅此处。它不适用于IE7或更低版本,但是,我相信Dean Edward的IE7.js为它添加了支持


  <style type="text/css">
.stretchedToMargin {
    position:absolute;
    width:100%;
    height:100%;

}
</style>

弗兰克的例子让我有点困惑——这在我的情况下不起作用,因为我对定位还不够了解。需要注意的是,父容器元素需要有一个非静态位置(他提到了这一点,但我忽略了它,在他的示例中没有)。

下面是一个示例,其中子对象(给定填充和边框)使用绝对定位来100%填充父对象。父级使用相对定位,以便在保持正常流的同时为子级的位置提供参考点-下一个元素“更多内容”不受影响:

#box {
    position: relative;
    height: 300px;
    width: 600px;
}

#box p {
    position: absolute;
    border-style: dashed;
    padding: 1em;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
}
<div id="box">
  <p>100% height and width!</p>
</div>
<div id="more-content">
</div>

快速学习CSS定位的有用链接


另一个解决方案是使用显示:表,它具有不同的框模型行为。

您可以为父级设置高度和宽度,并在不展开的情况下添加填充。子级的高度和宽度减去填充后为100%。

JSBIN公司

另一种选择是使用方框大小属性。两者唯一的问题是它们在IE7中都不起作用。


更好的方法是使用calc()属性。因此,您的案例看起来像:

#myDiv {
    width: calc(100% - 10px);
    height: calc(100% - 10px);
    padding: 5px;
}

简单、干净,没有变通办法。只需确保不要忘记值和运算符之间的空格(例如(100%-5px),这会破坏语法。享受


另一个解决方案:您可以使用百分比单位作为边距和大小。例如:

.fullWidthPlusMargin {
    width: 98%;
    margin: 1%;
}

这里的主要问题是,边距将随着父元素的大小而略微增加/减少。大概您更喜欢的功能是边距保持不变,子元素增长/收缩以填充间距变化。因此,取决于你需要多紧的显示器,这可能是有问题的。(我也会选择更小的利润率,比如0.3%)。


1.带衬垫的全高

正文{边距:0;}.容器{最小高度:100vh;填充:50px;框大小调整:边框框;背景:银色;}<div class=“container”>你好世界</分区>

2.带边距的全高

正文{边距:0;}.容器{最小高度:计算(100vh-100px);边距:50px;背景:银色;}<div class=“container”>你好世界</分区>

3.带边框的全高

正文{边距:0;}.容器{最小高度:100vh;边框:50px实心粉色;框大小调整:边框框;背景:银色;}<div class=“container”>你好世界</分区>


div周围的边框,而不是页面正文边距

另一个解决方案-我只是希望在页面边缘周围有一个简单的边框,当内容小于此值时,我希望有100%的高度。

边框不起作用,固定的位置似乎不适合这种简单的需求。

我最终在容器中添加了一个边框,而不是依赖页面主体的边距——它看起来像这样:

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

.container {
    width: 100%;
    min-height: 100%;
    border: 8px solid #564333;
}

使用flexbox(在IE11上工作)的解决方案:(或jsfiddle上的视图)

<html>
  <style>
    html, body {
      height: 100%; /* fix for IE11, not needed for chrome/ff */
      margin: 0; /* CSS-reset for chrome */
    }
  </style>
  <body style="display: flex;">
    <div style="background-color: black; flex: 1; margin: 25px;"></div>
  </body>
</html>

(CSS重置对于实际问题并不一定重要。)

重要的部分是flex:1(与父级的display:flex结合使用)。有趣的是,我所知道的关于Flex属性如何工作的最合理的解释来自一个react原生文档,所以我还是引用了它:

(…)flex:1,告诉组件填充所有可用空间,在具有相同父组件的其他组件之间均匀共享


这是display:block的默认行为。2020年修复它的最快方法是设置父元素的display:'flex'和填充,例如20px,那么它的所有子元素将具有相对于其高度的100%高度。


添加-webkit和-moz更合适

-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;