0
点赞
收藏
分享

微信扫一扫

CSS 各种百分比是基于什么工作的?



大家有没有对 CSS 中的百分比是如何工作的感兴趣?有没有想过,为什么它有时会乱七八糟,没啥头绪?反正我是有,所以今天分享这篇文章,对自己来说是加深理解,同时也希望对大家有所帮助。


什么百分比?

作为百分比,显然应该有一个目标作为参考源,这个参考一般是父元素。 这是正确的,但并不涵盖所有情况。 最正确的答案应该是包含块​​(containing block​​),即包含我们元素的块且它不必是直接的父元素。

看看下面的例子:

CSS 各种百分比是基于什么工作的?_html5

代码如下:

<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="utf-8">
<title>css百分比</title>
<link rel="stylesheet" href="css/swiper.min.css">
<link rel="stylesheet" href="css/certify.css">
<script src="js/swiper.min.js"></script>

</head>

<body>
<div class="grandparent">
<div class="parent">
<div class="child"></div>
</div>
</div>
</body>

</html>

<style>
.grandparent {
position: relative;
width: 200px;
height: 200px;
background: #eaeaea;
}

.parent {
width: 100px;
height: 100px;
background: #aaa;
}

.child {
position: absolute;
width: 50%;
height: 50%;
top: 25%;
left: 25%;
background: red;
}
</style>

在上面的例子中,我创建了 ​​3​​​ 个嵌套 ​​div​​,它们是具有以下特征的3个正方形

  • 最外面的组元​​div​​​ 是一个浅灰色,大小为​​4x4​
  • 父元素​​div​​​ 的颜色为深灰色,大小为​​2x2​
  • 以及分配​​50%​​​ 大小的红色子​​div​

如果百分比单位以父级为来源,则子级的大小应该是它的 ​​1/2​​​,但上面的不是,子级的大小实际上等于父级,也就是祖父级的 ​​1/2​​​。 原因是祖父级 ​​div​​​ 是子级 ​​div​​​ 的真正包含块,因为子级具有 ​​position: absolute​​​ ,对应于在祖父级中设置的 ​​position:relative​​ 。

因此,为了确定哪个是元素的实际包含块,它完全基于元素本身的 position 属性。

但是,对于某些属性,百分比单元的引用源既不是父块也不是包含块,而是它本身—— 自身元素。

百分比的属性

width/height

如上面的例子中看到的,当一个元素为其宽度分配一个百分比值时, ​​width​​​ 是基于包含块的 ​​width​​​, ​​height​​​ 是基于包含块的 ​​height​​。

padding

对于 ​​padding​​​,垂直(​​padding-top/padding-bottom​​​)或水平(​​padding-left/padding-right​​​)都是基于包含块的 ​​width​​ 来计算。

来个例子:

CSS 各种百分比是基于什么工作的?_css_02

代码如下:

<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="utf-8">
<title>css百分比</title>
<link rel="stylesheet" href="css/swiper.min.css">
<link rel="stylesheet" href="css/certify.css">
<script src="js/swiper.min.js"></script>

</head>

<body>
<div class="grandparent">
<div class="parent">
<div class="child"></div>
</div>
</div>
</body>

</html>

<style>
.parent {
background: #eaeaea;
width: 300px;
height: 200px;
}

.child {
display: inline-block;
background: red;
padding-top: 50%;
padding-left: 50%;
}

.parent {
position: relative;
}
.grandparent {
position: relative;
}

.grandparent::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 99;
background: radial-gradient(circle at 1px 1px, #000 2px, transparent 0);
background-size: 49.5px 49.5px;
}
</style>

在这个例子中:

  • 父​​div​​​ 的大小为​​6x4​​。
  • 子​​div​​​ 的大小为 0,但​​padding-top​​​ 和​​padding-left​​​ 分别为​​50%​

最后的结果是,子元素的大小相当于父级元素 ​​1/2​​​ 宽度,也就是一个 ​​3x3​​ 的正方形。

margin

与 ​​padding​​​,​​margin​​ 的百分比(垂直和水平)也是相对于包含块的宽度来计算。

来个例子:

CSS 各种百分比是基于什么工作的?_html5_03

代码如下:

<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="utf-8">
<title>css百分比</title>
<link rel="stylesheet" href="css/swiper.min.css">
<link rel="stylesheet" href="css/certify.css">
<script src="js/swiper.min.js"></script>

</head>

<body>
<div class="grandparent">
<div class="parent">
<div class="child"></div>
</div>
</div>
</body>

</html>

<style>
.parent {
background: #eaeaea;
width: 300px;
height: 200px;
}

