资讯专栏INFORMATION COLUMN

【CSS深入】设置不同块级流方向时的属性百分比计算

Yujiaao / 3438人阅读

摘要:简言之,块级流方向包含两种一种是水平流,一种是垂直流。对百分比计算的影响首先,先明确这里要讨论的是块级元素的水平流和垂直流对的百分比属性值的计算值的影响。

百分比在屏幕自适应是我们常用,但是很多时候某个CSS属性的百分比计算值,并非如我们所想象的那样子。前段时间有位同学分享了一篇关于margin/padding自适应布局的文章,看完后我去w3.org查了下marginpadding百分比计算的注意事项,描述如下:

Note that in a horizontal flow, percentages on ‘margin-top’ and ‘margin-bottom’ are relative to the width of the containing block, not the height (and in vertical flow, ‘margin-left’ and ‘margin-right’ are relative to the height, not the width).[1]

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).[2]

水平流?垂直流?那是甚么鬼?之前我一直不明白这两者何意,直到最近看CSS权威指南,讲到direction的时候提到了CSS Writing Modes Level 3里的writing-mode,查了官方文档后才知道,CSS3以后就有了定义内容书写方向的规范。

什么是块级流方向

块级流方向就是块级盒子在块级格式化上下文中以何种方向来进行顺序排列。这里要注意的一点是对于英文(也是简体中文)这种从上至下从左至右书写的语言,writing-modedirection分别会被默认设为horizontal-tbltr。简言之,块级流方向包含两种:一种是水平流,一种是垂直流。另外在CSS权威指南P171有提到,我们常见的margin的初始值是0,但是我们看到的大都是靠在左上方的,因为在英文语言的书写顺序、也就是块级流方向下,margin-rightmargin-bottom被默认强制设为auto了。如果不明白这些默认的强制格式化属性规范,很多时候我们做出来页面的效果可能会有点不合本意。这时我才渐渐意识到文本语言码识别lang和字符码识别charset在多语言情境下的重要性,另外关于FBC的内容还我也还未深入了解(这里挖个坑,以后填),请参看参考目录部分。

如何设置块级流方向

direction属性只是影响的行内类型内容的书写方向,而writing-mode则是可以直接影响块级元素的布局。horizontal-tb是我们常用页面的默认设定,决定了内容的水平方向书写和块级流方向的从上往下推进;vertical-rlvertical-lr则是部分语言的书写方向,这两个属性值决定了内容的垂直方向书写以及块级流方向分别是从右往左推进和从左往右的推进,比如,古汉字应用中最常见的是圣旨是从右向左推进、从上往下书写的,现代的日语也有这种格式的。

对百分比计算的影响

首先,先明确这里要讨论的是块级元素的水平流和垂直流对marginpaddingwidthheight的百分比属性值的计算值的影响。
然后,准备好测试代码(可以去我的github下找到ver_hor_flow.html和ver_hor_flow.css):

test contet
test content
#outer {
    background-color: fuchsia;
    height: 300px;
    width: 500px;
}
#inner {
    background-color: lime;
    margin: 1% 8% 2% 5%;
    padding: 1% 8% 2% 5%;
    height: 10%;
    width: 50%;
}

这里,我们对内部的子元素直接设置了宽高以便于,观察父元素容器的水平流和垂直流对子元素宽高的影响。但是如果不设置宽高,则子元素的宽高默认会是内容宽高,而内容高(垂直流中变成横向的了,以width衡量)由行高决定,而行高则在字体大小的基础上乘以一个浏览器默认的缩放因子来得到,字体大小也是有一个浏览器默认的计算值。比如我的浏览器默认是font-size:16px;以及line-height:21px;,这个21px是字体大小与一个缩放因子相乘后的结果,内容高度就是它了。Anyway,下面继续。

父元素容器水平流

对父元素,默认设置writing-mode: horizotal-tb;,水平流。
测试图:


margin-toppadding-top:500px乘以1%=5px
margin-rightpadding-right:500px乘以8%=40px
margin-bottompadding-bottom:500px乘以2%=10px
margin-leftpadding-left:500px乘以5%=25px
width:500px乘以50%=250px
height:300px乘以10%=30px
小结:可以看出,子元素marginpadding是以父元素的width为基数计算的,而子元素的widthheight是对应以父元素的widthheight为基数计算的。

父元素容器垂直流

对父元素设置writing-mode:vertical-lr;,垂直流。
测试图:


