大家有没有对 CSS 中的百分比是如何工作的感兴趣?有没有想过,为什么它有时会乱七八糟,没啥头绪?反正我是有,所以今天分享这篇文章,对自己来说是加深理解,同时也希望对大家有所帮助。
什么百分比?
作为百分比,显然应该有一个目标作为参考源,这个参考一般是父元素。 这是正确的,但并不涵盖所有情况。 最正确的答案应该是包含块(containing block
),即包含我们元素的块且它不必是直接的父元素。
看看下面的例子:
代码如下:
<!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
来计算。
来个例子:
代码如下:
<!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 的百分比(垂直和水平)也是相对于包含块的宽度来计算。
来个例子:
代码如下:
<!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
来计算。
来个例子:
代码如下:
<!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)。