如何设置边距或填充为父容器高度的百分比?

我一直在绞尽脑汁用下面的方法在css中创建一个垂直对齐

.base{
background-color:green;
width:200px;
height:200px;
overflow:auto;
position:relative;
}


.vert-align{
padding-top:50%;
height:50%;
}
<!-- and used the following div structure. -->


<div class="base">
<div class="vert-align">
Content Here
</div>
</div>

虽然这似乎适用于这种情况,但我惊讶地发现,当我增加或减少基本div的宽度时,垂直对齐会断开。我期望当我设置padding-top属性时,它会将填充作为父容器高度的百分比,这在我们的例子中是基础,但上面的50%值是作为宽度的百分比计算的。:(

是否有一种方法来设置填充和/或边缘作为高度的百分比,而不诉诸于使用JavaScript?

265345 次浏览

50%的填充不会居中你的子元素,它会把它放在中心下方。我觉得你需要25%的缓冲。也许你只是因为你的内容越来越高而没有空间了?你有没有试过设置边距顶部而不是填充顶部?

编辑:没关系,w3schools网站说

以包含元素宽度的百分比为单位指定填充

也许它总是使用宽度?我从没注意过。

你所做的事情可以通过display:table来实现(至少对于现代浏览器是这样)。这里将解释该技术

修正是,是的,垂直填充和空白是相对于宽度,但topbottom < em >。< / em >

因此,只需将一个div放在另一个div中,并在内部div中使用top:50%之类的东西(记住,如果position仍然不起作用,则很重要)

这里有两个选项来模拟所需的行为。不是一般的解决方案,但在某些情况下可能有帮助。这里的垂直间距是根据外部元素的大小计算的,而不是它的父元素,但是这个大小本身可以相对于父元素,这样间距也是相对的。

<div id="outer">
<div id="inner">
content
</div>
</div>

第一种选择:使用伪元素,这里的垂直和水平间距是相对于外层的。演示

#outer::before, #outer::after {
display: block;
content: "";
height: 10%;
}
#inner {
height: 80%;
margin-left: 10%;
margin-right: 10%;
}

将水平间距移动到外部元素使其相对于外部元素的父元素。演示

#outer {
padding-left: 10%;
padding-right: 10%;
}

第二种选择:使用绝对定位。演示

#outer {
position: relative;
}
#inner {
position: absolute;
left: 10%;
right: 10%;
top: 10%;
bottom: 10%;
}

将一行文本居中的另一种方法是:

.parent{
position: relative;
}


.child{
position: absolute;
top: 50%;
line-height: 0;
}

或者只是

.parent{
overflow: hidden; /* if this ins't here the parent will adopt the 50% margin of the child */
}


.child{
margin-top: 50%;
line-height: 0;
}

一个稍微不同的问题的答案:你可以使用vh单位将元素填充到视窗的中心:

.centerme {
margin-top: 50vh;
background: red;
}


<div class="centerme">middle</div>

为了使子元素的位置绝对依赖于它的父元素,你需要设置父元素的相对位置和子元素的绝对位置。

然后在子元素上'top'是相对于父元素的高度。所以你还需要把孩子的身高向上平移50%。

.
.base{
background-color: green;
width: 200px;
height: 200px;
overflow: auto;
position: relative;
}
    

.vert-align {
position: absolute;
top: 50%;
transform: translate(0, -50%);
}
    <div class="base">
<div class="vert-align">
Content Here
</div>
</div>

还有一种解决方案是使用伸缩盒。

.
.base{
background-color:green;
width: 200px;
height: 200px;
overflow: auto;
display: flex;
align-items: center;
}
<div class="base">
<div class="vert-align">
Content Here
</div>
</div>

你会发现两者都有优点/缺点。

这是一个非常有趣的bug。(在我看来,这是一个bug)很好的发现!

关于如何来设置它,我推荐Camilo Martin的答案。但是对于为什么,如果你们不介意的话,我想解释一下。


CSS规范中我发现:

< p > “填充” < br > 百分比:为包含块的宽度

这很奇怪,不过没关系。

因此,使用父对象width: 210px和子对象padding-top: 50%,我得到了padding-top: 96.5px的计算/计算值——这不是预期的105px

这是因为在Windows中(我不确定其他操作系统),普通滚动条的大小默认为17px × 100%(或100% × 17px为水平条)。这些17px被减去之前计算50%,因此是50% of 193px = 96.5px

这可以通过writing-mode属性来实现。如果你将元素的writing-mode设置为垂直书写模式,例如vertical-lr,它的后代在两个维度上的填充和边距的百分比值将相对于高度而不是宽度。

规范:

……在CSS2.1中,边缘和填充属性的百分比总是根据包含块的宽度计算,在CSS3中则根据包含块的内联大小计算。

内联大小的定义:

行内尺寸:横写时为物理宽度(水平尺寸),竖写时为物理高度(垂直尺寸)。

例如,对于一个可调整大小的元素,其中水平边距相对于宽度,垂直边距相对于高度。

.resize {
width: 400px;
height: 200px;
resize: both;
overflow: hidden;
}


.outer {
height: 100%;
background-color: red;
}


.middle {
writing-mode: vertical-lr;
margin: 0 10%;
width: 80%;
height: 100%;
background-color: yellow;
}


.inner {
writing-mode: horizontal-tb;
margin: 10% 0;
width: 100%;
height: 80%;
background-color: blue;
}
<div class="resize">
<div class="outer">
<div class="middle">
<div class="inner"></div>
</div>
</div>
</div>

如果您希望元素的纵横比保持不变,但希望其大小与高度相关,而不是与宽度相关,那么使用垂直书写模式特别有用。