html - 在不同情况下与其他单位相比,百分比的真正作用如何

标签 html css flexbox

所以基本上我最近一直在尝试 CSS,并且发现了一些对我来说似乎很新的东西。在设置元素的填充时,我通常使用 em 或 px 等单位,但这次我尝试使用百分比,令我惊讶的是,它的工作方式与其他单位非常不同。

所以我设置了三种不同的情况:

body {
  margin: 0;
}
.container {
  display: flex;
  background-color: lightblue;
  justify-content: space-between;
  margin: 30px 0;
}
.flex {
   display: flex;
}
.container a {
  color: #000;
  padding: 50px;
  background-color: rgba(0, 0, 0, 0.3)
}
.container.two {
  background-color: lightgreen;
}
.container.two a {
  padding: 30%;
}
.container.three {
  background-color: beige;
}
.container.three a {
  padding: 30%;
}
<div class="container">
  <div class="flex">
    <a href="#">Item 1</a>
    <a href="#">Item 2</a>
  </div>
  <div class="flex">
    <a href="#">Item 1</a>
    <a href="#">Item 2</a>
  </div>
</div>
<div class="container two">
  <div class="flex">
    <a href="#">Item 5</a>
    <a href="#">Item 6</a>
  </div>
  <div class="flex">
    <a href="#">Item 7</a>
    <a href="#">Item 8</a>
  </div>
</div>
<div class="container three">
  <div>
    <a href="#">Item 9</a>
    <a href="#">Item 10</a>
  </div>
  <div>
    <a href="#">Item 11</a>
    <a href="#">Item 12</a>
  </div>
</div>

在每种情况下,我都有一个导航栏,导航栏两侧都有 2 个元素。我使用像素和百分比来设置元素的填充。导航栏本身是 flex 容器。在前两种情况下,元素的容器是柔性容器,但第三种情况不是。

  1. 使用像素(与 Flexbox 一起): 当使用 Pixel 和 Flexbox 时,一切对我来说似乎都很正常。

  2. 使用百分比(与 flex 盒一起使用): 所以这就是事情开始变得奇怪的地方。这些元素被推出导航栏。

  3. 使用百分比(不使用 flex 盒): 在这里,这些元素并没有被推到导航栏上,而是只是在其直接父级内部增长,最终它们开始以更高的百分比值包装。

当我从导航栏中删除 Flex 时,一切都会变得更奇怪。

我只是想知道为什么在处理 flex 盒时百分比的行为与其他单位不同。我从来没有使用百分比来做这样的事情,所以这对我来说是非常新的。我好奇。我怀疑这与 Flexbox 有关,而不是直接与百分比单位有关。

这是相同内容的复制品:

https://jsfiddle.net/sLnvzrmb/

最佳答案

您同时面临着很多事情的结合。

首先,与 padding 一起使用的百分比会将父元素宽度视为引用(而不是元素本身)

The percentage is calculated with respect to the width of the generated box's containing block, even for 'padding-top' and 'padding-bottom' ref

在我们的例子中,包含 block 是父元素。

其次,在内联元素上应用填充与将其应用于 block 元素不同。内联元素的顶部和底部填充不会影响布局,但会有一种重叠:

The vertical padding, border and margin of an inline, non-replaced box start at the top and bottom of the content area, and has nothing to do with the 'line-height'. But only the 'line-height' is used when calculating the height of the line box. ref

第三,使用 Flexbox 时,您必须考虑默认的 nowrap 行为 ref 以及 Flex 元素被 block 化的事实(即使它们的显示设置为内联)

The display value of a flex item is blockified .. ref


现在,如果我们考虑使用 Flexbox 的第一种情况。这些元素被 block 化,百分比将考虑父级宽度作为引用,但是您有一个复杂的循环行为情况,因为父级(也是 flex 元素)的宽度基于其内容。我知道消化所有这些信息并不容易,因此这里有一个逐步说明以供理解:

.container {
  display: flex;
  background-color: lightblue;
  justify-content: space-between;
}
.flex {
   display: flex;
   border:2px solid red;
}
.container a {
  color: #000;
  background-color: rgba(0, 0, 0, 0.3)
}
.container.two a {
  padding: 30%;
}
Before padding
<div class="container">
  <div class="flex">
    <a href="#">Item 5</a>
    <a href="#">Item 6</a>
  </div>
  <div class="flex">
    <a href="#">Item 7</a>
    <a href="#">Item 8</a>
  </div>
</div>
After padding
<div class="container two">
  <div class="flex">
    <a href="#">Item 5</a>
    <a href="#">Item 6</a>
  </div>
  <div class="flex">
    <a href="#">Item 7</a>
    <a href="#">Item 8</a>
  </div>
</div>

仔细观察我添加的红色边框,以及它的宽度在两种情况下是如何相同的。诀窍在于,浏览器将首先忽略填充(因为它是百分比值)来计算父宽度,然后使用该宽度来查找填充值,从逻辑上讲,您将出现溢出。溢出等于您所拥有的填充(宽度的30%*4)。由于默认的 nowrap 行为,元素不会换行,但您可以禁用此功能:

.container {
  display: flex;
  background-color: lightblue;
  justify-content: space-between;
}
.flex {
   display: flex;
   border:2px solid red;
   flex-wrap:wrap;
}
.container a {
  color: #000;
  background-color: rgba(0, 0, 0, 0.3)
}
.container.two a {
  padding: 30%;
}
Before padding
<div class="container">
  <div class="flex">
    <a href="#">Item 5</a>
    <a href="#">Item 6</a>
  </div>
  <div class="flex">
    <a href="#">Item 7</a>
    <a href="#">Item 8</a>
  </div>
</div>
After padding
<div class="container two">
  <div class="flex">
    <a href="#">Item 5</a>
    <a href="#">Item 6</a>
  </div>
  <div class="flex">
    <a href="#">Item 7</a>
    <a href="#">Item 8</a>
  </div>
</div>

现在,如果您从父级中删除 display:flex,您将不再拥有 Flex 元素,现在您处理内联元素,您会得到以下内容

.container {
  display: flex;
  background-color: lightblue;
  justify-content: space-between;
}
.flex {
   border:2px solid red;
}
.container a {
  color: #000;
  background-color: rgba(0, 0, 0, 0.3)
}
.container.two a {
  padding: 30%;
}
Before padding
<div class="container">
  <div class="flex">
    <a href="#">Item 5</a>
    <a href="#">Item 6</a>
  </div>
  <div class="flex">
    <a href="#">Item 7</a>
    <a href="#">Item 8</a>
  </div>
</div>
After padding
<div class="container two">
  <div class="flex">
    <a href="#">Item 5</a>
    <a href="#">Item 6</a>
  </div>
  <div class="flex">
    <a href="#">Item 7</a>
    <a href="#">Item 8</a>
  </div>
</div>

与之前的逻辑相同,首先定义宽度,然后用作引用,但不会溢出,因为内联元素将换行到下一行,并且行之间会有重叠,因为 padding-top/bottom 不会重叠t 适用于内联元素。

添加inline-block并查看差异

.container {
  display: flex;
  background-color: lightblue;
  justify-content: space-between;
}
.flex {
   border:2px solid red;
}
.container a {
  color: #000;
  display:inline-block;
  background-color: rgba(0, 0, 0, 0.3)
}
.container.two a {
  padding: 30%;
}
Before padding
<div class="container">
  <div class="flex">
    <a href="#">Item 5</a>
    <a href="#">Item 6</a>
  </div>
  <div class="flex">
    <a href="#">Item 7</a>
    <a href="#">Item 8</a>
  </div>
</div>
After padding
<div class="container two">
  <div class="flex">
    <a href="#">Item 5</a>
    <a href="#">Item 6</a>
  </div>
  <div class="flex">
    <a href="#">Item 7</a>
    <a href="#">Item 8</a>
  </div>
</div>

最后,如果您从导航栏中删除 Flexbox,则曾经是 Flex 元素的父元素现在是一个 block 元素,并且其宽度不再基于其内容,但默认情况下它现在是全宽度,您将拥有

.container {
  background-color: lightblue;
  justify-content: space-between;
  width:100px;
}
.flex {
   border:2px solid red;
}
.container a {
  color: #000;
  background-color: rgba(0, 0, 0, 0.3)
}
.container.two a {
  padding: 30%;
}
Before padding
<div class="container">
  <div class="flex">
    <a href="#">Item 5</a>
    <a href="#">Item 6</a>
  </div>
  <div class="flex">
    <a href="#">Item 7</a>
    <a href="#">Item 8</a>
  </div>
</div>
After padding
<div class="container two">
  <div class="flex">
    <a href="#">Item 5</a>
    <a href="#">Item 6</a>
  </div>
  <div class="flex">
    <a href="#">Item 7</a>
    <a href="#">Item 8</a>
  </div>
</div>

bigger width
<div class="container two" style="width:300px">
  <div class="flex">
    <a href="#">Item 5</a>
    <a href="#">Item 6</a>
  </div>
  <div class="flex">
    <a href="#">Item 7</a>
    <a href="#">Item 8</a>
  </div>
</div>

full width
<div class="container two" style="width:auto">
  <div class="flex">
    <a href="#">Item 5</a>
    <a href="#">Item 6</a>
  </div>
  <div class="flex">
    <a href="#">Item 7</a>
    <a href="#">Item 8</a>
  </div>
</div>

所以我们的父元素是全宽的,padding:30% 基于该宽度。想象一下它会有多大,因为每个元素都有 60% 的填充(左 + 右),所以总共 120%。并且我们的元素是内联元素,因此顶部和底部将不适用并且只会重叠

使用inline-block并禁用overalp,现在顶部和底部是布局的一部分:

.container {
  background-color: lightblue;
  justify-content: space-between;
  width:100px;
}
.flex {
   border:2px solid red;
}
.container a {
  color: #000;
  display:inline-block;
  background-color: rgba(0, 0, 0, 0.3)
}
.container.two a {
  padding: 30%;
}
Before padding
<div class="container">
  <div class="flex">
    <a href="#">Item 5</a>
    <a href="#">Item 6</a>
  </div>
  <div class="flex">
    <a href="#">Item 7</a>
    <a href="#">Item 8</a>
  </div>
</div>
After padding
<div class="container two">
  <div class="flex">
    <a href="#">Item 5</a>
    <a href="#">Item 6</a>
  </div>
  <div class="flex">
    <a href="#">Item 7</a>
    <a href="#">Item 8</a>
  </div>
</div>

bigger width
<div class="container two" style="width:300px">
  <div class="flex">
    <a href="#">Item 5</a>
    <a href="#">Item 6</a>
  </div>
  <div class="flex">
    <a href="#">Item 7</a>
    <a href="#">Item 8</a>
  </div>
</div>

full width
<div class="container two" style="width:auto">
  <div class="flex">
    <a href="#">Item 5</a>
    <a href="#">Item 6</a>
  </div>
  <div class="flex">
    <a href="#">Item 7</a>
    <a href="#">Item 8</a>
  </div>
</div>

关于html - 在不同情况下与其他单位相比,百分比的真正作用如何,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67961622/

相关文章:

javascript - 我如何知道浏览器为特定元素设置的光标样式

css - 使代码镜像 block 填充 Safari 中页面的其余部分

html - 如何在悬停时更改列表项的背景颜色?

javascript - 如何在 Markdown 中使用 Github 按钮 (README.md)

html - Twitter Bootstrap ProgressBar 左右两侧带有徽章

html - 如何使用 CSS 分割不同颜色的圆

html - 水平对齐三个 div。需要建议

jquery - 将高度设置为视口(viewport)时,微小的滚动条消失了

css - width 和 flex-basis 的区别

css - flex 子项上的文本溢出省略号不起作用