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


236

我一直在绞尽脑汁使用以下命令在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?

Answers:


223

解决方法是,是的,垂直填充和边距与宽度有关,但top与宽度bottom 无关。

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


3
top根据浏览器/窗口的高度调整大小非常有用。在该div下方有一个div怎么样?您如何clear将第二个div放在下移top:50%?? 的div之下?
Federico

学习新东西。之前不知道垂直填充和边距是相对于宽度的。谢谢。
shaosh 2014年

5
也可以添加具有设置的百分比高度的'spacer'div。似乎有点脏,但可以。看到这个答案
WCByrne

4
永无止境的@%!^?为什么垂直边距和填充相对于宽度?什么?为什么做出这个决定?
临时用户名

与下面的alain答案相比,您的答案获得了极大的反对,后者给出了一个通用的解决方案,我发现它非常有用,几乎没有看到。top: 50%如果您需要按自己的中心对齐内容,则不是很有用。
okovko '18

35

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

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

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

为什么这个答案没有得到较高的投票?使用vh有什么问题吗?
AlanH '16

3
这是因为这不是针对原始问题的答案,这是一个有用的技巧,仅在少数相关情况下有效。
willoller '16

使用率vh几乎与百分比相同...在某些情况下甚至更糟。此答案与问题无关
vsync

33

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

<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%;
}

10

为了使子元素绝对位于其父元素的位置,您需要在父元素上设置相对位置,在子元素上设置绝对位置。

然后在子元素上,“ 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>

您会发现两者的优点/缺点。


1
使用平移是相对于其自身大小垂直移动元素的唯一实际方法。
伊兰·戈尔丁

谢谢你 这应该是选择的答案。
Wessam El Mahdy

6

这可以通过该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>

在您希望元素的长宽比保持恒定,但要使其尺寸与高度而不是宽度成比例的情况下,使用垂直书写模式特别有用。


这是IMO,将是更优雅的解决方案,但是(截至2018-05-05),垂直书写模式没有得到很好的支持。希望很快会改变。
扎纳罗克

1
@zanerock我相当确定MDN兼容表已过时。例如,它说Safari需要-webkit-前缀,但是根据caniuse的说法,自Safari 11起,它就不需要前缀了。您是否曾在任何无法使用它的浏览器中尝试过该前缀?
詹姆斯·T

1
不,我不得不承认我只是认为它很好,甚至是自动化的。
zanerock

4

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

.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;
}

0

50%的填充不会使您的孩子居中,它将放置在中心下方。我认为您真的希望填充率达到25%。也许随着内容的增加,您的空间即将用完?您是否也尝试过设置margin-top而不是padding-top?

编辑:没关系,w3schools网站说

%指定包含元素宽度的百分比的填充

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

可以使用display:table来实现您正在做的事情(至少对于现代浏览器而言)。该技术在这里进行说明


1
谢谢斯普利夫。我了解我的50%不会将div的内容居中。实际上,我只有一行文字需要垂直居中。非常感谢您提供的链接!
瑞安

3
如果只是一行文本,您是否考虑过使用一个可笑的大字体line-height,即使行高为200px?
SpliFF'2

@Ryan可将文本垂直居中,请参见stackoverflow.com/questions/8865458/…–
用户

您的链接已断开
端庄的

0

这是一个非常有趣的错误。(依我看,这仍然是一个错误)很高兴找到!

关于如何设置呢,我会建议卡米洛·马丁的答案。但是关于原因,如果你们不介意的话,我想解释一下。


CSS规范中,我发现:

“填充”
百分比: 指包含块的宽度

……这很奇怪,但是还可以。

因此,在有父母width: 210px和孩子的情况下padding-top: 50%,我得到的计算/计算值是padding-top: 96.5px–这不是预期的105px

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


没有为规范中的一个原因,而这更好的解释它:hongkiat.com/blog/calculate-css-percentage-margins
manikanta
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.