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

发布于 2024-10-16 22:37:33 字数 767 浏览 7 评论 0原文

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

I had been racking my brains over creating a vertical alignment in css using the following

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

While this seemed to work for this case, i was surprised that when i increased or decreased the width of my base div, the vertical alignment would snap. I was expecting that when I set the padding-top property, it would take the padding as a percentage of the height of the parent container, which is base in our case, but the above value of 50 percent is calculated as a percentage of the width. :(

Is there a way to set the padding and/or margin as a percentage of the height, without resorting to using JavaScript?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

妄断弥空 2024-10-23 22:37:33

解决方法是,垂直内边距和边距与宽度相关,但顶部底部不是。

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

The fix is that yes, vertical padding and margin are relative to width, but top and bottom aren't.

So just place a div inside another, and in the inner div, use something like top:50% (remember position matters if it still doesn't work)

絕版丫頭 2024-10-23 22:37:33

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

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

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

An answer to a slightly different question: You can use vh units to pad elements to the center of the viewport:

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

<div class="centerme">middle</div>
牵你的手,一向走下去 2024-10-23 22:37: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%;
}

Here are two options to emulate the needed behavior. Not a general solution, but may help in some cases. The vertical spacing here is calculated on the basis of the size of the outer element, not its parent, but this size itself can be relative to the parent and this way the spacing will be relative too.

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

First option: use pseudo-elements, here vertical and horizontal spacing are relative to the outer. Demo

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

Moving the horizontal spacing to the outer element makes it relative to the parent of the outer. Demo

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

Second option: use absolute positioning. Demo

#outer {
    position: relative;
}
#inner {
    position: absolute;
    left: 10%;
    right: 10%;
    top: 10%;
    bottom: 10%;
}
浮生未歇 2024-10-23 22:37:33

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

那么子元素的“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>

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

To make the child element positioned absolutely from its parent element you need to set relative position on the parent element AND absolute position on the child element.

Then on the child element 'top' is relative to the height of the parent. So you also need to 'translate' upward the child 50% of its own height.

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

There is another a solution using flex box.

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

You will find advantages/disavantages for both.

萧瑟寒风 2024-10-23 22:37:33

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

当您希望元素的纵横比保持不变,但希望其大小根据其高度而不是宽度进行缩放时,使用垂直书写模式特别有用。

This can be achieved with the writing-mode property. If you set an element's writing-mode to a vertical writing mode, such as vertical-lr, its descendants' percentage values for padding and margin, in both dimensions, become relative to height instead of width.

From the spec:

. . . percentages on the margin and padding properties, which are always calculated with respect to the containing block width in CSS2.1, are calculated with respect to the inline size of the containing block in CSS3.

The definition of inline size:

A measurement in the inline dimension: refers to the physical width (horizontal dimension) in horizontal writing modes, and to the physical height (vertical dimension) in vertical writing modes.

Example, with a resizable element, where horizontal margins are relative to width and vertical margins are relative to height.

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

Using a vertical writing mode can be particularly useful in circumstances where you want the aspect ratio of an element to remain constant, but want its size to scale in correlation to its height instead of width.

旧城烟雨 2024-10-23 22:37:33

将一行文本居中的其他方法是:

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

Other way to center one line text is:

.parent{
  position: relative;
}

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

or just

.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;
}
她说她爱他 2024-10-23 22:37:33

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

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


CSS规范中我发现:

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

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

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

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

This is a very interesting bug. (In my opinion, it is a bug anyway) Nice find!

Regarding how to set it, I would recommend Camilo Martin's answer. But as to why, I'd like to explain this a bit if you guys don't mind.


In the CSS specs I found:

'padding'
Percentages: refer to width of containing block

… which is weird, but okay.

So, with a parent width: 210px and a child padding-top: 50%, I get a calculated/computed value of padding-top: 96.5px – which is not the expected 105px.

That is because in Windows (I'm not sure about other OSs), the size of common scrollbars is per default 17px × 100% (or 100% × 17px for horizontal bars). Those 17px are substracted before calculating the 50%, hence 50% of 193px = 96.5px.

酒与心事 2024-10-23 22:37:33

带有空行的 CSS 网格

这种方法可能只有在您已经在相关容器中使用 css-grid 时才有意义,但是如果您是这样,您可以创建一个空行,其百分比(因为它是一行)将是身高的百分比。

.wrapper
{
  border: 2px solid red;
  width: 400px;
  height: 200px;
  
  display: grid;
  grid-template-rows: 10% 1fr;
}

.child
{
  background: orange;
  width: 50px;
  height: 50px;
  
  grid-area: 2/1;
}
<div class="wrapper">
  <div class="child">
  </div>
</div>

CSS Grid with empty row

This approach probably only makes sense if you're already using css-grid for the container in question, but if you are you can create an empty row with a percentage that (because it is a row) will be a percentage of the height.

.wrapper
{
  border: 2px solid red;
  width: 400px;
  height: 200px;
  
  display: grid;
  grid-template-rows: 10% 1fr;
}

.child
{
  background: orange;
  width: 50px;
  height: 50px;
  
  grid-area: 2/1;
}
<div class="wrapper">
  <div class="child">
  </div>
</div>

夏天碎花小短裙 2024-10-23 22:37:33

50% 的填充不会使您的孩子居中,而是将其置于中心下方。我想你确实想要 25% 的 padding-top。也许随着您的内容变高,您的空间不足了?您还尝试过设置 margin-top 而不是 padding-top 吗?

编辑:没关系,w3schools 网站说

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

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

您正在做的事情可以使用 display:table 来实现(至少对于现代浏览器)。 此处解释了该技术

A 50% padding wont center your child, it will place it below the center. I think you really want a padding-top of 25%. Maybe you're just running out of space as your content gets taller? Also have you tried setting the margin-top instead of padding-top?

EDIT: Nevermind, the w3schools site says

% Specifies the padding in percent of the width of the containing element

So maybe it always uses width? I'd never noticed.

What you are doing can be acheived using display:table though (at least for modern browsers). The technique is explained here.

辞取 2024-10-23 22:37:33

您可以使用gridinline-grid设置相对填充,如下所示:

.el {
  display: inline-grid;
  /* 25% 75% columns */
  grid-template-rows: 25fr 75fr;
  
  /* Insert :before into first row so text is forced into 2nd row. */
  &:before {
    content: "";
    display: block;
    grid-row: 1;
    background: red;
  }
}
<div class="el">
Some text<br/>
Some text<br/>
Some text<br/>
Some text<br/>
</el>

You can set relative padding using grid or inline-grid like following:

.el {
  display: inline-grid;
  /* 25% 75% columns */
  grid-template-rows: 25fr 75fr;
  
  /* Insert :before into first row so text is forced into 2nd row. */
  &:before {
    content: "";
    display: block;
    grid-row: 1;
    background: red;
  }
}
<div class="el">
Some text<br/>
Some text<br/>
Some text<br/>
Some text<br/>
</el>

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文