李东的技术博客

文章内容Content

CSS关于属性值是百分比的知识盘点

2016/07/27 265 ℃ 抢个沙发

by LiDong from https://www.lidongtech.com/css-percent-value-inventory.html
本文可全文转载,但需得到原作者书面许可,同时保留原作者和出处。如果只是引流,请随意~

文章目录

罗嗦的开头

早上感觉不对劲,一睁眼就发现媳妇趴在我身上,她告诉我她的手机找不到了问我看没看到。我去啊~我刚睡醒谁特么知道你手机丢哪里去了?我就直接告诉她我没看到,而且我刚睡醒怎么可能知道。我又告诉她是不是早上上厕所了放厕所了,而且昨天晚上她是玩手机玩睡着的。这样看来,手机在厕所的几率是30%,手机在卧室的几率是70%。不过她非说是我藏起来的。我欲哭无泪啊,我说你再无理取闹我就不理你了。就算你用白花花的大美腿来诱惑我也没用。就像下面这张图一样。

说什么都不行,媳妇不依不饶,我算是无奈了。不过还好最后在床下面找到了。我看了看表才特么6点钟,这娘们这么早爬起来第一反应就是看自己的手机。算是没救了……不过她竟然在我申辩之后竟然不相信自己的老公,也着实可恶。我要处罚她……我擦玩过火了,现在腰还在酸疼~~! 😛

不过,仔细想想。百分比这种方式在我们的日常生活中还是比较常见的。例如我百分百没有×××,你百分百×××,某某百分百是×××等等。在我们的工作学习中百分比的形式更是多见。CSS中有些属性的值存在百分比的形式的,今天就来做个总结把这些属性百分比的知识加深下理解。

width和height

在前段中很多元素都是可以设置widthheight的。设置可能值的形式中也包含百分比。在早期网页设计中使用table经行布局时,为了保证表格能响应内容的变化,很多人都会使用百分比的值来渲染table。后来经过技术的演化迭代,table布局逐渐没落,div+css开始兴起。给widthheight设置固定的PX成为主流。百分比table的形式荣光不再,但伟大的想法总会是卷土重来。再后来移动客户端兴起,响应式布局也随着开始火起来。百分比也就是解决响应视口变化的不二法门。DIV+CSS、百分比形式再加上@media三者的结合有称霸前端的趋势。当然现在似乎更前沿的是css中的flex布局,这个有机会再聊。

前面说了这么多,其实widthheight设置百分比还是很容易被理解的,就是参照物是父元素。例如width:50%就是说元素的宽度是父元素宽度的50%,height:30%就是高度是父元素高度的30%。这个没什么要特别说的,就是对应父元素的属性值进行百分比计算,widthwidthheightheight。看下面的图就能理解。

width和height百分比计算方式

margin和padding

marginpadding的百分比是个比较难以理解的属性。当然它也是相对于父元素来计算自己百分比的值的,不过计算方式有点奇葩,它们是基于父元素的宽度(width)来进行计算的。margin-left/margin-rightpadding-left/padding-right基于父元素宽度还好理解,奇葩点就是margin-top/margin-bottompadding-top/padding-bottom的百分比也是基于父元素的宽度来计算的。什么个情况?难道不是widthheight的计算方法啊?

margin和padding百分比计算方式

