CSS / CSS3

Posted Silam Lin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CSS / CSS3相关的知识,希望对你有一定的参考价值。

CSS / CSS3 篇


勤能补拙,查缺补漏!基础不牢,地动山摇!
分点回答,全面细致!打好基础,打好基础!

三种导入CSS的方式

导入CSS的三种方式

CSS盒子模型

  • 当浏览器渲染进行到了“布局”步骤的时候,会把所有的元素表示作一个一个的盒子。
  • 盒子模型由四部分组成,由内到外分别是:content内容、padding内边距、border边框和margin外边距。
  • 盒子模型可以分作两大类,即IE盒模型标准盒模型。IE盒模型的width是包括content、padding和border;而标准盒模型的width只是包括content。
  • CSS有box-sizing属性:box-sizing:content-box|border-box|inherit-box。分别对应的盒子模型是标准盒模型、IE盒模型和继承。
  • 实际开发中,IE盒模型会更加方便。因为在IE盒模型设置width,直接控制的就是盒子的实际宽度(content+padding+border),不会因为设置padding或者border而改变盒子大小从而影响布局;倘若是标准盒模型,设置宽度width仅仅是控制content部分。再设置padding或border,会把该盒子“再撑大”,增加盒子的实际宽度,从而影响布局,不方便。

CSS选择器

CSS 基础选择器、组合选择器、属性选择器、伪类选择器、伪元素、CSS3属性选择器、优先级

一、基础选择器

  • 通配符选择器 (可用于清除默认边距)
  • 标签选择器
  • class选择器
  • id选择器

二、组合选择器

  • 多元素选择器 E,F
  • 后代元素选择器 E F
  • 子代元素选择器 E > F
  • 毗邻兄弟元素选择器 E + F (选择紧跟在F后面的E元素且E和F要有同一个父元素)

三、属性选择器 (可匹配选择多个属性)

  • *[att],选择所有具有att属性的元素
  • E[att] ,选择所有具有att属性的E元素
  • E[att=“value”],选择所有具有att属性,且att属性的值为value的E元素
  • E[att~=“value”],选择所有具有att属性,且att属性的其中一个值为value的E元

四、链接伪类

  • link表示未访问时的状态
  • visited表示访问过的状态
  • hover表示鼠标悬停在上面时的状态
  • active表示鼠标已经按下但未释放时的状态

五、:first-child伪类
六、伪元素

伪类与伪元素

区别:

  • 伪类是单冒号;伪元素是双冒号
  • 伪类用于选择已有元素处于某个特定状态时,给其赋予特定的样式(链接伪类);伪元素是用于创建一些不在文档树的元素,虽然可以看到,但它就是不处于文档树中(::before、::after)

伪类:

  • 链接伪类:lvha
  • first-child伪类

伪元素:

  • ::first-line 作用于块级元素的首行
  • ::first-letter 作用于块级元素的首字母
  • ::before
  • ::after
h1::after 
  content: url(smiley.gif);

选择器的优先级

  • !important > 行内样式>ID选择器 > 类选择器 > 标签选择器 > 通配符 > 继承 > 浏览器默认属性
  • 行内样式 > style样式 > 外部链接

如果是同一级别的,后续样式将覆盖前面的样式。

选择器权重的计算规则

  • ① 行内样式,1,0,0,0
  • ② ID选择器,0,1,0,0
  • ③ 类选择器、属性选择器、伪类选择器,0,0,1,0
  • ④ 标签元素、伪元素,0,0,0,1
  • ⑤ 通配符*、子代选择器>、毗邻兄弟元素选择器+,0,0,0,0

规则说明:

  • 每一类只对特定的位做出贡献,譬如行内样式只对 x,0,0,0 的 x 位做贡献
  • 同一位的权重可以叠加,但不可进位
  • 高位数的权重一定大于低位数的

选择器为什么是从右往左匹配的

简单来说,从右往左去匹配选择器,可以一定程度上减少许多不必要的匹配,从而提升性能。

譬如 div span a

如果从左边开始,是从最不具体的规则到最具体的规则。有可能遍历到最末的子节点,发现不是a,那就又需要回溯上去重新匹配。

如果最后都不是a,何必在一开始花那么多时间匹配左边的规则呢。

所以CSS选择器是从右边往左边开始匹配的,把最终不是a的统统pass掉,最后可以减少很多不必要的匹配。

可以继承的属性有哪些

字体相关

  • font
  • font-family
  • font-weight
  • font-size
  • font-style

文本相关

  • text-indent
  • text-align
  • line-height
  • word-spacing
  • letter-spacing
  • color

其它

  • cursor 光标
  • visibility

注意

  • a标签的字体颜色无法继承
  • h1-h6的字体大小无法继承

px / em / rem / vh / vw / %百分比

