一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第6天,点击查看活动详情。
往期文章
- 微前端 qiankun 实践与总结
- 前端 JavaScript 基础知识总结(上)
- 前端 JavaScript 基础知识总结(中)
- 前端 JavaScript 基础知识总结(下)
- 前端 ES6 十个新特性总结
前言
一、如果把网页比作一个人的话,HTML就是他的骨架,而CSS是他的皮肤,JavaScript是神经控制着行动。所以学好CSS不仅能够美化我们的页面,更体现了一个优秀前端的基础功底
二、接下来的内容我将对CSS中的部分特性做出相关梳理和总结,为大家的前端知识体系进一步地巩固
总结
1.盒子模型
一、定义
- 浏览器的渲染引擎会根据标准之一的 CSS 基础框盒模型(CSS basic box model),将所有元素表示为一个个矩形的盒子(box)
二、组成
content
:即实际内容,显示文本和图像boreder
:即边框,围绕元素内容的内边距的一条或多条线,由粗细、样式、颜色三部分组成padding
:即内边距,清除内容周围的区域,内边距是透明的,取值不能为负,受盒子的background
属性影响margin
:即外边距,在元素外创建额外的空白,空白通常指不能放其他元素的区域
三、类型
1、标准盒子模型(盒子模型为W3C
标准盒子模型):width/height
只是内容高度,不包含 padding
和 border
值
- 盒子总宽度 = width + padding + border + margin
- 盒子总高度 = height + padding + border + margin
2、IE 怪异盒子模型:width/height
包含了 padding
和 border
值
- 盒子总宽度 = width + margin
- 盒子总高度 = height + margin
四、Box-sizing
1、语法:
box-sizing: content-box|border-box|inherit:
- content-box 默认值,元素的 width/height 不包含padding,border,与标准盒子模型表现一致
- border-box 元素的 width/height 包含 padding,border,与怪异盒子模型表现一致
- inherit 指定 box-sizing 属性的值,应该从父元素继承
2.选择器
一、定义
- 它是元素和其他部分组合起来告诉浏览器哪个HTML元素应当是被选为应用规则中的CSS属性值的方式
- 选择器所选择的元素,叫做“选择器的对象”
二、类型
- id选择器(#box),选择id为box的元素
- 类选择器(.one),选择类名为one的所有元素
- 标签选择器(div),选择标签为div的所有元素
- 后代选择器(#box div),选择id为box元素内部所有的div元素
- 子选择器(.one>one_1),选择父元素为.one的所有.one_1的元素
- 相邻同胞选择器(.one+.two),选择紧接在.one之后的所有.two元素
- 群组选择器(div,p),选择div、p的所有元素
- 伪类选择器
:link :选择未被访问的链接
:visited:选取已被访问的链接
:active:选择活动链接
:hover :鼠标指针浮动在上面的元素
:focus :选择具有焦点的
:first-child:父元素的首个子元素
- 伪元素选择器
:first-letter :用于选取指定选择器的首字母
:first-line :选取指定选择器的首行
:before : 选择器在被选元素的内容前面插入内容
:after : 选择器在被选元素的内容后面插入内容
- 属性选择器
[attribute] 选择带有attribute属性的元素
[attribute=value] 选择所有使用attribute=value的元素
[attribute~=value] 选择attribute属性包含value的元素
[attribute|=value]:选择attribute属性以value开头的元素
三、优先级
- 内联 > ID选择器 > 类选择器 > 标签选择器
- 内联样式的优先级最高,如果外部样式需要覆盖内联样式,就需要使用
!important
3.em px rem vh vw
一、定义
- 从
CSS3
开始,浏览器对计量单位的支持又提升到了另外一个境界,新增了rem
、vh
、vw
、vm
等一些新的计量单位 - 利用这些新的单位开发出比较良好的响应式页面,适应多种不同分辨率的终端,包括移动设备等
二、单位
CSS单位 | |
---|---|
相对长度单位 | em、ex、ch、rem、vw、vh、vmin、vmax、% |
绝对长度单位 | cm、mm、in、px、pt、pc |
三、px(像素)
1、定义:所谓像素就是呈现在我们显示器上的一个个小点,每个像素点都是大小等同的,所以像素为计量单位被分在了绝对长度单位中
- 有些人会把
px
认为是相对长度,原因在于在移动端中存在设备像素比,px
实际显示的大小是不确定的 - 这里之所以认为
px
为绝对单位,在于px
的大小和元素的其他属性无关
四、em(相对长度单位)
1、定义:相对于当前对象内文本的字体尺寸
- 如当前对行内文本的字体尺寸未被人为设置,则相对于浏览器的默认字体尺寸(
1em = 16px
) - 为了简化
font-size
的换算,我们需要在css
中的body
选择器中声明font-size
=62.5%
,这就使 em 值变为16px*62.5% = 10px
- 这样
12px = 1.2em
,10px = 1em
, 也就是说只需要将你的原来的px
数值除以 10,然后换上em
作为单位就行了
2、特点:
- em 的值并不是固定的
- em 会继承父级元素的字体大小
- em 是相对长度单位。相对于当前对象内文本的字体尺寸。如当前对行内文本的字体尺寸未被人为设置,则相对于浏览器的默认字体尺寸
- 任意浏览器的默认字体高都是 16px
五、rem(相对单位)
1、定义:相对的只是HTML根元素font-size
的值
- 如果想要简化
font-size
的转化,我们可以在根元素html
中加入font-size: 62.5%
- 这样页面中1rem=10px、1.2rem=12px、1.4rem=14px、1.6rem=16px;使得视觉、使用、书写都得到了极大的帮助
2、特点:
- rem单位可谓集相对大小和绝对大小的优点于一身
- 和em不同的是rem总是相对于根元素,而不像em一样使用级联的方式来计算尺寸
六、vh和vw(窗口的宽度、窗口的高度)
1、定义:就是根据,分成100等份,100vw就表示满宽,50vw就表示一半宽
2、类型:
- 在桌面端,指的是浏览器的可视区域
- 移动端指的就是布局视口
3、特点:像vw
、vh
,比较容易混淆的一个单位是%
,不过百分比宽泛的讲是相对于父元素:
- 对于普通定位元素就是我们理解的父元素
- 对于position: absolute;的元素是相对于已定位的父元素
- 对于position: fixed;的元素是相对于 ViewPort(可视窗口)
七、总结
- px:绝对单位,页面按精确像素展示
- em:相对单位,基准点为父节点字体的大小,如果自身定义了
font-size
按自身来计算,整个页面内1em
不是一个固定的 - rem:相对单位,可理解为
root em
, 相对根节点html
的字体大小来计算 - vh、vw:主要用于页面视口大小布局,在页面布局上更加方便简单
4.隐藏元素
一、display:none
1、定义:将元素设置为display:none
后,元素在页面上将彻底消失
- 元素本身占有的空间就会被其他元素占有,也就是说它会导致浏览器的重排和重绘
- 消失后,自身绑定的事件不会触发,也不会有过渡效果
2、特点:元素不可见,不占据空间,无法响应点击事件
二、visibility:hidden
1、定义:设置元素的visibility
为hidden
也是一种常用的隐藏元素的方法
- 从页面上仅仅是隐藏该元素,DOM结果均会存在,只是当时在一个不可见的状态,不会触发重排,但是会触发重绘
- 给人的效果是隐藏了,所以他自身的事件不会触发
2、特点:元素不可见,占据页面空间,无法响应点击事件
三、opacity:0
1、定义:opacity
属性表示元素的透明度,将元素的透明度设置为0后,在我们用户眼中,元素也是隐藏的
- 不会引发重排,一般情况下也会引发重绘
- 由于其仍然是存在于页面上的,所以他自身的的事件仍然是可以触发的,但被他遮挡的元素是不能触发其事件的
- 需要注意的是:其子元素不能设置opacity来达到显示的效果
2、特点:改变元素透明度,元素不可见,占据页面空间,可以响应点击事件
四、设置height、width属性为0
1、定义:
- 将元素的
margin
,border
,padding
,height
和width
等影响元素盒模型的属性设置成0 - 如果元素内有子元素或内容,还应该设置其
overflow:hidden
来隐藏其子元素
2、特点:元素不可见,不占据页面空间,无法响应点击事件
五、position:absolute
1、定义:将元素移出可视区域
2、特点:元素不可见,不影响页面布局
六、clip-path
1、定义:通过裁剪的形式
2、特点:元素不可见,占据页面空间,无法响应点击事件
七、区别
display: none | visibility: hidden | opacity: 0 | |
---|---|---|---|
页面中 | 不存在 | 存在 | 存在 |
重排 | 会 | 不会 | 不会 |
重绘 | 会 | 会 | 不一定 |
自身绑定事件 | 不触发 | 不触发 | 可触发 |
transition | 不支持 | 支持 | 支持 |
子元素可复原 | 不能 | 能 | 不能 |
被遮挡的元素可触发事件 | 能 | 能 | 不能 |
5.BFC
一、本质
1、定义:BFC
(Block Formatting Context),即块级格式化上下文,它是页面中的一块渲染区域,并且有一套属于自己的渲染规则
- 内部的盒子会在垂直方向上一个接一个的放置
- 对于同一个BFC的俩个相邻的盒子的margin会发生重叠,与方向无关。
- 每个元素的左外边距与包含块的左边界相接触(从左到右),即使浮动元素也是如此
- BFC的区域不会与float的元素区域重叠
- 计算BFC的高度时,浮动子元素也参与计算
- BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然
2、目的:形成一个相对于外界完全独立的空间,让内部的子元素不会影响到外部的元素
二、触发条件
- 根元素,即HTML元素
- 浮动元素:float值为left、right
- overflow值不为 visible,为 auto、scroll、hidden
- display的值为inline-block、inltable-cell、table-caption、table、inline-table、flex、inline-flex、grid、inline-grid
- position的值为absolute或fixed
6.垂直居中
一、定义:
1、类型:居中元素(子元素)的宽高已知、居中元素宽高未知
2、实现方式:
- 利用定位+margin:auto
- 利用定位+margin:负值
- 利用定位+transform
- table布局
- flex布局
- grid布局
3、总结:根据元素标签的性质,可以分为内联元素居中布局、块级元素居中布局
二、内联元素居中布局
1、水平居中:
- 行内元素可设置:text-align: center
- flex布局设置父元素:display: flex; justify-content: center
2、垂直居中:
- 单行文本父元素确认高度:height === line-height
- 多行文本父元素确认高度:disaply: table-cell; vertical-align: middle
三、块级元素居中布局
1、水平居中:
- 定宽: margin: 0 auto
- 绝对定位+left:50%+margin:负自身一半
2、垂直居中:
- position: absolute设置left、top、margin-left、margin-top(定高)
- display: table-cell
- transform: translate(x, y)
- flex(不定高,不定宽)
- grid(不定高,不定宽),兼容性相对比较差
7.Flexbox
一、本质
1、定义:Flexible Box
简称 flex
,意为”弹性布局”,可以简便、完整、响应式地实现各种页面布局
- 采用Flex布局的元素,称为
flex
容器container
- 它的所有子元素自动成为容器成员,称为
flex
项目item
- 容器中默认存在两条轴,主轴和交叉轴,呈90度关系。项目默认沿主轴排列,通过
flex-direction
来决定主轴的方向 - 每根轴都有起点和终点,这对于元素的对齐非常重要
2、属性:flex-direction、flex-wrap、flex-flow、justify-content、align-items、align-content、flex
二、flex-direction
1、定义:决定主轴的方向(即项目的排列方向)
.container {
flex-direction: row | row-reverse | column | column-reverse;
}
2、属性:
- row(默认值):主轴为水平方向,起点在左端
- row-reverse:主轴为水平方向,起点在右端
- column:主轴为垂直方向,起点在上沿。
- column-reverse:主轴为垂直方向,起点在下沿
三、flex-wrap
1、定义:弹性元素永远沿主轴排列,那么如果主轴排不下,通过flex-wrap
决定容器内项目是否可换行
.container {
flex-wrap: nowrap | wrap | wrap-reverse;
}
2、属性:
- nowrap(默认值):不换行
- wrap:换行,第一行在下方
- wrap-reverse:换行,第一行在上方
3、注意:默认情况是不换行,但这里也不会任由元素直接溢出容器,会涉及到元素的弹性伸缩
四、flex-flow
1、定义:是flex-direction
属性和flex-wrap
属性的简写形式,默认值为row nowrap
.box {
flex-flow: <flex-direction> || <flex-wrap>;
}
五、justify-content
1、定义:项目在主轴上的对齐方式
.box {
justify-content: flex-start | flex-end | center | space-between | space-around;
}
2、属性:
- flex-start(默认值):左对齐
- flex-end:右对齐
- center:居中
- space-between:两端对齐,项目之间的间隔都相等
- space-around:两个项目两侧间隔相等
六、align-items
一、定义:项目在交叉轴上如何对齐
.box {
align-items: flex-start | flex-end | center | baseline | stretch;
}
二、属性:
- flex-start:交叉轴的起点对齐
- flex-end:交叉轴的终点对齐
- center:交叉轴的中点对齐
- baseline: 项目的第一行文字的基线对齐
- stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度
七、align-content
1、定义:多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用
.box {
align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}
2、属性:
- flex-start:与交叉轴的起点对齐
- flex-end:与交叉轴的终点对齐
- center:与交叉轴的中点对齐
- space-between:与交叉轴两端对齐,轴线之间的间隔平均分布
- space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍
- stretch(默认值):轴线占满整个交叉轴
3、容器成员属性:
order
、flex-grow
、flex-shrink
、flex-basis
、flex
、align-self
八、flex
1、定义:flex
属性是flex-grow
, flex-shrink
和 flex-basis
的简写,默认值为0 1 auto
.item {
flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}
2、属性:
- flex: 1 = flex: 1 1 0%
- flex: 2 = flex: 2 1 0%
- flex: auto = flex: 1 1 auto
- flex: none = flex: 0 0 auto,常用于固定尺寸不伸缩
8.Grid
一、定义
1、Grid
布局即网格布局,是一个二维的布局方式,由纵横相交的两组网格线形成的框架性布局结构,能够同时处理行与列
- 擅长将一个页面划分为几个主要区域,以及定义这些区域的大小、位置、层次等关系
- 设置
display:grid/inline-grid
的元素就是网格布局容器,这样就能出发浏览器渲染引擎的网格布局算法
二、属性
1、display:
- 在元素上设置
display:grid
或display:inline-grid
来创建一个网格容器 - display:grid 则该容器是一个块级元素
- display: inline-grid 则容器元素为行内元素
2、grid-template-columns、grid-template-rows:
grid-template-columns
属性设置列宽grid-template-rows
属性设置行高
3、grid-row-gap、grid-column-gap、grid-gap:
grid-row-gap
属性、grid-column-gap
属性分别设置行间距和列间距grid-gap
属性是两者的简写形式
4、grid-template-areas:一个区域由一个或者多个单元格组
5、grid-auto-flow:
- 划分网格以后,容器的子元素会按照顺序,自动放置在每一个网格
- 顺序就是由
grid-auto-flow
决定,默认为行,代表"先行后列",即先填满第一行,再开始放入第二行
6、justify-items、align-items、place-items
justify-items
属性设置单元格内容的水平位置(左中右)align-items
属性设置单元格的垂直位置(上中下)place-items
属性是align-items
属性和justify-items
属性的合并简写形式
7、justify-content、align-content、place-content
justify-content
属性是整个内容区域在容器里面的水平位置(左中右)align-content
属性是整个内容区域的垂直位置(上中下)
8、grid-auto-columns、grid-auto-rows
- 一些项目的指定位置,在现有网格的外部,就会产生显示网格和隐式网格
- 比如网格只有3列,但是某一个项目指定在第5行。这时,浏览器会自动生成多余的网格,以便放置项目。超出的部分就是隐式网格
- 而
grid-auto-rows
与grid-auto-columns
就是专门用于指定隐式网格的宽高
9、grid-column-start、grid-column-end、grid-row-start、grid-row-end
- 指定网格项目所在的四个边框,分别定位在哪根网格线,从而指定项目的位置
- grid-column-start 属性:左边框所在的垂直网格线
- grid-column-end 属性:右边框所在的垂直网格线
- grid-row-start 属性:上边框所在的水平网格线
- grid-row-end 属性:下边框所在的水平网格线
10、grid-area:属性指定项目放在哪一个区域
11、justify-self、align-self、place-self
justify-self
属性设置单元格内容的水平位置(左中右),跟justify-items
属性的用法完全一致,但只作用于单个项目align-self
属性设置单元格内容的垂直位置(上中下),跟align-items
属性的用法完全一致,也是只作用于单个项目
9.回流与重绘
一、定义
1、解析过程:
- 回流:布局引擎会根据各种样式计算每个盒子在页面上的大小与位置
- 重绘:当计算好盒模型的位置、大小及其他属性后,浏览器根据每个盒子特性进行绘制
2、渲染机制:
- 解析HTML,生成DOM树,解析CSS,生成CSSOM树
- 将DOM树和CSSOM树结合,生成渲染树(Render Tree)
- Layout(回流):根据生成的渲染树,进行回流(Layout),得到节点的几何信息(位置,大小)
- Painting(重绘):根据渲染树以及回流得到的几何信息,得到节点的绝对像素
- Display:将像素发送给GPU,展示在页面上
二、如何减少
- 如果想设定元素的样式,通过改变元素的
class
类名 (尽可能在 DOM 树的最里层) - 避免设置多项内联样式
- 应用元素的动画,使用
position
属性的fixed
值或absolute
值(如前文示例所提) - 避免使用
table
布局,table
中每个元素的大小以及内容的改动,都会导致整个table
的重新计算 - 对于那些复杂的动画,对其设置
position: fixed/absolute
,尽可能地使元素脱离文档流,从而减少对其他元素的影响 - 使用css3硬件加速,可以让
transform
、opacity
、filters
这些动画不会引起回流重绘 - 避免使用 CSS 的
JavaScript
表达式 - 在使用
JavaScript
动态插入多个节点时, 可以使用DocumentFragment
. 创建后一次插入. 就能避免多次的渲染性能
10.优化和提高性能
一、内联首屏关键CSS
1、在打开一个页面,页面首要内容出现在屏幕的时间影响着用户的体验,而通过内联css
关键代码能够使浏览器在下载完html
后就能立刻渲染
- 而如果外部引用
css
代码,在解析html
结构过程中遇到外部css
文件,才会开始下载css
代码,再渲染 - 所以,
CSS
内联使用使渲染时间提前
2、注意:但是较大的css
代码并不合适内联(初始拥塞窗口、没有缓存),而其余代码则采取外部引用方式
二、异步加载CSS
1、在CSS
文件请求、下载、解析完成之前,CSS
会阻塞渲染,浏览器将不会渲染任何已处理的内容
2、前面加载内联代码后,后面的外部引用css
则没必要阻塞浏览器渲染。这时候就可以采取异步加载的方案,主要有如下
- 使用javascript将link标签插到head标签最后
- 设置link标签media属性为noexis,浏览器会认为当前样式表不适用当前类型,会在不阻塞页面渲染的情况下再进行下载。加载完成后,将
media
的值设为screen
或all
,从而让浏览器开始解析CSS - 通过rel属性将link元素标记为alternate可选样式表,也能实现浏览器异步加载。同样别忘了加载完成之后,将rel设回stylesheet
三、资源压缩
- 利用
webpack
、gulp/grunt
、rollup
等模块化工具,将css
代码进行压缩,使文件变小,大大降低了浏览器的加载时间
四、合理使用选择器
1、css
匹配的规则是从右往左开始匹配,例如#markdown .content h3
匹配规则如下
- 先找到h3标签元素
- 然后去除祖先不是.content的元素
- 最后去除祖先不是#markdown的元素
2、如果嵌套的层级更多,页面中的元素更多,那么匹配所要花费的时间代价自然更高
3、所以我们在编写选择器的时候,可以遵循以下规则
- 不要嵌套使用过多复杂选择器,最好不要三层以上
- 使用id选择器就没必要再进行嵌套
- 通配符和属性选择器效率最低,避免使用
五、减少使用昂贵的属性
- 在页面发生重绘的时候,昂贵属性如
box-shadow
/border-radius
/filter
/透明度/:nth-child
等,会降低浏览器的渲染性能
六、不要使用@import
1、css样式文件有两种引入方式,一种是link
元素,另一种是@import
2、@import
会影响浏览器的并行下载,使得页面在加载时增加额外的延迟,增添了额外的往返耗时
- 而且多个
@import
可能会导致下载顺序紊乱 - 比如一个css文件
index.css
包含了以下内容:@import url("reset.css")
3、那么浏览器就必须先把index.css
下载、解析和执行后,才下载、解析和执行第二个文件reset.css
七、其他
- 减少重排操作,以及减少不必要的重绘
- 了解哪些属性可以继承而来,避免对这些属性重复编写
- cssSprite,合成所有icon图片,用宽高加上backgroud-position的背景图方式显现出我们要的icon图,减少了http请求
- 把小的icon图片转成base64编码
- CSS3动画或者过渡尽量使用transform和opacity来实现动画,不要使用left和top属性
八、总结
css
实现性能的方式可以从选择器嵌套、属性特性、减少http
这三面考虑,同时还要注意css
代码的加载顺序
结尾
- 好了,本篇的所有内容就到这里了,希望大家能够在未来的日子里学以致用!