.child {
display: inline-block;
background: red;
width: 50px;
height: 50px;
margin-top: 50%;
margin-left: 50%;
}

.parent {
position: relative;
}

.grandparent {
position: relative;
}

.grandparent::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 99;
background: radial-gradient(circle at 1px 1px, #000 2px, transparent 0);
background-size: 49.5px 49.5px;
}
</style>

在这个例子中:

  • 父级​​div​​​ 的大小为​​6x4​​。
  • ​margin-top​​​ 和​​margin-left​​​ 分别为​​50%​

其结果是,子元素被定位在离父级元素的上边距和左边距3个单位的地方(父级宽度的1/2)。

top/bottom/left/right

​top​​​、​​bottom​​​ 基于包含块的 ​​height​​​ 来计算,​​left​​​、​​right​​​ 基于包含块的​​width​​来计算。

来个例子:

CSS 各种百分比是基于什么工作的?_百分比_04

代码如下:

<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="utf-8">
<title>css百分比</title>
<link rel="stylesheet" href="css/swiper.min.css">
<link rel="stylesheet" href="css/certify.css">
<script src="js/swiper.min.js"></script>

</head>

<body>
<div class="grandparent">
<div class="parent">
<div class="child"></div>
</div>
</div>
</body>

</html>

<style>
.parent {
position: relative;
background: #eaeaea;
width: 300px;
height: 200px;
}

.child {
position: absolute;
background: red;
width: 16.67%;
height: 25%;
top: 50%;
left: 50%;
}

.parent {
position: relative;
}

.grandparent {
position: relative;
}

.grandparent::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 99;
background: radial-gradient(circle at 1px 1px, #000 2px, transparent 0);
background-size: 49.5px 49.5px;
}
</style>

在这个事例中:

  • 父级​​div​​​ 的大小为​​6x4​
  • 子元素有​​position: absolute​​​,​​top​​​ 和​​left​​​ 分别为​​50%​

最终结果,子 ​​div​​​ 被定位在离父 ​​div​​​ 的顶部边缘 ​​2​​​ 个单位的位置(​​父 div 高度的 1/2​​​),并被定位在离父 ​​div​​​ 的左侧边缘 ​​3​​​ 个单位的位置(​​父 div 宽度的 1/2​​)。

transform: translate()

一个用于动画/过渡的不可思议的属性,它也支持百分比值。然而,这个属性并不指其包含的块,而是指其自身。

来个例子:

CSS 各种百分比是基于什么工作的?_css_05

代码如下:

<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="utf-8">
<title>css百分比</title>
<link rel="stylesheet" href="css/swiper.min.css">
<link rel="stylesheet" href="css/certify.css">
<script src="js/swiper.min.js"></script>

</head>

<body>
<div class="grandparent">
<div class="parent">
<div class="child"></div>
</div>
</div>
</body>

</html>

<style>
.parent {
background: #eaeaea;
width: 300px;
height: 200px;
}

.child {
background: red;
width: 100px;
height: 50px;
transform: translate(50%, 50%);
}

.parent {
position: relative;
}

.grandparent {
position: relative;
}

.grandparent::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 99;
background: radial-gradient(circle at 1px 1px, #000 2px, transparent 0);
background-size: 49.5px 49.5px;
}
</style>

在这个事例中:

  • 父级​​div​​​ 的大小为​​6x4​​。
  • 子​​div​​​ 的大小为​​2x1​​​,使用​​transform: translate(50%, 50%)​

最后结果,子 div 被定位在离父 div 的顶部边缘 0.5 个单位的位置(自身高度的 1/2),并被定位在离父 div 的左侧边缘 1 个单位的位置(自身宽度的 1/2)。

background-size

​background-size​​ 属性将百分比单元的复杂性提升到一个新的水平

此属性的百分比值指的是背景定位区域,类似于包含块,但添加了以下 ​​3​​ 个因素:

  • 只有内容的块(​​content-box​​)
  • 带有内容和​​padding​​​ 的块 (​​padding-box​​)
  • 带有内容、​​padding​​​ 和​​border​​​ 的块(​​border-box​​)

这三个值是由 ​​background-origin​​​ 给出,具体看 ​​MDN​​。

来个例子:

CSS 各种百分比是基于什么工作的?_css_06

代码如下:

<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="utf-8">
<title>css百分比</title>
<link rel="stylesheet" href="css/swiper.min.css">
<link rel="stylesheet" href="css/certify.css">
<script src="js/swiper.min.js"></script>

</head>

<body>
<div class="grandparent">
<div class="parent">
<div class="child"></div>
</div>
</div>
</body>

</html>