px:

  • px 即 pixel 像素,是屏幕上的一个个小点,是相对于屏幕的分辨率而言

em:

  • em是相对单位长度,其值不是固定的
  • 一般情况下,em是相对于当前对象内文本的字体尺寸
  • 若行内文本的字体尺寸没有被设置,则相对于浏览器的默认字体尺寸(即1em=16px)
  • 为了简化使用,一般在body里面设置font-size:62.5%,即font-size:10px。那么1em = 10px

rem:

  • rem相对于root em。它直接是相对于html根元素的文本字体尺寸大小

vh与vw:

  • vh是viewport height,vw是viewport width
  • 是根据窗口的高度和宽度分成100等分:100vh就是满高,100vw就是满宽;50vh就是半宽

%百分比:

  • 对于普通元素,%是相对于其父元素
  • 若元素设置position:absolute,则相对的是已经定位的父元素
  • 若元素设置position:fixed,则相对的是viewport

background属性

background-image 设置背景图像

background-color 背景的颜色

background-position 背景图像image的起始位置

background-size 背景图像的尺寸(length|percentage|cover|contain)

  • length 设置背景图像的宽度和高度
  • percentage 以父元素的百分比来设置图像的宽度和高度
  • cover 让背景图像完全覆盖整个背景区域(有可能背景图像的某些部分无法显示在背景区域当中)
  • contain 把背景图像扩展到最大尺寸,使得宽度和高度完全适应内容区域

background-repeat 设置背景图像的平铺方式

  • repeat (default)图像在水平方向和竖直方向上重复
  • repeat-x
  • repeat-y
  • no-repeat
  • inherit

background-origin 规定background-position相对于什么参考来定位

  • content-box
  • padding-box
  • border-box

background-clip 规定背景的绘制区域

  • content-box
  • padding-box
  • border-box

background-attachment

  • scroll 背景图像会随着页面其余部分的滚动而移动
  • fixed 背景图像固定
  • inherit

position的取值

  • CSS的position属性有四个值:absolute、relative、static、fixed。配合设置TLBR(top、left、bottom、right)可以调整布局和元素位置。
  • absolute 是绝对定位,会脱离文档流即不占据空间。它是相对与最近一个非static的父元素而进行定位的, 否则则以body为标准定位。
  • relative 是相对定位,不脱离文档流。它是相对于自身静态位置而进行定位的。
  • static 是静态定位,不脱离文档流。没有特别的设定,就出现在正常的文档流中
  • fixed 是固定定位,会脱离文档流。 它定位的参考则是屏幕视口viewport,而不是body元素。效果即在页面滚动时,fixed定位的元素是不会移动的。

display的取值

常见的有:

  • none 元素不显示,从文档流中完全移除
  • block 块级元素
  • inline 行内元素
  • inline-block 行内块元素

还有:

  • table 元素为块级表格
  • list-item 生成块级列表
  • inherit 从父元素继承display的值

block、inline、inline-block的区别

block 块级盒子

  • 独占一行
  • 可定义width,height,默认宽度100%
  • 可定义四个方向上的margin和padding
  • 内部可容纳其它block或inline元素

inline 行内盒子

  • 不独占一行
  • 不可定义width,height,默认宽度为自身内容宽度
  • 只能定义margin-left,margin-right,padding-left,padding-right
  • 内部只能容纳inline元素或者文本

inline-block 行内块盒子

  • 不独占一行
  • 可定义width,height,默认宽度为自身宽度
  • 可以定义四个方向上的margin和padding

display:none;visibility:hidden;opacity:0

  • display:none 不占有原来的位置,影响布局;元素所绑定的事件也不会被触发,忽略了元素的权重。相当于在渲染树中完全消失。
  • visibility:hidden 占有原来的位置,不影响布局;元素所绑定的事件不能被触发。
  • opacity:0 占有原来的位置,不影响布局;元素所绑定的事件还是能被触发。

隐藏页面元素的方式

主要方式有三种:

  • opacity:0 即设置元素的透明度为0。特点:仍存在页面中,不影响布局,仍可触发元素所绑定的事件。
  • visibility:hidden 即设置元素为不可见。特点:仍存在页面中,不影响布局,不可触发元素所绑定的事件。
  • display:none 即让元素彻底消失。特点:不存在页面中,影响布局,不可触发元素所绑定的事件,

关于重排重绘,注意:

  • display:none 会引起重排和重绘;
  • visibility:hidden 会引起重绘,不引起重排;
  • opacity:0 不一定会重绘,不引起重排

另外还可以:

  • 设置position:absolute ; top:-9999px ; left:-9999px ;即让元素脱离文档流,并向外移出
  • 设置margin、border、padding、width和height为0即可使元素不可见。若有子元素则再设置overflow:hidden从而隐藏子元素
  • z-index 设置为负值,使层叠级别变低而被覆盖
  • transform:scale(0,0),设置缩放

