ChatGPT解决这个技术问题 Extra ChatGPT

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

我一直在绞尽脑汁使用以下方法在 css 中创建垂直对齐

.base{ 背景颜色:绿色;宽度:200px;高度:200px;溢出:自动;位置:相对; } .vert-align{ 填充顶部:50%;高度:50%; }

内容在这里

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

有没有办法将填充和/或边距设置为高度的百分比,而无需使用 JavaScript?


T
TylerH

解决方法是,是的,垂直填充和边距与宽度相关,但 topbottom 不是。

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


top 非常适合根据浏览器/窗口高度调整大小。在那个div下面有一个div怎么样?你怎么能 clear 第二个 div 位于由 top:50% 向下移动的 div 下?
学习新东西。以前不知道垂直填充和边距是相对于宽度的。谢谢你。
也可以添加具有设定百分比高度的“间隔”div。看起来有点脏,但它的工作原理。见this answer
什么是永恒的@%!^?为什么垂直边距和填充相对于宽度?什么?为什么会做出这个决定?
与下面的 alain 的回答相比,您的回答得到了极其不成比例的支持,后者给出了一个通用的解决方案,我发现它非常有帮助,几乎没有看到。如果您需要将内容按自己的中心对齐,top: 50% 就不是很有用。
w
willoller

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

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

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

为什么这个答案的票数不高?使用 vh 有什么问题吗?
这是因为它不是针对原始问题量身定制的答案,它是一个有用的技巧,仅在少数相关情况下有效。
使用 vh 几乎与百分比相同......在某些情况下甚至更糟。这个答案与问题无关
u
user

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

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

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

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

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

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

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

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

a
alain

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

然后在子元素上的“顶部”是相对于父元素的高度。因此,您还需要将孩子向上“平移”其自身高度的 50%。

.base{ 背景颜色:绿色;宽度:200px;高度:200px;溢出:自动;位置:相对; } .vert-align { 位置:绝对;最高:50%;变换:翻译(0,-50%); }

内容在这里

还有另一种使用弹性盒的解决方案。

.base{ 背景颜色:绿色;宽度:200px;高度:200px;溢出:自动;显示:弯曲;对齐项目:居中; }

内容在这里

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


使用 translate 是相对于其自身大小垂直移动元素的唯一真正方法。
谢谢你。这应该是选择的答案。
J
James T

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

spec

. . . margin 和 padding 属性的百分比,在 CSS2.1 中总是根据包含块的宽度计算,在 CSS3 中是根据包含块的内联大小计算的。

inline size的定义:

内联尺寸的测量:在水平书写模式下是指物理宽度(水平尺寸),在垂直书写模式下是指物理高度(垂直尺寸)。

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

.resize { 宽度:400px;高度:200px;调整大小:两者;溢出:隐藏; } .outer { 高度:100%;背景颜色:红色; } .middle { 写作模式:vertical-lr;保证金:0 10%;宽度:80%;高度:100%;背景颜色:黄色; } .inner { 写作模式:水平-tb;保证金:10% 0;宽度:100%;高度:80%;背景颜色:蓝色; }

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


这是,IMO,将是更优雅的解决方案,但是(截至 2018-05-05),vertical writing modes aren't well supported。希望这种情况很快就会改变。
@zanerock 我相当肯定 MDN 兼容表已经过时。例如,它说 Safari 需要 -webkit- 前缀,但根据 caniuse,它自 Safari 11 以来就不需要前缀。您是否在任何无法使用它的浏览器上尝试过?
不,我不得不承认我只是认为它很好,甚至是自动化的。
最好在内部使用 writing-mode: revert;codepen.io/sollyu/pen/dyJQyze?editors=1100
r
rawiro

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

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

S
SpliFF

50% 的填充不会使您的孩子居中,它会将其放置在中心下方。我认为你真的想要一个 25% 的 padding-top。也许您只是因为内容变高而空间不足?您是否也尝试过设置 margin-top 而不是 padding-top?

编辑:没关系,w3schools 网站说

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

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

您正在做的事情可以使用 display:table 来实现(至少对于现代浏览器而言)。 The technique is explained here


谢谢斯普利夫。我知道我的 50% 不会以 div 的内容为中心。我实际上只有一行需要垂直居中的文本。非常感谢您的链接!
如果它只是一行文字,您是否考虑过使用大得离谱的 line-height,即,将行高设为 200 像素?
@Ryan 用于垂直居中文本,请参阅 stackoverflow.com/questions/8865458/…
你的链接坏了
W
WoodrowShigeru

这是一个非常有趣的错误。 (在我看来,无论如何这是一个错误)很好的发现!

关于如何设置,我会推荐 Camilo Martin 的回答。但至于为什么,如果你们不介意的话,我想稍微解释一下。

the CSS specs 中,我发现:

'padding' 百分比:指包含块的宽度

……这很奇怪,但没关系。

因此,对于父 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
如果你使用“写作模式:vertical-lr;”它似乎使百分比指的是包含块的高度,至少在 Chrome 88 中是这样。