终于搞懂了 CSS 中的百分比是基于什么工作的了!

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

[[425677]]

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

什么百分比?

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

看看下面的例子:

代码:

  1. <div class="grandparent"
  2.   <div class="parent"
  3.     <div class="child"></div> 
  4.   </div> 
  5. </div> 
  1. .grandparent { 
  2.   position: relative
  3.   width: 200px; 
  4.   height: 200px; 
  5.   background: #eaeaea; 
  6.  
  7. .parent { 
  8.   width: 100px; 
  9.   height: 100px; 
  10.   background: #aaa; 
  11.  
  12. .child { 
  13.   position: absolute
  14.   width: 50%; 
  15.   height: 50%; 
  16.   top: 25%; 
  17.   left: 25%; 
  18.   background: red; 

在上面的例子中,我创建了 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)都是基于包含块的 height 来计算。

来个例子:

  1. <div class="parent"
  2.  <div class="child"></div> 
  3. </div> 
  1. .parent { 
  2.   background: #eaeaea; 
  3.   width: 300px; 
  4.   height: 200px; 
  5.  
  6. .child { 
  7.   display: inline-block; 
  8.   background: red; 
  9.   padding-top: 50%; 
  10.   padding-left: 50%; 
  11.  
  12. .parent { 
  13.   position: relative

线上地址:https://codepen.io/khangnd/pen/powbjEL

在这个例子中:

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

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

margin

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

来个事例:

  1. <div class="parent"
  2.   <div class="child"></div> 
  3. </div> 
  1. .parent { 
  2.   background: #eaeaea; 
  3.   width: 300px; 
  4.   height: 200px; 
  5.  
  6. .child { 
  7.   display: inline-block; 
  8.   background: red; 
  9.   width: 50px; 
  10.   height: 50px; 
  11.   margin-top: 50%; 
  12.   margin-left: 50%; 

在这个例子中:

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

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

top/bottom/left/right

这4个定位属性也是基于包含块的宽度来计算的。

来个例子:

  1. <div class="parent"
  2.   <div class="child"></div> 
  3. </div> 
  1. .parent { 
  2.   position: relative
  3.   background: #eaeaea; 
  4.   width: 300px; 
  5.   height: 200px; 
  6.  
  7. .child { 
  8.   position: absolute
  9.   background: red; 
  10.   width: 16.67%; 
  11.   height: 25%; 
  12.   top: 50%; 
  13.   left: 50%; 

在这个事例中:

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

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

transform: translate()

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

来个例子:

  1. <div class="parent"
  2.   <div class="child"></div> 
  3. </div> 
  1. .parent { 
  2.   background: #eaeaea; 
  3.   width: 300px; 
  4.   height: 200px; 
  5.  
  6. .child { 
  7.   background: red; 
  8.   width: 100px; 
  9.   height: 50px; 
  10.   transform: translate(50%, 50%); 

在这个事例中:

  • 父级 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 :https://developer.mozilla.org/zh-CN/docs/Web/CSS/background-origin

来个例子:

  1. <div class="parent"
  2.   <div class="child"></div> 
  3. </div> 
  1. .parent { 
  2.   background: #eaeaea; 
  3.   width: 300px; 
  4.   height: 200px; 
  5.  
  6. .child { 
  7.   background-image: url(https://d2fltix0v2e0sb.cloudfront.net/dev-rainbow.png); 
  8.   background-size: 50% 50%; 
  9.   background-repeat: no-repeat; 
  10.   background-color: red; 
  11.   width: 50%; 
  12.   height: 50%; 

在这个例子中:

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

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

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

在这个例子中:

  1. <div class="parent"
  2.   <div class="child"></div> 
  3. </div> 

css

  1. .parent { 
  2.   background: #eaeaea; 
  3.   width: 300px; 
  4.   height: 200px; 
  5.  
  6. .child { 
  7.   background-image: url(https://d2fltix0v2e0sb.cloudfront.net/dev-rainbow.png); 
  8.   background-size: 50% 50%; 
  9.   background-position: 50% 50%; 
  10.   background-repeat: no-repeat; 
  11.   background-color: red; 
  12.   width: 50%; 
  13.   height: 50%; 

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

  • 如果没有任何值(默认值为0 0),背景图像将位于左上角。
  • 使用 background-position: 0 50%,背景图片被定位在左边中间。
  • 使用 background-position: 50% 50%,背景图片被定位在中心。
  • 使用 background-position: 100% 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 ,百分比值仅指向它的直接父块。

来个例子:

  1. <div class="grandparent"
  2.   font-size: 13px 
  3.   <div class="parent"
  4.     font-size: 26px 
  5.     <div class="child">font-size: 50% 
  6.   </div> 
  7. </div> 

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

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

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

线上地址:https://codepen.io/khangnd/pen/MWoeXMO

~~ 完,最近一个礼拜都在赶项目,基本都要2点后才能睡,这篇文章是间断整理好的,现在时间 是 9/20 深夜3点,睡了,感谢大家的观看。

作者:Khang 译者:前端小智 来源:dev 原文:https://dev.to/khgnd/understanding-css-percentage-44gd

 

责任编辑:姜华 来源: 大迁世界
相关推荐

2021-09-27 08:49:03

开发 CSS padding

2021-09-28 08:31:22

Flex:1 CSSflex属性

2011-04-06 10:57:11

Cacti监控

2011-03-31 16:16:43

Cacti监控

2021-07-08 06:47:21

Python

2017-03-16 09:10:41

鱼缸式信息图表计算

2015-07-28 10:03:56

H5前端margin

2011-08-02 21:46:11

SQL Server数按百分比查询

2022-08-16 15:04:02

iOS电池修复

2021-08-19 09:59:07

Spring代码Java

2012-12-24 11:13:17

CSSjQueryJavaScript

2020-06-18 10:52:17

运维架构技术

2020-06-09 08:19:25

微服务网站架构

2019-12-24 13:40:16

数据科学PythonPytorc

2023-11-27 11:51:13

CSS前端

2017-05-02 13:38:51

CSS绘制形状

2019-08-28 08:57:05

2021-09-30 14:23:23

服务器开发工具

2013-05-21 09:49:22

Quickbooks云安全云存储服务

2018-10-20 16:05:12

iOSAPP开发
点赞
收藏

51CTO技术栈公众号