标准流、浮动流、浮动带来的影响

① 首先明确标准流的规则:

  • 一个页面从上到下,分作一行一行。
  • block块级元素独占一行
  • inline行内元素和inline-block行内块元素不独占一行,在每一行中从左到右排列将该行占满

② 为什么要有浮动,浮动流是什么?

  • 最初,浮动的出现只是想实现 文字环绕 这一效果。
  • 后来,我们想要让 block块级元素能够在同一行显示,而不是像往常一样块级元素独占一行。
  • 显然,标准流无法满足我们的需求
  • 所以,需要将元素设置为浮动,成为浮动流。

③ 若某元素设置float:left或者是float:right,会页面发生以下变化:

  • 元素本身脱离标准流,成为浮动流
  • 剩下的元素成为新的标准流
  • 设置浮动的元素,会向左向右浮动,直至碰到父元素或浮动元素

④ 浮动带来的影响

  • 1、对元素自身:元素若设置了float属性,那么它就变成了block块级元素(不独占一行),可以设置width,hight,padding和margin
  • 2、对父元素:子元素设置float,若其高度大于父元素的高度,或者父元素不便设置高度,那么会出现父元素塌陷
  • 3、对兄弟元素:自身是浮动元素则脱离标准流,剩下的元素成为新的标准流,则会影响页面布局

清除浮动的方式

① clear:both

  • 在浮动元素后面,添加一个div class='clear’元素
  • 选择题设置为 clear:both,清除所有浮动
  • 评价:并不推荐:添加了无意义代码,破坏html的语义性;若需要多次清除浮动,则需要多次添加无意义标签

② clear:both + ::after 伪元素

.clearfix
	*zoom:1;   // 解决IE6 IE7的浮动问题

.clearfix::after
	display:block;
	content:'';
	height:0;
	clear:both;

③ 考虑使用BFC

两栏布局的实现

两栏布局:左边定宽,右边自适应

实现一、 利用BFC

  • 左边盒子设置float:left左浮动,且设置width为定宽;
  • 右边盒子设置overflow:hidden,触发BFC

实现二、 利用flex布局

  • 父盒子设置display:flex
  • 左边盒子设置定宽width
  • 右边盒子设置flex:1 (flex-grow为1)

实现三、 利用Grid布局

  • display:grid 生成grid容器
  • grid-template-columns: 200px auto;

三栏布局的实现

实现一、 利用flex布局

  • 父盒子设置display:flex,且设置justify-content:space-between(两边对齐)
  • 左盒子右盒子设置定宽
  • 中间盒子设置width:100%,或者flex:1(flex-grow为1);可自动填满

实现二、 利用Grid布局

  • 父盒子设置display:grid;width:100%
  • 父盒子设置grid-template-columns:左定宽 auto 右定宽

Grid布局 —— 网格布局

一、几个基本容器属性:

  • display:grid 或 display: inline-grid : 创建一个Grid容器
  • grid-template-columns 和 gird-template-rows :在Grid容器中声明有几个列项目和有几个行项目。行项目与列项目的交集处会产生单元格
  • grid-row-gap 和 grid-column-grid 和 grid-gap :设置行间距、列间距和间距(row and column)。

基本使用:

宽度均为200px的三列、高度均为50px的两行、行间距与列间距均为5px

.wrapper
	display:grid;
	grid-template-columns: 200px 200px 200px;
	grid-template-rows: 50px 50px;
	grid-gap:5px;

二、几个关键字:

  • repeat()函数 : 用于创建相同的行或列。
  • auto-fill : 自动填充,让水平方向或竖直方向尽可能容纳更多的列项目或行项目。简单来说就是尽可能创建多一些行项目或列项目。
  • auto:让浏览器决定长度 (自适应,自动填充)
  • fr:表示宽度或高度的比例关系
grid-template-columns:repeat(3,200px);
// 在网格容器内重复创建3个宽度为200px的列项目
grid-template-columns:repeat(auto-fill,200px);
// 在网格容器内尽可能创建多个宽度为200px的列项目
grid-template-columns:200px auto 200px;
// 左列项目和右列项目均为定宽200px。中间列项目则由浏览器决定,可做到自适应,自动填充,即用于自适应三栏布局。
grid-template-columns:200px 1fr 3fr;
// 在网格容器内创建三个列项目。第一列为200px,第二列占剩下宽度的1/4,第三列则占剩余宽度的3/4。

三、设置单元格内的内容的位置:justify-items, align-items, place-items

  • justify-items设置的是单元格的内容的水平位置
  • align-items设置的是单元格的内容的垂直位置
  • 取值都是:start | end | center | stretch (对应的是单元格起始边缘、单元格的结束边缘、单元格内居中、拉伸占满整个单元格)
  • place-items: align-items jusitfy-items

