终于搞懂了 CSS 中的百分比是基于什么工作的了!
作者:Khang大家有没有对 CSS 中的百分比是如何工作的感兴趣?有没有想过,为什么它有时会乱七八糟,没啥头绪?反正我是有,所以今天分享这篇文章,对自己来说是加深理解,同时也希望对大家有所帮助。
译者:前端小智
来源:dev
有梦想,有干货,微信搜索 【大迁世界】 关注这个在凌晨还在刷碗的刷碗智。
本文 GitHub https://github.com/qq449245884/xiaozhi 已收录,有一线大厂面试完整考点、资料以及我的系列文章。
什么百分比?
作为百分比,显然应该有一个目标作为参考源,这个参考一般是父元素。 这是正确的,但并不涵盖所有情况。 最正确的答案应该是包含块(containing block),即包含我们元素的块且它不必是直接的父元素。
看看下面的例子:
文章图片
代码:
.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;
}
在上面的例子中,我创建了
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
来计算。来个例子:
文章图片
.parent {
background: #eaeaea;
width: 300px;
height: 200px;
}.child {
display: inline-block;
background: red;
padding-top: 50%;
padding-left: 50%;
}.parent {
position: relative;
}
线上地址:https://codepen.io/khangnd/pe...
在这个例子中:
- 父
div
的大小为6x4
。 - 子
div
的大小为0
,但padding-top
和padding-left
分别为50%
1/2
宽度,也就是一个 3x3
的正方形。margin 与
padding
,margin
的百分比(垂直和水平)也是相对于包含块的宽度来计算。来个事例:
文章图片
.parent {
background: #eaeaea;
width: 300px;
height: 200px;
}.child {
display: inline-block;
background: red;
width: 50px;
height: 50px;
margin-top: 50%;
margin-left: 50%;
}
在这个例子中:
- 父级
div
的大小为6x4
。 margin-top
和margin-left
分别为50%
top/bottom/left/right
top
、bottom
基于包含块的height
来计算,left
、right
基于包含块的width
来计算。来个例子:
文章图片
.parent {
position: relative;
background: #eaeaea;
width: 300px;
height: 200px;
}.child {
position: absolute;
background: red;
width: 16.67%;
height: 25%;
top: 50%;
left: 50%;
}
在这个事例中:
- 父级
div
的大小为6x4
- 子元素有
position: absolute
,top
和left
分别为50%
div
被定位在离父 div
的顶部边缘 2
个单位的位置(父 div
高度的 1/2
),并被定位在离父 div
的左侧边缘 3
个单位的位置(父 div
宽度的 1/2
)。transform: translate() 一个用于动画/过渡的不可思议的属性,它也支持百分比值。然而,这个属性并不指其包含的块,而是指其自身。
来个例子:
文章图片
.parent {
background: #eaeaea;
width: 300px;
height: 200px;
}.child {
background: red;
width: 100px;
height: 50px;
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
属性将百分比单元的复杂性提升到一个新的水平【终于搞懂了 CSS 中的百分比是基于什么工作的了!】此属性的百分比值指的是背景定位区域,类似于包含块,但添加了以下 3 个因素:
- 只有内容的块(
content-box
) - 带有内容和
padding
的块 (padding-box
) - 带有内容、
padding
和border
的块(border-box
)
background-origin
给出,具体看 MDN :https://developer.mozilla.org...来个例子:
.parent {
background: #eaeaea;
width: 300px;
height: 200px;
}.child {
background-image: url(https://d2fltix0v2e0sb.cloudfront.net/dev-rainbow.png);
background-size: 50% 50%;
background-repeat: no-repeat;
background-color: red;
width: 50%;
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
属性的百分比也依赖于背景定位区域。在这个例子中:
css
.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%;
}
在本例中,使用了与前面相同的图像和布局。当我们改变
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: 13pxfont-size: 26px
font-size: 50%
在这个例子中,我使用与第一个例子相同的布局,字体大小分配如下。
- grandparent 13px
- parent 26px
- child 50%
child
的字体大小现在与 grandparent
一样,是 parent 的1/2
。线上地址:https://codepen.io/khangnd/pe...
~~ 完,最近一个礼拜都在赶项目,基本都要2点后才能睡,这篇文章是间断整理好的,现在时间 是 9/20 深夜3点,睡了,感谢大家的观看。
代码部署后可能存在的BUG没法实时知道,事后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具 Fundebug。
原文:https://dev.to/khgnd/understa...
交流
有梦想,有干货,微信搜索 【大迁世界】 关注这个在凌晨还在刷碗的刷碗智。
本文 GitHub https://github.com/qq44924588... 已收录,有一线大厂面试完整考点、资料以及我的系列文章。
文章图片
推荐阅读
- 热闹中的孤独
- 2018-02-06第三天|2018-02-06第三天 不能再了,反思到位就差改变
- 尽力
- 你到家了吗
- 这辈子我们都不要再联系了
- 死结。
- 我从来不做坏事
- 时间老了
- 喂,你结婚我给你随了个红包
- 赢在人生六项精进二阶Day3复盘