上面的图中可以清晰的看出来实际渲染结果却是是按照父元素宽度的百分比来设置的。margin-top:10%;的实际渲染结果50px;padding-top:1%;的实际渲染效果是5px,它们都是根据父元素的宽度width:500px;产生的计算结果。这个试验印证了:子元素边距和填充距的值设为百分比,那么它的计算方式就是根据父元素的宽度(width来进行计算的。另外提一下的是,在上面的图中可以看到我在父元素设置了一个overflow:hidden;的声明。这个是为了防止margin collapsing的出现。关于margin collapsing的详细介绍出门右转在我的文章《浅析让人蛋疼的margin折叠》中有说明。

嗯!奇葩的百分比,我也跟着奇葩了。我竟然不说原理直接上实验结果了。酒香不怕巷子深,这点小小的“奇葩”不耽误我们理解这个知识点。从相应的官方文档《8.3 Margin properties》也能看到相应的说明。下面引用相应关于margin的资料。

The percentage is calculated with respect to the width of the generated box’s containing block. Note that this is true for ‘margin-top’ and ‘margin-bottom’ as well. If the containing block’s width depends on this element, then the resulting layout is undefined in CSS 2.1.

蹩脚的翻译:该百分比相对于设置元素的包含块的宽度计算。如果包含块的宽度取决于此元素,那么在CSS 2.1中的结果布局是未定义的。

然后这里是引用相应关于padding的资料,它来自于《5. The padding properties》

Note that percentages on ‘padding-top’ and ‘padding-bottom’ are relative to the width of the containing block, not the height (at least in a horizontal flow; in a vertical flow they are relative to the height).Note that percentages are not required for CSS level 2.

蹩脚的翻译:注意“padding-top”和“padding-bottom”的百分比与包含块的宽度有关,而不是高度(至少在水平流中),在垂直流中它们与高度相对应。CSS level2不需要百分比。

问题来了,为什么是基于宽度来计算呢?这是因为我们的“阅读模式”导致的,我们都是“从左向右逐字,由上到下逐行”的阅读习惯,这种模式也就决定了宽度必须是固定的,而高度是可以无限扩展的。在一个高度可以随时扩展且是无限的容器内,百分比的计算结果就会不固定,这个有悖于我们的“排版、布局”的设计初衷,页面元素变的不容易可控。所以依据宽度固定的计算结果能更好的控制“设计结果”。其实这是西方的阅读方式,我们中国的传统阅读习惯是“从上到下逐字,从右向左逐列”的模式,没办法谁让这玩意是人家发明的呢。

所以,如果使用属性writing-mode改变文本流的方向变成垂直流的话,那么这个计算方式就不是依据父元素的宽度了,而是依据复原度的高度。因为在垂直文本流中,高度变成固定而宽度变成了可以无限扩展。这个介绍到这里差不多了,继续下一个。

position

position是个大宝贝儿,不管是position:absolute;还是position: relative;使用方位都非常广。关于两者的区别不再过多啰嗦,这篇文章只关于百分比的问题。设置完毕position之后可以根据top/right/bottom/left属性的值来对元素进行定位,它们的取值形式中也还有百分比。关于百分比是和谁有关呢?先买个关子。我们先来建立一个概念,让我们的脑海中有个“逆Y轴坐标”——自己胡乱起的名字,别较真~

position坐标系

有了这个图之后,再理解top/right/bottom/left属性的百分比值就容易许多。说白了其实还是与父元素的widthheight属性有关。从图上可以知道top就是和父元素height有关,其他的几个属性的百分比计算也是一样,都是通过父元素来确定自己的值的。

需要注意的是top/right/bottom/left属性在同方向上只能有一个属性有效,例如设置了top再去设置bottom就会无效,设置了right再去设置left就会无效。如果四个同时设置,只会生效两个。他们的权重是上大于下,左大于右,意思是同时设置上下,那么上生效。同时设置左右,左生效。

而且在设置不同的组合,相当于原点来计算的元素顶点位置也是不一样的。具体情况如图:

position坐标系对应原点计算的顶点差异

常用的就这些了,不过还没完~嘿嘿嘿~~
进入中级装逼模式

盒模型影响

上面所有的情况都是在常规盒模型下的结果。也就是box-sizing: content-box;时的结果。如果修改为怪异盒模型即box-sizing: border-box;之后,计算方式没有变,该与谁有关就与谁有关。可是计算结果会多出一步来,就是需要减去borderpadding的值。

因为在标准盒模型下,宽和高的值就是固定的,是不包含borderpadding的。而怪异盒模型下的宽和高是包含borderpadding的值的。换句话说:在标准盒模型下,百分比的计算和宽高的值有关,拿来直接计算;在怪异盒模型下,百分比的计算是和容器真实大小有关(宽高-margin-padding=真实大小)。关于盒模型的概念在我的文章《盒模型与box-sizing》中很详细的说明。

举个例子就能验证下我的说法是否正确。想了半天,我还是不弄demo页了。因为快递小哥连续两天都忘拿我的东西了,今天说无论如何一定要直接送到我家,这会已经快到了。所以直接导进来凑合看吧。

See the Pen 盒模型模式对CSS属性百分比的影响 by tkoctkoc (@tkoctkoc) on CodePen.27881

如果我的心算没有错,橙色块的width:80px;height:15px;,人到了我要快点下去了,没时间验证。自己可以进入浏览器调试模式,选中橙色的块看下我的心算结果对不对。我闪了,88~

(报告完毕!)
本文标签:标签:, , ,