四、整个内容区域在Grid容器的位置:justify-content, align-content, place-content

.container 
  justify-content: start | end | center | stretch | space-around | space-between | space-evenly;
  align-content: start | end | center | stretch | space-around | space-between | space-evenly;  

  • justify-content:center,则让整个内容区域在水平方向上处于Grid容器的中间;
  • justify-content:space-between,则让列项目两边对齐,间隔相等

——————————————————————
项目属性:

指定项目的位置:grid-column和grid-row

  • grid-column-start 指定项目的左边框处于哪条垂直网格线
  • grid-column-end 指定项目的右边框处于哪条垂直网格线
  • grid-row-start 指定项目的上边框处于哪条水平网格线
  • grid-row-end 指定项目的下边框处于哪条水平网格线
.item-1 
  grid-column-start: 2;
  grid-column-end: 4;

则1号项目的左边框压住第二条网格线,右边框压住第四条网格线。

Flex布局 —— 弹性布局

基本概念

  • display:flex 或 display:inline-flex 创建一个Flex容器
  • Flex容器内部的成员,叫项目 item
  • Flex容器有两根轴:水平的主轴和竖直的交叉轴
  • 主轴开始和结束的地方分别叫main start 和 main end;交叉轴开始和结束的地方分别叫 cross start 和 cross end
  • 项目在主轴方向上占据叫主轴空间main size;项目在交叉轴方向上占据的叫交叉轴空间cross size

作用于整个flex容器 —— 容器属性:

  • flex-direction: row | row-reverse | column | column-reverse (决定了主轴的方向,实际上也是决定项目在Flex容器的排布方向)
  • flex-wrap: nowrap(default) | wrap | wrap-reverse (默认不换行,换行且第一行在上方,换行但第一行在下方)
  • flex-flow: flex-direction | flex-wrap
  • justify-content: flex-start(default) | flex-end | center | space-between | space-around (定义项目在主轴上的对齐方式:左对齐、右对齐、居中、两端对齐且间距相等、每个项目的两边距离)。默认是左对齐
  • align-items:flex-start | flex-end | center | baseline | stretch(default) (定义项目在交叉轴上的对齐方式:交叉轴的起点、交叉轴的终点、交叉轴的中点、项目第一行文字基线对齐、拉伸占满整个容器的高)。默认是拉伸占满

作用于容器内的项目 —— 项目属性

  • order 定义flex容器内项目的排列顺序,数字越小,排得越靠前
  • flex-grow 定义项目的放大比例(若有空闲的空间),默认为0
  • flex-shrink 定义项目的缩小比例(若空间不足),默认为1
  • flex-basis 在分配多余的空间之前,用于定义该项目所占据的主轴空间main size,默认值为auto,即项目本身的大小。根据此属性,可以判断是否有多余的主轴空间。
  • flex :flex-grow flex-shrink flex-basis
  • align-self 允许项目拥有自己独特的对齐方式。可以取六个值:auto(default 继承父元素的align-items) | flex-start | flex-end | center | baseline | stretch

margin外边距叠加

官方对此现象的描述:

两个或多个毗邻的普通流的块元素的垂直方向上的margin会叠加

”两个或多个毗邻“修饰的并不是块元素,而是margin,也就是单个块元素的两条margin若是毗邻,满足条件也会叠加,没有限制非得是两个块级元素。

发生叠加的两个或多个margin外边距应该满足以下四个条件:

  • 处于普通流的
  • 属于块元素
  • 是垂直方向上的
  • 得是相邻的