margin-toppadding-top:300px乘以1%=3px
margin-rightpadding-right:300px乘以8%=24px
margin-bottompadding-bottom:300px乘以2%=6px,这里margin-bottom的258px是因为我们设置了height:10%;,由于margin只是设置的最小值,一旦不足他会自动补上剩余的部分(300px-3px-3px-30px-6px=258px)。如果没设置height就会“正常”了。(这里要考虑到“过度受限”规则影响,也就是一个盒子的计算值相互矛盾的情况下,进行的一种“优先级”权衡。这里的自动补充计算值其实是因为对于水平流、从上往下推进的语言,实际上的margin-bottom会被强制设为auto,至于为何margin-right又正常呢?嗯,我也还在深入了解这个影响计算规则的“过度受限overconstrained”。)
margin-leftpadding-left:300px乘以5%=15px
width:500px乘以50%=250px
height:300px乘以10%=30px
小结:设置垂直流以后,marginpadding的百分比计算基数变成了父元素的高度(height:300px;),而子元素的widthheight的百分比计算仍然是对应以父元素的widthheight为基数计算的。
这里只测试了垂直流中从右向左推进时,各属性值的计算,另一种从左向右推进的各属性值计算结果是一样的,在此不赘述。

子元素垂直流

上面都是对作为容器的父元素进行块级流方向设置,如果只是对于子元素设置呢?
对内部的子元素设置writing-mode: vertical-lr;父元素不做其他设置,即默认。


小结:子元素的宽高和外边距、内边距都没有改变,也就是说子元素改变的块级流方向不影响本身marginpaddingwidthheight的计算值。

2D变形中旋转的影响

2D变形中有个rotate()函数可以扭转一个元素的摆放方向,那这个函数的设置会不会对子元素本身的marginpaddingwidthheight计算值造成影响呢?
设置transform:rotate(-90deg);


小结:变形只是改变了子元素的表现形式,但是并未改变子元素的百分比计算值。
--------------------------------------割----------------------------------
两天后,回过头看了下,这部分还要加个父元素的测试才算完整。不过结果是一样的:各属性的百分比数值计算并不受影响。我的Github上的测试代码,会同步更新。

边框不可设置百分比

查看边框的官方标准可知,边框不能设置百分比属性值,但是有相对属性值em、ex等,它们的计算都是以当前字体大小为基数。

box-sizing属性的影响

这个属性只会影响到设置widthheight后,内容区的大小,它对于外边距和内边距的计算不影响。

总结

在常用的盒模型百分比计算中,子元素的widthheight始终跟随父元素对应的宽高计算;而子元素的marginpadding则要考虑当前文档的块级流方向是水平流还是垂直流,如果是水平流,则以父元素的width为基数计算百分比,如果是垂直流则以父元素的height为基数计算百分比。单个子元素改变块级流方向以及设置变形都不改变父元素下子元素的块级流方向,不影响百分比计算。边框不可设置百分比。

参考

《CSS权威指南(第三版)》

CSS basic box model

CSS Writing Modes Level 3

Visual formatting model

详说 Block Formatting Contexts (块级格式化上下文) | Kayo"s Melody

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/111269.html

相关文章

  • 深入理解css盒子模型

    摘要:下面我们就一步一步揭开的神秘面纱,深入理解盒模型,这对我们在布局上会有一个质的提升。与内联元素的百分比值与内联元素。 css是一门具象语言,并不像js那样具有逻辑性,因此,就算入行了前端很久的工程师,也觉得css难以掌握。下面我们就一步一步揭开css的神秘面纱,深入理解css盒模型,这对我们在布局上会有一个质的提升。 盒子模型 showImg(https://segmentfault....

    gplane 评论0 收藏0
  • css世界》- 详细重点笔记与技巧

    摘要:概述在世界这本书中有一些黑魔法给列举出来,在结合自己的理解。篇幅有点长,希望大家能够坚持看完,一定会有收获以下是摘自每章内一些重要的概念与技巧。 概述 在《css世界》这本书中有一些黑魔法给列举出来,在结合自己的理解。篇幅有点长,希望大家能够坚持看完,一定会有收获!!!以下是摘自每章内一些重要的概念与技巧。其中有解决图片间隙的问题、小图标与文字居中问题等; ps: 特别是 line-h...

    MasonEast 评论0 收藏0
  • css世界》- 详细重点笔记与技巧

    摘要:概述在世界这本书中有一些黑魔法给列举出来,在结合自己的理解。篇幅有点长,希望大家能够坚持看完,一定会有收获以下是摘自每章内一些重要的概念与技巧。 概述 在《css世界》这本书中有一些黑魔法给列举出来,在结合自己的理解。篇幅有点长,希望大家能够坚持看完,一定会有收获!!!以下是摘自每章内一些重要的概念与技巧。其中有解决图片间隙的问题、小图标与文字居中问题等; ps: 特别是 line-h...

    赵连江 评论0 收藏0
  • 你有所不知的margin属性

    摘要:前言致谢本文总结于张鑫旭老师的深入理解之课程,感谢张老师的辛苦付出难学的作为前端狗的我们,每天都要和网页打交道。页面中任何地方,嵌套或直接放入任何空的,都不会影响原来的布局。比如,给元素声明,但在中的属性是。 前言 致谢  本文总结于 张鑫旭老师的 CSS深入理解之margin课程,感谢张老师的辛苦付出! 难学的 CSS  作为前端狗的我们,每天都要和网页打交道。当 UI 将设计稿发给...

    joywek 评论0 收藏0

发表评论

0条评论

Yujiaao

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<