<style>
.parent {
background: #eaeaea;
width: 300px;
height: 200px;
}

.child {
background-image: url(https://media.mybj123.com/wp-content/uploads/2021/09/1632706681-f60540cafc9989b.png);
background-size: 50% 50%;
background-repeat: no-repeat;
background-color: red;
width: 50%;
height: 50%;
}

.parent {
position: relative;
}

.grandparent {
position: relative;
}

.grandparent::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 99;
background: radial-gradient(circle at 1px 1px, #000 2px, transparent 0);
background-size: 49.5px 49.5px;
}
</style>

在这个例子中:

  • 父​​div​​​ 的大小为​​6x4​
  • 子​​div​​​ 的大小为​​3x2​​​,没有​​padding​​​,没有​​border​
  • 这里使用了一个DEV logo(比例为​​1:1​​​ )作为子​​div​​​ 的背景图像,背景大小属性设置为​​50% 50%​

其结果是,背景图像被拉伸为 ​​1.5 x 1​​ 的大小。

background-position

与 ​​background-size​​​ 类似,​​background-position​​ 属性的百分比也依赖于背景定位区域。

来个例子:

CSS 各种百分比是基于什么工作的?_html_07

代码如下:

<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="utf-8">
<title>css百分比</title>
<link rel="stylesheet" href="css/swiper.min.css">
<link rel="stylesheet" href="css/certify.css">
<script src="js/swiper.min.js"></script>

</head>

<body>
<div class="grandparent">
<div class="parent">
<div class="child"></div>
</div>
</div>
</body>

</html>

<style>
.parent {
background: #eaeaea;
width: 300px;
height: 200px;
}

.child {
background-image: url(https://d2fltix0v2e0sb.cloudfront.net/dev-rainbow.png);
background-size: 50% 50%;
background-position: 50% 50%;
background-repeat: no-repeat;
background-color: red;
width: 50%;
height: 50%;
}

.parent {
position: relative;
}

.grandparent {
position: relative;
}

.grandparent::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 99;
background: radial-gradient(circle at 1px 1px, #000 2px, transparent 0);
background-size: 49.5px 49.5px;
}
</style>

在这个例子中:

在本例中,使用了与前面相同的图像和布局。当我们改变​​background-position​​的值时,可以看到一些变化:

  • 如果没有任何值(默认值为​​0 0​​),背景图像将位于左上角。
  • 使用 background-position:​​0 50%​​,背景图片被定位在左边中间。
  • 使用 background-position:​​50% 50%​​,背景图片被定位在中心。
  • 使用 background-position: 1​​00% 100%​​,背景图片被定位在右下方。

注意: ​​background-position: 0 50%​​ 是下面的缩写:

  • ​background-position-x: 0​
  • ​background-position-y: 50%​

显然,这个属性的百分比背后有一些计算,而不仅仅是图像的顶部和左侧边缘与孩子的距离。通过一些研究和测试,似乎 ​​background-position​​ 属性在产生一个实际值之前依赖于以下计算。


offset X = (容器的宽度-图像的宽度) * background-position-x
offset Y = (容器的高度-图像的高度) * background-position-y


在这种情况下:

  • 容器作为子​​div​
  • 图像的宽度/高度是​​background-size​​ 的结果。

font-size

对于 font-size ,百分比值仅指向它的直接父块。

来个例子:

CSS 各种百分比是基于什么工作的?_html_08

代码如下:

<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="utf-8">
<title>css百分比</title>
<link rel="stylesheet" href="css/swiper.min.css">
<link rel="stylesheet" href="css/certify.css">
<script src="js/swiper.min.js"></script>

</head>

<body>
<div class="grandparent">
font-size: 13px
<div class="parent">
font-size: 26px
<div class="child">font-size: 50%
</div>
</div>
</div>
</body>

</html>

<style>
.grandparent {
position: relative;
background: #eaeaea;
width: 200px;
height: 200px;

font-size: 13px;
}

.parent {
background: #aaa;
width: 100px;
height: 100px;

font-size: 26px;
}

.child {
position: absolute;
background: red;
color: #fff;
width: 50%;
height: 50%;
top: 25%;
left: 25%;

font-size: 50%;
}
</style>

在这个例子中,我使用与第一个例子相同的布局,字体大小分配如下。

  • grandparent 13px
  • parent 26px
  • child 50%

我们可以清楚地看到,​​child​​​ 的字体大小现在与 ​​grandparent​​​ 一样,是 ​​parent 的1/2​​。

结语

以上就为“CSS 各种百分比是基于什么工作的?”的全部内容,希望大家阅读后能有所收获。



举报

相关推荐

0 条评论