margin外边距发生叠加的三种情况:

  • ① 垂直方向上,相邻的margin-top与margin-bottom会发生叠加(注意:相邻指的并非相邻兄弟元素,而是相邻的margin-top和margin-bottom,是两个外边距挨在一块!
  • ② 当元素之间有包含关系时,外层的margin-top与内层的margin-top会发生叠加
  • ③ 当是空元素时,其margin-top和margin-bottom会发生叠加;或者遇到另外一个元素的margin,先把自己的margin叠加合并,再与另一元素的margin叠加

外边距叠加的计算规则:

  • 如果二者都是正值,则取最大值
  • 如果二者一正一负,则将负值取绝对值,再用正值减去最大值
  • 如果二者都是负值,则全取绝对值,再用 0 减去最大值

外边距叠加发生的解决(破坏上述四点原因):

  • 不再处于普通流(设置float不为none,设置position为absolute,使元素脱离标准流)
  • 不是块元素
  • 不是垂直方向上永远不会叠加
  • 不让margin之间直接相邻(设置一些border、padding或者其它内容使其分隔开)

BFC

概述:

  • BFC 英文是 block formatting context,翻译作块级格式化上下文;
  • BFC 是一个仅有块级盒子参与独立渲染区域
  • BFC 规定了其参与元素在此独立渲染区域内的布局规则
  • BFC 是一个独立渲染区域,不影响外界

可以通过一定的条件触发,从而创建BFC

  • 根元素
  • float不为none
  • overflow不为visible
  • position不为static,relative
  • display为 inline-block,flex,inline-flex,table-caption,table-cell

BFC的特点:

  • ① 在一个BFC内,内部元素会在垂直方向上由上而下一个个排列;
  • ② 在一个BFC内,垂直方向上,相邻的外边距margin会发生叠加;
  • ③ 计算BFC的高度,浮动元素也会参与计算;
  • ④ 在一个BFC内,所有元素(包括浮动元素)的左外边界(margin-left)都会紧挨着容器的左边(border-left);
  • ⑤ 在一个BFC内,若内部有元素是新的BFC,也有内部元素为浮动元素,该新的BFC不会与浮动元素重叠

BFC的用途:

  • 消除相邻外边距叠加 —— 可以再创建BFC,使得两个相邻外边距不属于同一个BFC,则不会发生叠加现象;另外也可适当添加padding或border,使得二者外边距隔开从而非相邻。
  • 清除浮动带来的影响 —— 若子元素是浮动元素,父元素又不便于设置高度时,会发生高度塌陷的情况。若是使其都在一个BFC内(给父元素设置overflow:hidden),则计算BFC高度时,浮动元素也会参与计算。则不会发生坍塌。
  • 创建自适应两列布局 —— 左盒子定宽且浮动,右盒子设置overflow:hidden创建BFC。若右盒子不创建BFC,二者都会符合第四条规则紧挨着容器的左边框;当右盒子创建了BFC,则符合第五条规则,新的BFC不与浮动元素重叠。

层叠上下文与层叠级别

层叠上下文、层叠级别

元素水平居中 / 垂直居中的方法

水平居中 / 待处理元素是行内元素:

  • 若父元素为块级元素,则为父元素设置 “text-align:center”
  • 若父元素非块级元素,则为父元素设置 “display:block;text-align:center”

水平居中 / 待处理元素是块级元素:

  • 若待处理元素定宽,则为其设置 “margin: 0 auto”

  • 若待处理元素不定宽,则为其设置 “display: inline-block 或 display: inline”。父元素再设置 “text-align:center”

     现在换个思路,子绝父相,使用position
    
  • 若待处理元素(子元素)定宽,设置子元素"left:50%“,再设置"transform:translateX(-50%)” 或 “margin-left: - 子元素宽度的一半”

  • 若待处理元素(子元素)不定宽,设置子元素"left:50%“,再设置"transform:translateX(-50%)”

     再可以试试flex
    
  • 父元素设置 display:flex 和 justify-content:center

垂直居中 / 待处理元素为行内元素:

  • 若待处理元素为单行行内元素,则设置子元素行高与父元素高度相同即可。即 line-height:height

  • 若待处理元素为多行行内元素,父元素设置"vertical-align:middle"

     	子绝父相也可以处理垂直居中
    
  • 设置好position。若待处理子元素是定高度,则可设置 top:50%,再设置transform:translateY(-50%) 或 margin-top: - 子元素高度的一半

  • 设置好position。若待处理子元素不定高度,可以设置 top:50%,再设置transform:translateY(-50%)

     	也可以用flex
    
  • 父元素设置display:flex,再设置 align-items:center

深入了解vertical-align

深入了解line-height

CSS3新增特性

一、新增简单过渡transition

transition: property duration timing-function delay

  • property:设置过渡效果CSS属性名称
  • duration:设置完成过渡效果需要多久
  • timing-function:指定速度曲线
  • delay:指定过渡开始的延迟时间

二、新增复杂动画animation

animation: name duration timing-function delay iteration-count direction

  • name:规定绑定到选择器的Keyframe名称
  • duration:设置动画完成的时间
  • timing-function:指定速度曲线
  • delay:指定动画开始的延迟时间
  • iteration-count:规定动画播放次数
  • direction:规定是否应该轮流反向播放动画

三、新增元素转换transform

旋转:

  • transform:rotate(90deg);
  • transform:rotateX(90deg);
  • transform:rotateY(90deg);
  • transform:rotateZ(90deg);
  • transform:rotate3d(x,y,z,angle)

倾斜:

  • transform:skewX(10deg)
  • transform:skewY(10deg)

缩放:

  • transform:scaleX(0.5)
  • transform:scaleY(0,5)

平移:

  • transform:translateX(-50%)
  • transform:translateY(-50%)

四、新增阴影倒影

  • box-shadow
  • box-reflect
  • text-shadow

五、新增边框radius

  • border-radius

六、新增颜色

  • RGBA ( Red Green Blue Alpha )
  • HLSA ( 色度 饱和度 亮度 Alpha)

flex弹性布局、grid栅格布局也是新增的

transition和animation的区别

  • transition是简单过渡,只有开始和结束两帧;animation是复杂动画,可通过keyframes绘制每一帧
  • transition需要hover或js事件触发;animation可以自主播放
  • transition只能发生一次;animation可以通过设置iteration-count来设定播放次数
@keyframes animat

	0%   background:red;
	25%  background:yellow;
	50%  background:blue;
	100% background:green;

重排reflow与重绘repaint

概述:

  • 回流 / 重排 :当Rendering Tree 中部分元素的尺寸大小、布局、隐藏等属性改变时,浏览器的布局需要调整,则需要重新渲染DOM。这个过程就叫回流。回流也叫重排(对整个页面进行重新排版)。
  • 重绘 : 当元素属性的改变不影响DOM Tree的结构,即不会影响浏览器的布局,只是“表象”发生变化(如background-color,visibility等),那么针对新样式对元素进行重新绘制。
  • 回流一定会引起重绘,重绘不一定引起回流
  • 回流需要重新计算、渲染DOM,处理Rendering Tree,其开销比重绘要大

何时发生 回流 / 重排

  • 与DOM元素有关:添加或删除可见元素、元素位置发生变化、元素尺寸大小发生变化
  • 访问特定属性:offsetTop/offsetLeft/offsetWidth/offsetHeight、scrollTop/scrollLeft/scrollWidth/scrollHeight、clientTop/clientLeft/clientWidth/clientHeight
  • 调用特定方法:getComputedStyle()、getBoundingClientRect()、currentStyle()
  • 发生特定事件:页面初始化渲染、浏览器窗口尺寸改变resize事件

如何减少

  • 统一批量修改样式,避免逐次修改
  • 使DOM脱离文档流
  • 缓存布局属性
  • position脱离文档流
  • CSS3硬件加速

具体参考:回流与重绘以及减少的方案

响应式设计

响应式网站设计的概述:

  • 页面的设计和开发应当根据用户行为及设备环境(系统平台、屏幕尺寸、屏幕定向等)进行相应的响应和调整。
  • 能同时适配PC、平板以及手机

页面头部meta声明viewport,以支持移动端:

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no”>
  • width=device-width —— 自适应手机屏幕尺寸宽度
  • initial-scale=1 —— 缩放的初始比例
  • maximun-scale=1 —— 缩放比例的最大值
  • user-scalable=no —— 禁用缩放

实现响应式布局的四个途径:

  • 媒体查询
  • rem
  • vh/vw
  • %

一、媒体查询

根据不同的媒体类型条件,从而匹配相应条件下的样式
匹配视口宽度大于375px小于600px的媒体,如下:

@media screen (min-width: 375px) and (max-width: 600px) 
  body 
    font-size: 18px;
  

二、rem

rem 是 root em,即相对于根元素html的font-size字体属性计算出大小,默认情况下浏览器的font-size为16px,即1rem=16px;

可以配合Media查询,在不同媒体类型条件下设置不同的html font-size,rem则可以因此根据不同的font-size作出调整

三、百分比单位

  • 子元素的top/left和bottom/right若设置百分比,则相对于最近一个非Static父元素的高度和宽度
  • 子元素的padding和margin若设置百分比,都是相对于父元素的width
  • 子元素的border-radius若设置百分比,是相对于自身width计算

优点:

  • 灵活、便捷地解决不同设备的显示问题

缺点:

  • 某种程度上来说,效率偏低
  • 代码累赘,针对某种类型都得编写相应的样式代码

CSS的性能优化

CSS的性能优化可以从以下几个方面考虑:

一、CSS的渲染

① 内联首屏关键CSS

  • 页面首要关键内容呈现给用户的时间直接影响用户的体验
  • 内联关键CSS,可以使html文档下载解析完成后,立刻渲染
  • 若CSS加载解析时间较长(放在文档尾部或是引用外部CSS文件),有可能引起白屏或FOUS的不良问题

② 慎用高性能属性如:浮动、定位、box-shadow、box-radius
③ 减少页面的重排、重绘
④ 考虑使用雪碧图

二、CSS的加载

CSS的加载会阻塞对文档的解析。

① 利用媒体查询 media

  • 设置link标签media属性为一个当前浏览器所不支持的值。浏览器会认为该资源的优先级较低,会在不阻塞页面解析渲染的情况下加载这份资源。
  • 设置link标签的onload,使得加载完后改变media值变回all,从而开始解析
<link rel="stylesheet" href="mystyles.css" media="nonono" onload="this.media='all'">

② 提前加载资源 preload

  • 使得资源的优先级最高,异步且最先加载
  • 等需要时,浏览器直接从缓存中获取
  • rel设置为preload
  • 设置onload,使得加载完后改变rel值变回stylesheet
<link rel="preload" href="./index.css" onload="this.rel='stylesheet'">

③ 设置rel为可选样式表

  • 通过rel设置为 alternate stylesheet,标记资源为可选样式表
  • 设置onload,使得加载完后改变rel值变回stylesheet
<link rel="alternate stylesheet" href="mystyles.css" onload="this.rel='stylesheet'">

④ 使用link而不是@import

三、关于CSS选择器的使用

主要是避免冗杂无用的遍历匹配避免重复书写CSS代码

减少冗杂无用的遍历

  • 避免使用通配符选择器,计算次数太多
  • 如果规则中有ID选择器作为关键选择器,没有必要再添加规则
  • 能用class选择器就不要通过标签选择器去匹配
  • 尽量不要用后代/子代选择器。因为样式系统会遍历所有的后代/子代元素,再去判断后续规则是否满足。
  • 尽量降低选择器深度,免得层层遍历(就像写太多的for循环),最高不要超过3层

避免重复书写

  • 应当了解哪些属性是可以通过继承得到的,避免重复书写相同的规则。

四、压缩

  • webpack、gulp/grunt等工具进行资源压缩

单行或多行文本溢出省略样式

若是单行文本

  • white-space : nowrap 设置文本不换行
  • overflow:hidden 隐藏溢出的元素
  • text-overflow: ellipsis 文本溢出时显示 ‘…’省略标记;若为clip则是裁剪掉溢出部分

若是多行文本,可以基于高度或基于行数:

基于高度进行截断:

.text 
   position: relative;
   line-height: 20px;
   height: 40px;
   overflow: hidden;

.text::after 
   content: "...";
   position: absolute;

常见动画(CSS3)

一、transition : property duration timing-function delay

  • property 设置过渡效果CSS属性名称
  • duration 设置完成过渡效果需要多久
  • timing-function 指定速度曲线
  • delay 指定过渡开始的延迟时间

二、animation : name duration timng-function delay iteration-count direction

  • name 规定绑定到选择器的Keyframe名称
  • duration 设置动画完成的时间
  • timing-function 指定速度曲线
  • delay 指定动画开始的延迟时间
  • iteration-count 规定动画播放次数
  • direction 规定是否应该轮流反向播放动画

三、transform

旋转

  • transform:rotate(90deg);
  • transform:rotateX(90deg);
  • transform:rotateY(90deg);
  • transform:rotateZ(90deg);
  • transform:rotate3d(x,y,z,angle);

倾斜

  • transform:skewX(10deg)
  • transform:skewY(10deg)

缩放

  • transform:scaleX(0.5)
  • transform:scaleY(0,5)

平移

  • transform:translateX(-50%)
  • transform:translateY(-50%)

非CSS部分:
四、Canvas
五、Gif
六、原生JS

link和@import

  • 二者都是引入外部CSS的方法:link是链接法,@import是导入法
  • link是html元素,无兼容性问题;@import是CSS提供,IE5才能识别
  • 使用link,是一边载入页面一边载入样式效果,使用体验良好;使用@import,则是加载完页面才载入样式。
  • link的优先级高于@import。
  • link除了引入CSS文件,还可以引入图标icon等其它信息;而@import只能引入CSS文件。
  • link支持JS去控制DOM改变样式;@import不支持。

setTimeout和setInterval执行动画的缺点

setTimeout与setInterval执行动画的缺点,源于它们自身的特性;

setTimeout超时调用可能会卡顿、掉帧:

  • 超过一定时间后,将待执行任务插入执行队列(宏任务)。当主线程任务执行完毕后,才会执行宏任务队列,所以即使超过一定时间,待执行任务也不是立即调用。
  • setTimeout设置的时间间隔不一定与屏幕刷新间隔时间相同

setInterval卡顿掉帧,还可能会浪费CPU资源

  • setInterval设置的间隔调用,若不通过clearInterval取消定时器。它将不断地执行直至页面卸载。若页面处于不可见的状态,setInterval仍继续执行动画任务,此时刷新动画完全是浪费CPU资源
  • 若定时器待执行的函数func()需要执行的时间长于间隔时间t,如长到第二次触发定时器时,第一次func()还没有执行完。那么第二次func()就只能进入任务队列等待调度。这样函数的执行间隔时间就不是t了。
  • 若第一个func()执行时间特别长,长到后续触发了第二个、第三个func(),都还没有处理完。那么会导致第三个func()及以后的函数被忽略。因为任务队列里不能同时有两个及以上同一个定时器的回调函数。

requestAnimationFrame 请求动画帧

HTML5提供requestAnimationFrame(请求动画帧),专用于请求动画

window.requestAnimationFrame(callback)

  • 希望执行一个动画,并且在下一次重绘之前调用指定的回调函数callback更新动画
  • callback属于宏任务

优点:

  • CPU节能:页面处理是未激活状态时,该页面的屏幕刷新任务也会被系统暂停,跟着系统走的requestAnimationFrame也会停止渲染;当页面处理重新激活,动画会从上次停留的地方继续。()
  • 函数节流:requestAnimationFrame可以保证每个刷新间隔内,函数只执行一次。一个刷新间隔内函数执行多次是没有意义的,多次绘制也不会显示出来
  • 合并DOM:在每次重绘或重排中集中每一帧的所有DOM

inline与inline-block之间的空白间隙

  • 当元素为inline或inline-block时,元素之间的空白字符会被浏览器处理,即代码中的回车换行转换成一个空白字符。
  • 若font-size不为0,空白字符也就占据了一定的宽度,则出现了空白间隙

解决:

  • 代码写在同一行,不人为留下换行回车。缺点:可读性差、稳定性差(一旦修改代码排版,效果就消失)
  • 父元素设置font-size:0,子元素重新设定font-size。缺点:增加代码量
  • 最优:父元素设置display:table和word-spacing

替换元素

典型的替换元素有:

  • iframe
  • img
  • video
  • embed

CSSSprites

CSSSprites 精灵图 :将很多小图片合并到一张较大的图片,利用CSS的background-image插入,再用background-repeat、background-position进行定位等。

这样只需要加载一张大的图片,而不是一次一次请求加载小的图片

优点:

  • 有效减少网页的http请求,从而提高了性能
  • 减少图片的字节:三张图片合成一张图片的字节总量小于三张图片的字节总和

缺点:

  • CSS精灵图的制作比较麻烦,需要借助Photoshop等工具来对每个小图片做精准测量
  • CSS精灵图的维护比较麻烦,若页面背景有变动,则需要相应修改精灵图,甚至还要调整CSS样式

物理像素、逻辑像素和像素密度

物理像素: 设备屏幕实际拥有的像素点。如iPhone 6的屏幕在宽度方向有750个像素点,高度方向有1334个像素点,所以iPhone 6 总共有750*1334个物理像素。

逻辑像素: 也叫“设备独立像素”(Device Independent Pixel, DIP),可以理解为反映在CSS/JS代码里的像素点数。

像素比例: 也称设备像素比,它等于 物理像素/逻辑像素;

当像素比例越高,说明一个逻辑像素里容纳了更多的物理像素。换句话说,像素比例越高,是用更多的物理像素来渲染一个逻辑像素。

像素比例越高的结果是:更加精细

为什么移动端开发需要@2x或@3x的图片

至少要让一个位图像素对应着一个物理像素,才不会显示失真

一张图片如果是375*200 = 75000个位图像素;

如果是2倍屏,那么像素比例是2(设备像素比是2),1个逻辑像素=2个物理像素,也就是需要2个物理像素来渲染一个逻辑像素

那么就需要准备75000*2 = 150000 位图像素的图片,才能保证一个位图像素对应着一个物理像素,才能在2倍屏上正常显示。

否则本需要15000物理像素显示的图片,却只有75000像素,那么当然会失真,模糊了。

sass、less

  • sass和less都是CSS的预处理器
  • 增加了一些编程特性,如:变量、混合、嵌套、函数、作用域等常用功能,无需考虑浏览器的兼容问题

好处:

  • 关于编写:提高代码复用性,简化编写,提高效率
  • 关于维护:可读性强、更加简洁、方便维护

变量

@width: 10px;
@height: @width + 10px;

#header 
  width: @width;
  height: @height;

混合Mixins(将一部分样式一起抽出,作为单独的模块,可供其它选择器重复使用,也可接受参数)

.bordered 
  border-top: dotted 1px black;
  border-bottom: solid 2px black;


#menu a 
  color: #111;
  .bordered();


.post a 
  color: red;
  .bordered();

预处理器、后处理器

预处理器:

  • 常见的有less、sass、stylus
  • 增加了一些编程特性,如:变量、混合、嵌套、函数、作用域等常用功能,无需考虑浏览器的兼容问题

好处:

  • 关于编写:提高代码复用性,简化编写,提高效率
  • 关于维护:可读性强、更加简洁、方便维护

后处理器

以上是关于CSS / CSS3的主要内容,如果未能解决你的问题,请参考以下文章

前端面试大汇总 —— CSS / CSS3 篇

[CSS3] 学习笔记--CSS盒子模型

css3伸缩盒子强制换行

CSS中的外边距合并问题

盒子模型以及css3指定盒子模型种类的box-sizing

css中margin-top的两个问题