1-选择器
选择器:用于在文档树中选择HTML元素作为css样式规则的应用目标,可以分为以下几类:
- 元素选择器:也称类型选择器,通过元素的标签名称选择文档树中的元素,语法为:
elementname { /* style rules */ }; - 属性选择器:通过元素的属性值对的特点选择文档树中的元素; 语法为:
[atrr[(^|&|~|*)=value]] { /* style rules */ };其中类选择器.classname { /* style rules */ }是[class~=value] { /* style rules */ }的简单语法; - ID选择器:因为同一页面里id属性的值是唯一,所以哦那个过id属性的值可以选择文档树中的特定的元素;语法为:
#idname { /* style rules */ }; - 伪类选择器:根据元素的状态(位置状态、显示状态、交互状态等)选择元素,但不会在文档树中显示;语法为:
:pseudo-class { /* style rules */ }; - 通用选择器:匹配任一文档树中的元素;语法为:
* { /* style rules */ }; - 简单选择器:上述选择器的链式语法构成的选择器;如:
div#product.product[title="any"] - 伪元素选择器:依赖于,但不会在文档树中显示;语法为:
::pseudo-element { /* style rules */ }; - 组合选择器: 可以使用一些组合符号将简单选择器组合成更复杂的选择器;
1)后代选择符:使用“ ”表示;如:p span;
2)子代选择符:使用“>”表示;如:p > span;
3)后继兄弟选择符:使用“+”表示;如:p + span;
4)通用兄弟选择符:使用“~”表示;如:p ~ div;
3)列选择器:使用“||”表示;实验性属性,生产中不推荐使用;
2-CSS样式解析
浏览器将HTML文档渲染成页面的过程中会经历很多阶段,为了便于理解,这里忽略JS解析与执行的过程,只考虑HTML与CSS的解析。大致阶段如下:
- HTML元素被解析成Document Object Model,DOM;
- CSS样式规则被解析成CSS Object Model,CSSOM;
- DOM结合CSSOM生成Render Tree;
- Render Tree经过Visual Formating Model算法渲染成页面;
其中CSS样式的解析包括两个方面:
- 层叠规则解决样式冲突;
- 值解析,:1)将
rem,vh相对单位转换成绝对单位px;2)将url的相对地址转换成绝对地址;3)将#FFF,#FFFFFF, red等颜色值转换成操作系统定义的颜色值;
2-1、CSS层叠规则
CSS的层叠规则包含三个方面:important(重要性),specificity( 具体性,备注:找不到准确表达英文含义的中文词,考虑到从元素到内联样式,样式与元素联系越紧密越具体),order(顺序);
- 重要性:指属性值后是否添加
"!important"。根据样式来源与是否被表示important,优先级从上到下依次递减:
- 浏览器样式+
"!important"; - 开发者样式+
"!important"; - 用户样式;
- 开发者样式;
- 浏览器样式;
此外,CSS Cascading and Inheritance Level 5引入层叠层的概念,非标识为"i!mportant"的层叠层中属性,按照层叠层的顺序,后者覆盖前者;标识为"i!mportant",则相反。详情见@layer
- 具体性:不同类型的选择器具有不同的优先级权重,一般分为五个级别:内联样式 > ID选择器 > [伪]类选择器 > [伪]元素选择器 > 通用选择器;选择器的规则如下:
- 高级别的总比低级别的特异性高,不论低级别的数量有多少;
- 同一级别的选择器数量越多,特异性越高;
具体计算规则见CSS/Specificity
- 顺序:重要性相同与特异性相同的元素,最终的应用样式取决于样式规则的顺序,遵循“后来者居上”;
2-2、值解析
在讨论值解析前,需要说明的是:
- 在属性定义表中,每个CSS属性都有一个初始值;
- CSS属性可以分为继承属性与非继承属性;
在属性值的解析过程中,会对不同阶段的属性值赋予不同的名称,解析过程如下:
- 声明值(declared value):样式表中的声明规则定义的属性值;
- 层叠值(cascaded value):声明值经过层叠规则解析后的属性值;
- 指定值(specified value):也称默认值,经过defaulting后的属性值;
- 计算值(computed value):指定值绝对化后的属性值;
- 使用值(used value):计算值经过其他计算(如:布局计算)后的值;
- 实际值(actual value):由于设备与浏览器限制而不能精确到使用值,使用值经过取舍后的值;
其中defaulting阶段,又可以分为:
- 是否有层叠值,若有则指定值等于层叠值;否则,判断属性是否可以继承;
- 若属性可继承,则属性值等于父元素的计算值;否则,属性值等于初始值;
3-视觉格式化模型(Visual Formating Model)
视觉格式化模型:是描述浏览器如何将渲染树进行处理并显示到媒体介质上的一种算法。
在视觉格式化模型中,元素的布局受下列几种因素控制:
-
盒子尺寸与类型;
-
定位方式(正常流,浮动,绝对定位);
-
DOM中元素间的位置关系;
-
外部信息(视口,可替换元素的尺寸等)
理解视觉格式化模型,需要了解一些概念:
-
块布局:以左右书写方向为例,盒子上下垂直排列,盒子间距由margin决定(可能产生塌陷);盒子会换行;height与witdh属性有效;
-
内联布局:以左右书写方向为例:内联级盒子左右横向排列,内联级盒子不会换行;height与witdh属性无效;每行内的内联级盒子组成虚拟的行盒子,行盒子自上而下顺序排列;
-
块级盒子(Block-level Box):参与块布局的盒子;
-
内联级盒子(Inline-level Box):参与内联布局的盒子;
-
行盒子:由行内的内联级盒子组成的虚拟盒子。行的高度:等于处于行内的内联级盒子里的最高点与处于行内的内联级盒子最低点只差,宽度等于行内所有内联级盒子尺寸之和;(注意:行的高度并不是CSS属性line-height,在块级盒子上设置的
line-height,表示行的高度至少为line-height的设置值,但实际高度取决于行内的所有内联级盒子,计算如前所述); -
块级格式上下文(Block Formating Context):块级盒子参与的格式化上下文(块布局环境);
-
内联级格式上下文(Inline Formating Context):内联级盒子参与的格式化上下文(内联布局环境);
-
块容器(Block Container):生成块格式化上下文的盒子;
-
块盒子(Block Box ):既是块级盒子又是块容器的盒子;
3-1、盒子的显示
在视觉格式化模型中,每个元素至少会生成一个盒子。盒子的显示由"display"属性决定。
"display"属性实际包含两种显示类型:外部显示类型和内部显示类型。
- 外部显示类型(outer display type):定义盒子如何参与流布局(flow layout);
<display-outside> = block | inline | run-in; - 内部显示类型(inner display type):定义盒子生成的格式化上下文类型;<
display-inside> = flow | flow-root | table | flex | grid | ruby;
就像现在的商品房,每一层由多套房子组成,每一套房子由多个房间组成。房子自身具有两种角色:外部参与层的布局与内部如何布局房间。
3-2、盒模型
盒模型
1)盒子组成:内容区、内边距、边框、外边距;其中,内边距、边框、外边距默认值为0;此外,margin可以取负值,类似阳台可以悬空超出;
2)盒子尺寸(宽高):由"box-sizing"决定,包含:content-box (默认值)|| border-box;
当box-sizing:content-box;时,width与height表示内容区的尺寸;
当box-sizing:border-box;时,width与height表示边框的尺寸;
实际上,border-box更符合人的直觉,并且在响应式布局中,border-box使用更为常见;
3-3、定位方案
盒模型只考虑了盒子的尺寸,页面布局中需要考虑盒子的布局方式。
- 正常流布局:块盒子布局 + 内联盒子布局;
- 浮动布局:在浮动模型中,盒子先根据标准流定位,然后脱离标准流,尽可能的向右或向左移动;浮动最开始引入是为了使得文本可以围绕图像的视觉效果,后来人们发现不仅可以浮动图像,还可以浮动其他任何元素,使得浮动广泛应用于多栏布局,然随着浏览器对flex布局与grid布局的实现,可以使用这些新布局技术实现浮动布局的效果,不在推荐使用浮动布局;
- 绝对定位:上述布局只能实现二维布局,实际上网页是三维的,有时元素可以固定在某处或者在某些元素之上,这就需要使用绝对定位;在绝对定位模型中,盒子完全从标准流中移除,然后根据其包含块定位;元素的定位由
"position"属性决定,包含:static (默认值)|| relative || absolute || fixed || sticky;定位点由top | bottom | left | right属性决定;
3-4、堆叠上下文
除了水平方向的行内格式上下文与垂直方向的块格式上下文,还有z-axis(垂直于电脑屏幕)的层叠上下文。
每个盒子属于某一层叠上下文。在特定的层叠上下文中,每个定位盒子有一个用数字表示其在相同堆叠上下文中的相对层叠层级。层叠层级越高,盒子越靠近用户方向,视觉上表现为层叠层级高的盒子会覆盖层叠水平低的盒子。
层叠层级:用z-index属性来表示,包含两层意思:
- 盒子在当前堆叠上下文中的层叠层级;
- 盒子是否建立层叠上下文
非零整数:表示定位盒子在当前层叠上下文的层叠水平,并建立了新的层叠上
下文;
层叠顺序:在每层层叠上下文中,下列层由后向前绘制,如下图所示: