CSS3新特性(布局、图片、文字、颜色、动画)

  • 选择器:nth-child(n)、nth-of-type(n)(伪类选择器,结构伪类)、attribute^=value(属性选择器)、

  • 边框border:border-radius、box-shadow、border-image

  • 背景: background-clip(用于确定背景画区: border-box(背景从border开始显示))、background-origin(用于确定背景图片的左上角对齐方式:border-box从border开始计算background-position)、background-size调整背景图片的大小、background-break(元素可以被分成几个盒子,此属性用于控制背景在这些不同盒子中的显示。continuous:忽略盒之间的距离;)

  • 颜色渐变:线性渐变background-image: linear-gradient(direction, color-stop1, color-stop2, …);径向渐变radial-gradient

  • 文本效果:word-wrap(换行)、text-overflow(文本超过容器边界的显示效果:clip裁剪文本、:ellipsis省略号代表)

  • 字体@font-face规则

  • transform转换

  • 过渡:transition属性可以被指定为一个或多个CSS属性的过渡效果,多个属性之间用逗号进行分隔,必须指定过渡效果和持续时间。

    1
    transition: CSS属性,花费时间,效果曲线(默认ease),延迟时间(默认0)
  • 动画:@keyframes规则、animation属性

  • 多列

  • 盒模型

  • 布局:flex、grid

  • 多媒体查询(@media)

  • 颜色表示方式:rgba、hsla(h为色相、s为饱和度、l为亮度、a为透明度)

  • currentColor:是color属性的值。具体意思是指:currentColor关键字的使用值是color属性值的计算值。如果currentColor关键字被应用在color属性自身,则相当于是color:inherit。

CSS三大特性–优先级、层叠级、继承级

导入方式
  • 外联(外部样式表):通过link标签引入外部CSS
  • 内联(内嵌样式表):在head标签中使用style标签
  • 嵌入(行内样式表):在标签中使用style属性
隐藏页面元素的方式及区别
  • display: none指元素完全不陈列出来,不占据空间,涉及到DOM结构,故产生重绘和重排。
  • visibility:hidden指元素不可见但存在,保留空间,不影响结构,故只产生重绘。若元素绑定了事件,则不可以触发绑定的事件。
  • opacity: 0指元素不可见但存在,保留空间,不影响结构。若元素绑定了事件,可以触发事件。
  • height、width设置为0。如果元素内有子元素或内容,还应该设置其overflow:hidden来隐藏其子元素。特点:元素不可见,不占据页面空间,无法响应点击事件。
重绘(repaint)与重排(reflow,也叫回流)的例子
  • font-size改变会产生重排
  • 当HTML标签使用fixed或absolute的position时,修改它们的CSS不会回流的,因为它们已经脱流了。
最小化重绘和重排
  • 批量修改元素样式 elem.className 和 ele.style.cssText 代替 elem.style.xxx
  • 尽量使用 CSS 属性简写:比如 border、 font、 background等
  • 避免使用 CSS 表达式(expression),因为每次调用都会重新计算值(包括加载页面)
  • 尽量避免用 table 布局(table 元素一旦触发回流就会导致 table 里的所有其他元素回流)
  • 需要对元素进行复杂操作时,可以先隐藏(display:none),操作完成后再显示
  • 需要创造多个 DOM 节点时,使用 DocumentFramgment 创建完后一次性加入 document 缓存 Layout属性值,如:let left = elem.offsetLeft ; 这样多次使用 left 只产生一次回流。
属性继承
  • 默认情况下,能被继承的一般都是文本属性。
  • 不可继承:display margin border padding height width background position
CSS层叠样式表的权重值
  • style: 1000

  • #ID: 100

  • .class: 10

  • element: 1

  • 内联样式>ID选择器>class选择器=伪类选择器=属性选择器(后面的样式会覆盖前面的样式)>标签选择器>通配符选择器>浏览器自定义样式

选择器

基础选择器

1
2
3
4
- 标签选择器:h1
- 类选择题:.class
- ID选择题:#id
- 通配选择器:*

属性选择器

1
2
3
4
5
6
7
8
9
-[attr]: 指定属性的元素
-[attr=val]: 属性等于指定值的元素
-[attr*=val]: 属性包含指定值(可以不是完整单词)的元素
-[attr^=val]: 属性以指定值开头的元素
-[attr$=val]: 属性以指定值结尾的元素
-[attr~=val]: 属性包含指定值(完整单词)的元素
-[attr|=val]: 属性以指定值开头的元素(完整单词)

例子:p[id^="one"]{}

组合选择器

1
2
3
4
-相邻兄弟选择器:A+B
-通用兄弟选择器:A~B(寻找A后所有符合条件的兄弟元素)
-直系后代选择器:A>B
-后代选择器:A B

伪类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
1 条件伪类
-:lang(): 基于元素语言来匹配页面元素
-:dir(): 匹配特定文字书写方向的元素
-:has(): 匹配包含指定元素的元素
-:is(): 匹配指定选择器列表里的元素
-:not(): 用来匹配不符合一组选择器的元素

例子:p:lang(en) //匹配语言为”en”的<p>
2 行为伪类
-:active: 鼠标激活元素
-:hover: 鼠标悬浮元素
-::selection: 鼠标选中的元素
3 状态伪类
-:target: 当前锚点的元素
-:visited: 已访问的链接元素
-:disabled: 事件禁用的表单元素

4 结构伪类
-:root: 文档的根元素
-a:first-child: 选择不管是什么标签下的,只要第一个子元素是a元素
-a:nth-child(n): 选择不管是什么标签下的,只要第n个子元素是a元素
-a:nth-child(-n+4):选取小于等于4的标签
-a:nth-last-child(n):倒数第n个元素
-a:first-of-type:不管是什么标签下的,只要第一个出现的a元素
-a:nth-of-type(n):不管是什么标签下的,只要第n个出现的a元素
-a:only-child:匹配属于其父元素的唯一子元素的每个元素

伪元素

1
2
-::before: 在元素前插入内容
-::after: 在元素后插入内容

外边距塌陷问题

1
2
3
4
5
6
7
8
9
10
表现:
- 当两个标准流中相邻(兄弟或父子关系)的块级元素的外边距,组合在一起变成单个外边距,但只有上下外边距会发生塌陷。
计算方式:
- 两个块margin都为正,则取较大的一个
- 两个块margin都为负,则取绝对值较大的那个
- 一正一负,则取两个块margin之和
举例:求下面两个div元素的垂直边距
<div style="width:100px;height:100px;margin-bottom:100px"></div>
<div style="width:100px;height:100px;margin-top:200px"></div>
200px
inline-block与inline的区别
  • inline-block可以设置高度,inline不可以设置高度
  • block会独占一行,但inline-block不会
  • inline-block兼备了块元素和行元素的性质,所以padding和margin在inline-block上都有作用。而inline只能使用padding、margin-left和margin-right
relative与absolute
  • 当元素的position属性设置为relative时,设置的top、right、bottom、left偏移值是相对于其自身
  • 当元素的position属性设置为absolute时,设置的top、right、bottom、left偏移值是相对于其上一级有定位的祖先元素的。不占据空间
  • 当元素的position属性设置为fixed时,设置的top、right、bottom、left偏移值是相对于viewport(视窗)的。即使窗口滚动它也不会移动。不在标准流中占据位置
  • 当元素的position属性设置为static时,表示保留在原本应该在的位置,不会重新定位。top、left、right、bottom属性失效。static为position属性的默认值。
  • 网页中,rem作为元素尺寸单位时,是相对文档根节点的font-size进行计算的
属性
  • border的规范写法为:border-width、border-style、border-color

  • position可以设置的值:absolute、fixed、relative、static、inherit

display
  • display:block。将元素显示为块级元素,一般是其他元素的容器,可容纳内联元素和其他块级元素。块级元素排斥其他元素,自成一行,宽度高度起作用。常见为div和p.
  • display:inline。将元素显示为内联元素,内联元素只能容纳文本或者其他内联元素。可以与其他内联元素位于同一行,宽度高度不起作用。常见为a。
  • display:inline-block。将元素显示为内联元素,但对象内容作为块对象呈递。也就是周围元素能保持在同一行,宽度和高度均起作用。
overflow(规定内容溢出时发生的事情)
  • overflow:scroll。必出现滚动条.
  • overflow:auto。当子元素大于父元素时会出现滚动条。
  • overflow:visible。溢出的内容出现在父元素之外。
  • overflow:hidden。溢出隐藏。
outline轮廓(用于绘制元素周围的一条线)
  • 位于边框边缘的外围,可起到突出元素的作用
  • 可以设置元素轮廓的颜色和宽度
  • 与border属性类似,但是outline不占据空间
CSS标准单位
  • px
  • em
  • rem:根据页面的根节点的字体大小进行转变
CSS预编译工具
  • Sass
  • Less
  • Stylus

BFC(块级格式上下文)

概念
  • 是一个隔离的容器,容器里的子元素不会影响外面的元素
创建BFC的方式
  • display: inline-block | table-cell | table-caption | flex | inline-flex
  • float: left | right
  • position: absolute | fixed
  • overflow: hidden
特性
  • BFC的区域与float的元素区域不会产生重叠
  • 计算BFC高度时,浮动子元素也会参与计算
  • 只要元素可以触发BFC,就无须使用clear:both来清除浮动的影响

令child垂直居中

<parent><child>content</child></parent>

1
2
3
4
5
6
7
8
9
10
<style>
parent{
display: table;
}
child{
display: table-cell;
vertical-align: middle;
}
</style>
<!-- 把parent变成table,再把子元素变成table-cell,而vertical-algn属性可以设置元素垂直对齐。但这种方法只能应用于内联元素以及display值为table-cell的元素 -->
1
2
3
4
5
6
7
<style>
parent{
display: flex;
align-items: center;
}
</style>
<!-- 弹性布局。align-items: center为设置子元素在侧轴方向向上居中对齐,弹性布局默认主轴方向为row(从左到右),侧轴方向为column(从上到下) -->
1
2
3
4
5
6
7
8
9
10
11
<style>
parent{
position: relative;
}
child{
position: absolute;
top: 50%;/*把元素的上边缘设置在其包含元素上边缘之下50%高的位置*/
transform: translateY(-50%);
}
</style>
<!-- 定位。父元素相对定位,子元素绝对定位。子元素的top值设置为50%,即父元素高度的50%。此时child元素的左上角移动到了parent元素的(0, parent高度的50%),而不是child元素的中心点移动到了parent元素的垂直方向的中心。因为child需要往上移动自身高度的50%,即transform: translateY(-50%). -->

CSS百分比参照

  • 参照父元素宽度的元素:padding、margin、width、text-indent
  • 参照父元素高度的元素:height
  • 参照父元素属性:font-size、line-height
  • 相对定位的时候,top(bottom)、left(right)参照的是父元素的内容区域的高度与宽度;而绝对定位的时候,参照的是最近的定位元素包括padding的高度与宽度

父元素高度塌陷

子元素都为浮动时的解决方案
  • 给父元素添加overflow:hidden
  • 在浮动元素下方添加空div,并添加样式clear:both;(clear:both;属性定义了元素的哪边的上方不允许出现浮动元素).clear属性指明该元素周围不可出现浮动元素。
  • 设置父元素 :after{content:’’;clear:both;display:block;overflow:hidden;}
浮动元素
  • 如果有多个浮动元素,浮动元素会按顺序排下来而不会发生重叠的现象
  • 浮动元素会尽可能地向顶端对齐、向左或向右对齐
  • 行内元素与浮动元素发生重叠,边框、背景、内容都会显示在浮动元素之上
  • 块级元素与浮动元素发生重叠,边框、背景会显示在浮动元素之下,内容会显示在浮动元素之上

屏幕适配

屏幕大小
  • 超小屏幕:col-xs(<768像素)
  • 小屏幕:col-sm(>=768像素)
  • 中等屏幕:col-md(>=992像素)
  • 大屏幕:col-lg(>1200像素)
background-position
  • 该属性可以有两个取值,第一个取值为背景图像与其容器在水平方向上的距离,第二个取值为背景图像与其容器在垂直方向上的距离
  • 若只有一个取值,则第二个取值默认为50%
  • 若取值用百分数表示,则表示此背景图像离其容器左边的距离为x=(对象的宽度-图像的宽度)*x%; 离其容器上边的距离为y=(对象的高度-图像的高度)*y%.

动画

Animation-timing-function
  • linear规定以相同速度开始至结束的过渡效果
  • ease规定慢速开始,然后变快,然后慢速结束的过渡效果。这是默认效果。
  • ease-in规定以慢速开始的过渡效果
  • ease-out规定以慢速结束的过渡效果
  • ease-in-out规定以慢速开始和结束的过渡效果

优化CSS图片加载

  • CSSSprite:允许将一个页面涉及到的零星图片都包含到一张大图中,当访问页面时,载入的图片不会像之前那样一幅一幅地慢慢显示出来。能降低网页的HTTP请求,从而大大提高页面的性能。
  • SVG sprite:与CSS sprite类似,只是属于另外一种实现思路<symbol>+<use>。其中,<symbol>用于定义可复用的形状,定义的形状不会展示出来,而是通过<use>元素引用来显示。
  • icon font:图标字体,就是字体做的图标。能自由变化大小,且不会模糊。比图片小,加载快,可以任意修改颜色。
  • base64:可以将图片编码成一串字符串,使用该字符串代替图像地址,能有效减少HTTP请求次数。

伪类和伪元素

  1. 特性与区别
  • 伪类本质上是为了弥补常规CSS选择器的不足,以便获取到更多信息
  • 伪元素本质上是为了创建一个有内容的虚拟容器
  • CSS3中伪类和伪元素的语法不同,伪类:link:hover, 伪元素::before::after
  • 可以同时使用多个伪类,但只能同时使用一个伪元素。伪类类似于添加类所以可以是多个,而伪元素在一个选择器中只能出现一次,而且只能出现在末尾。
  • 伪类和伪元素的根本区别在于是否创建了新的元素。伪元素/伪对象不存在DOM文档中,是虚拟的元素,是创建的新元素。这个新元素是某个元素的子元素,这个子元素虽然在逻辑上存在,但却并不实际存在于文档树中。伪类存在于DOM文档中(无标签,找不到,只有符合触发条件时才能看到),逻辑上存在但在文档树中却无需标识。
  1. 例:当鼠标移到span上时,span前插入”duang”
1
2
3
4
5
6
7
8
9
<style>
span{
background: yellow;
}
span:hover::before{
content: "duang";
}
</style>
<span>2222</span>

浏览器私有属性前缀

  • mozilla:-moz
  • webkit:-webkit
  • opera:-o
  • trident:-ms

盒模型

是什么?

​ 当对一个文档进行布局的时候,浏览器的渲染引擎会根据CSS 基础框盒模型,将所有元素表示为一个个矩形的盒子。一个盒子由四个部分组成:contentpaddingbordermargin

分类

标准盒模型(W3C)

  • 盒子总宽度 = width + padding + border + margin;
  • 盒子总高度 = height + padding + border + margin

也就是,width/height 只是内容高度,不包含 paddingborder值。也就是给盒模型设置width和height后,它显示出来的content的width和height就是设置的值。

怪异盒模型(IE)

  • 盒子总宽度 = width + margin;
  • 盒子总高度 = height + margin;

也就是,width/height 包含了 paddingborder

box-sizing

  • CSS 中的 box-sizing 属性定义了引擎应该如何计算一个元素的总宽度和总高度

  • box-sizing: content-box|border-box|inherit

  • content-box 默认值,与标准盒子模型表现一致

  • border-box 与怪异盒子模型表现一致

  • inherit 指定 box-sizing 属性的值,应该从父元素继承

使用场景

​ 如果想让两个盒子的宽度都为50%,有一定的padding,且在同一行,content-box很难达到这个要求。因为一个盒子的宽度+padding会超过50%,另一个盒子就会显示到下一行去。在这个场景中可以使用border-box解决,因为padding 和 content都算在50%内了。

​ 当前流行的CSS框架都采用border-box,因为框架要想具备栅格系统,必须使用border-box。

选择器

常见的选择器

选择器的优先级

属性继承

em/px/rem/vh/vw的区别

  • px:绝对单位,页面按精确像素展示
  • em:相对单位,基准点为父节点字体的大小,如果自身定义了font-size按自身来计算,整个页面内1em不是一个固定的值
  • rem:相对单位,可理解为root em,相对根节点html的字体大小来计算
  • vh、vw:主要用于页面视口(viewport)大小布局

设备像素、CSS像素、设备独立像素、dpr、ppi的区别

  • 无缩放的情况下,一个CSS像素=一个设备独立像素
  • 设备像素由屏幕生产之后就不发生变化,设备独立像素是一个虚拟单位会发生改变
  • PC端,未缩放,1个设备独立像素=1个设备像素
  • 移动端,标准屏,1个设备独立像素=1个设备像素
  • 设备像素比dpr = 设备像素/设备独立像素
  • 每英寸像素ppi,值越大,图像越清晰
1
2
屏幕分辨率:X * Y
PPI = sqrt(X^2+Y^2)/屏幕尺寸

BFC

是什么?

BFC(Block Formatting Context),即块级格式化上下文。BFC目的是形成一个相对于外界完全独立的空间,让内部的子元素不会影响到外部的元素。它是页面中的一块渲染区域,并且有一套属于自己的渲染规则:

  • 内部的盒子会在垂直方向上一个接一个的放置
  • 对于同一个BFC的俩个相邻的盒子的margin会发生重叠,与方向无关
  • 每个元素的左外边距与包含块的左边界相接触(从左到右),即使浮动元素也是如此
  • BFC的区域不会与float的元素区域重叠
  • 计算BFC的高度时,浮动子元素也参与计算
  • BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然

常见触发条件

  • 根元素,即html
  • 浮动元素:float=left || right
  • position=absolute || fixed
  • overflow值不为 visible,为 auto、scroll、hidden
  • display的值为inline-block、inltable-cell、table-caption、table、inline-table、flex、inline-flex、grid、inline-grid

应用场景

  • 防止margin重叠:同一个BFC中两个相邻的盒子的margin会发生重叠,但是如果给其中一个盒子再套上一个BFC时margin就不会发生重叠了。

  • 清除内部浮动:当父元素中子元素均为浮动元素时会产生高度塌陷问题。由于BFC计算高度时会计算浮动元素的高度,故可以给父元素添加overflow:hidden;变成BFC。

  • 自适应多栏布局

两栏布局,右侧自适应

实现思路1:左float,右margin-left

  • 使用 float 左浮左边栏
  • 右边模块使用 margin-left 撑出内容块做内容展示
  • 为父级元素添加BFC,防止下方元素飞到上方内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<style>
.box{
overflow: hidden; /*添加BFC*/
}
.left{
float: left;
width: 200px;
background-color: gray;
height: 400px
}
.right{
margin-left: 210px;
background-color: lightgray;
height: 200px;
}
</style>
<div class="box">
<div class="left">左边</div>
<div class="right">右边</div>
</div>

实现思路2

  • 使用flex布局
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<style>
.box{
display: flex;
}
.left{
width: 100px;
}
.right{
flex: 1;
}
</style>
<div class="box">
<div class="left">左边</div>
<div class="right">右边</div>
</div>

三栏布局,中间自适应

方案:

  • 两边使用 float,中间使用 margin
  • 两边使用 absolute,中间使用 margin
  • 两边使用 float 和负 margin
  • display: table 实现
  • flex实现
  • grid网格布局

两边使用 float,中间使用 margin: 浮动+margin

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<style>
.wrap{
backgound: #eee;
overflow: hidden;
padding: 20px;
height: 200px;
}
.left{
width: 200px;
height: 200px;
float: left;
background: coral;
}
.right{
width: 120px;
height: 200px;
float: right;
background: lightblue;
}
.middle{
margin-left: 220px;
margin-right: 200px;
height: 200px;
background: lightpink;
}
</style>
<div class="wrap">
<div class="left">左侧</div>
<div class="right">右侧</div>
<div class="middle">中间</div>
</div>
  • 需要将中间的内容放在html结构最后,否则右侧会在中间内容的下方

原理:

  • 两边固定宽度,中间宽度自适应。
  • 利用中间元素的margin值控制两边的间距
  • 宽度小于左右部分宽度之和时,右侧部分会被挤下去

这种实现方式存在缺陷:

  • 主体内容是最后加载的。
  • 右边在主体内容之前,如果是响应式设计,不能简单的换行展示

两边使用absolute,中间使用margin: 定位+margin

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<style>
.container{
position: relative;
}
.left,
.right,
.main{
height: 200px;
line-height: 200px;
text-align: center;
}
.left{
position: absolute;
top: 0;
left: 0;
width: 100px;
background: green;
}
.right{
position: absolute;
top: 0;
right: 0;
width: 100px;
background: green;
}
.main{
margin: 0 110px;
background: black;
color: white;
}
</style>
<div class="container">
<div class="left">左边固定宽度</div>
<div class="right">右边固定宽度</div>
<div class="main">中间自适应</div>
</div>
  • 基于绝对定位的三栏布局:注意绝对定位的元素脱离文档流,相对于最近的已经定位的祖先元素进行定位。无需考虑HTML中结构的顺序.

原理:

  • 左右两边使用绝对定位,固定在两侧。
  • 中间占满一行,但通过 margin和左右两边留出10px的间隔

两边使用float和负margin

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<style>
.left,
.right,
.main{
height: 200px;
line-height: 200px;
text-align: center;
}
.main-wrapper{
float: left;
width: 100%;
}
.main{
margin: 0 110px;
background: black;
color: white;
}
.left,
.right{
float: left;
width: 100px;
margin-left: -100%;
background: green;
}
.right{
margin-left:-100px;
}
</style>
<div class="main-wrapper">
<div class="main">中间自适应</div>
</div>
<div class="left">左边固定宽度</div>
<div class="right">右边固定宽度</div>

实现过程:

  • 中间使用了双层标签,外层是浮动的,以便左中右能在同一行展示
  • 左边通过使用负 margin-left:-100%,相当于中间的宽度,所以向上偏移到左侧
  • 右边通过使用负 margin-left:-100px,相当于自身宽度,所以向上偏移到最右侧

缺点:

  • 增加了 .main-wrapper 一层,结构变复杂
  • 使用负 margin,调试也相对麻烦

使用display:table实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<style>
.container{
height: 200px;
line-height: 200px;
text-align: center;
display: table;
table-layout: fixed;
width: 100%;
}
.left,
.right,
.main{
display: table-cell;
}
.left,
.right{
width: 100px;
background: green;
}
.main{
width: 100%;
background: black;
}
</style>
<div class="container">
<div class="left">左边固定宽度</div>
<div class="main">中间自适应</div>
<div class="right">右边固定宽度</div>
</div>

原理:

  • 通过 display: table设置为表格,设置 table-layout: fixed;表示列宽自身宽度决定,而不是自动计算。
  • 内层的左中右通过 display: table-cell设置为表格单元。
  • 左右设置固定宽度,中间设置 width: 100% 填充剩下的宽度

flex

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<style>
.wrap{
display: flex;
justify-content: space-between;
}
.left,
.right,
.middle{
height: 100px;
}
.left{
width: 200px;
background: coral;
}
.right{
width: 120px;
background: lightblue;
}
.middle{
background: #555;
width: 100%; /*或者flex:1;*/
margin: 0 20px;
}
</style>
<div class="wrap">
<div class="left">左侧</div>
<div class="middle">中间</div>
<div class="right">右侧</div>
</div>

实现过程:

  • 仅需将容器设置为display:flex;
  • 盒内元素两端对其,将中间元素设置为100%宽度,或者设为flex:1,即可填充空白
  • 盒内元素的高度撑开容器的高度

优点:

  • 结构简单直观
  • 可以结合 flex的其他功能实现更多效果,例如使用 order属性调整显示顺序,让主体内容优先加载,但展示在中间

grid

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<style>
.wrap{
display: grid;
width: 100%;
grid-template-columns: 300px auto 300px;
}
.left,
.right,
.middle{
height: 100px;
}
.left{
background: coral;
}
.right{
background: lightblue;
}
.middle{
background: #555;
}
</style>
<div class="wrap">
<div class="left">左侧</div>
<div class="middle">中间</div>
<div class="right">右侧</div>
</div>

元素水平垂直居中(如果是不定高的情况呢?)五种

思路1:定位+margin: auto(让浏览器自己选择一个合适的外边距)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<style>
.father{
width: 500px;
height: 300px;
border: 1px solid #0a3b98;
position: relative;
}
.son{
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
height: 40px;
width: 100px;
margin:auto;
}
</style>
<div class="father">
<div class="son"></div>
</div>

思路2:定位+transform

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<style>
.father{
position: relative;
width: 200px;
height: 200px;
}
.son{
position: absolute;
top: 50%;
left: 50%;
width: 100px;
height: 100px;
transform: translate(-50%, -50%);
}
</style>
<div class="father">
<div class="son"></div>
</div>

思路3:table布局

​ 父元素display: table-cell,子元素display: inline-block。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<style>
.father{
display: table-cell;
width: 200px;
height: 200px;
vertical-align: middle;
text-align: center; /* text-align CSS 属性定义行内内容(例如文字)如何相对它的块父元素对齐。text-align 并不控制块元素自己的对齐,只控制它的行内内容的对齐。*/
}
.son{
display: inline-block;
width: 100px;
height: 100px;
}
</style>
<div class="father">
<div class="son"></div>
</div>

思路4:flex布局

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<style>
.father{
display: flex;
justify-content: center;
align-items: center;
width: 200px;
height: 200px;
}
.son{
width: 100px;
height: 100px;
}
</style>
<div class="father">
<div class="son"></div>
</div>

思路5:网格布局

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<style>
.father{
display: grid;
align-items: center;
justify-content: center;
width: 200px;
height: 200px;
}
.son{
width: 10px;
height: 10px;
}
</style>
<div class="father">
<div class="son"></div>
</div>

垂直居中、水平居中、垂直且水平居中

  • 水平居中:text-align: center。行内内容如何相对它的块父元素对齐。也可以在块元素中使用,来将其中的行内元素对齐。
  • 垂直居中:vertical-align: middle。只对行内、行内块元素生效,块级元素不行。
  • flex布局:设置justify-content: center水平居中;align-items: center垂直居中。
  • 垂直水平居中:
    1. 父元素relative, 子元素absolute,并且top:0, left:0, margin: auto;
    2. 绝对定位+transform: 父relative,子absolute, 并且top: 50%, left: 50%, translate(-50%, -50%);

grid网格布局

是什么?

Grid 布局即网格布局,是一个二维的布局方式,由纵横相交的两组网格线形成的框架性布局结构,能够同时处理行与列。擅长将一个页面划分为几个主要区域,以及定义这些区域的大小、位置、层次等关系。

​ 网格线:如下为2*3网格,有3根水平网格线和4根垂直网格线

网格线

属性

属性可以分为

  • 容器属性
  • 项目属性
display属性

​ 在元素上设置display:griddisplay:inline-grid 来创建一个网格容器

grid-template-columns属性,grid-template-rows属性

grid-template-columns 属性设置列宽,grid-template-rows 属性设置行高

1
2
3
4
5
6
7
8
9
.wrapper {
display: grid;
/* 声明了三列,宽度分别为 200px 200px 200px */
grid-template-columns: 200px 200px 200px;
grid-gap: 5px;
/* 声明了两行,行高分别为 50px 50px */
/*重复写的参数可以使用repeat()函数简写:第一个参数是重复的次数,第二个参数是重复的值*/
grid-template-rows: repeat(2, 50px);
}

​ 还能写成如下形式:

1
2
3
4
5
6
7
8
/*auto-fill自动填充*/
grid-template-columns: repeat(auto-fill, 200px)
/*fr表示比例,第一个列宽为200px,后面的宽度分别为剩余宽度的1/3, 2/3*/
grid-template-columns: 200px 1fr 2fr;
/*产生一个长度范围,范围内的长度都可以应用到网格中*/
grid-template-columns: minmax(100px, 1fr);
/*auto由浏览器自己决定*/
grid-template-columns: 100px auto 100px;

grid-row-gap、grid-column-gap、grid-gap属性

grid-row-gap 属性、grid-column-gap 属性分别设置行间距和列间距。grid-gap 属性是两者的简写形式

grid-template-areas属性

​ 用于定义区域,一个区域由一个或者多个单元格组成。以下代码先划分出9个单元格,然后将其定名为ai的九个区域,分别对应这九个单元格。

1
2
3
4
5
6
7
8
.container {
display: grid;
grid-template-columns: 100px 100px 100px;
grid-template-rows: 100px 100px 100px;
grid-template-areas: 'a b c'
'd e f'
'g h i';
}

grid-auto-flow属性

​ 划分网格以后,容器的子元素会按照顺序,自动放置在每一个网格。顺序就是由grid-auto-flow决定,默认为行,代表”先行后列”,即先填满第一行,再开始放入第二行。

justify-items、align-items、place-items属性

justify-items 属性设置单元格内容的水平位置(左中右),align-items 属性设置单元格的垂直位置(上中下)。place-items属性是align-items属性和justify-items属性的合并简写形式。

justify-content、align-content、place-content属性

justify-content属性是整个内容区域在容器里面的水平位置(左中右),align-content属性是整个内容区域的垂直位置(上中下)。

grid-column-start、grid-column-end、grid-row-start、grid-row-end属性

​ 指定网格项目所在的四个边框,分别定位在哪根网格线,从而指定项目的位置,grid布局的重点属性

​ 如下代码为示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<style>
#container{
display: grid;
grid-template-columns: 100px 100px 100px;
grid-template-rows: 100px 100px 100px;
}
.item-1 {
grid-column-start: 2;
grid-column-end: 4;
}
</style>

<div id="container">
<div class="item item-1">1</div>
<div class="item item-2">2</div>
<div class="item item-3">3</div>
</div>
示例

grid-area属性

指定项目放在哪一个区域

justify-self 属性、align-self 属性以及 place-self 属性

​ 用于设置单个单元格的格式

兼容性

​ 总体兼容性还不错,但在 IE 10 以下不支持。目前,Grid布局在手机端支持还不算太友好。

CSS动画

是什么?

​ 元素从一种样式逐渐过渡为另一种样式的过程。

​ CSS中动画实现方式

  • transition实现渐变动画
  • transform实现转变动画
  • animation实现自定义动画

transition

transition的属性如下:

  • property:填写需要变化的css属性
  • duration:完成过渡效果需要的时间单位(s或者ms)
  • timing-function:完成效果的速度曲线
  • delay: 动画效果的延迟触发时间

timing-function的取值如下:

描述
linear 匀速(等于 cubic-bezier(0,0,1,1))
ease 从慢到快再到慢(cubic-bezier(0.25,0.1,0.25,1))
ease-in 慢慢变快(等于 cubic-bezier(0.42,0,1,1))
ease-out 慢慢变慢(等于 cubic-bezier(0,0,0.58,1))
ease-in-out 先变快再到慢(等于 cubic-bezier(0.42,0,0.58,1)),渐显渐隐效果
cubic-bezier(n,n,n,n) 在 cubic-bezier 函数中定义自己的值。可能的值是 0 至 1 之间的数值

例如,实现鼠标移动到元素上发生变化的动画效果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<style>
.base {
width: 100px;
height: 100px;
display: inline-block;
background-color: #0EA9FF;
border-width: 5px;
border-style: solid;
border-color: #5daf34;
transition-property: width, height, background-color, border-width;
transition-duration: 2s;
transition-timing-function: ease-in;
transition-delay: 500ms;
}

/*简写*/
/*transition: all 2s ease-in 500ms;*/
.base:hover {
width: 200px;
height: 200px;
background-color: #5daf34;
border-width: 10px;
border-color: #3a8ee6;
}
</style>
<div class="base"></div>

transform

一般配合transition使用,包含四个常用的功能:

  • translate:位移
  • scale:缩放
  • rotate:旋转
  • skew:倾斜
1
2
3
4
5
6
7
8
9
10
11
12
<style>
.base2 {
transform: none;
transition-property: transform;
transition-delay: 5ms;
}

.base2:hover {
transform: scale(0.8, 1.5) rotate(35deg) skew(5deg) translate(15px, 25px);
}
</style>
<div class="base base2"></div>

​ transform的缺点:进行3D变换的时候,可能会增加内存使用量,需要更多的计算能力,从而导致动画卡顿或者页面响应变慢。

animation实现自由动画

animation是由 8 个属性的简写,分别如下:

属性 描述 属性值
animation-duration 指定动画完成一个周期所需要时间,单位秒(s)或毫秒(ms),默认是 0
animation-timing-function 指定动画计时函数,即动画的速度曲线,默认是 “ease” linear、ease、ease-in、ease-out、ease-in-out
animation-delay 指定动画延迟时间,即动画何时开始,默认是 0
animation-iteration-count 指定动画播放的次数,默认是 1
animation-direction 指定动画播放的方向,默认是 normal normal、reverse、alternate、alternate-reverse
animation-fill-mode 指定动画填充模式。默认是 none forwards、backwards、both
animation-play-state 指定动画播放状态,正在运行或暂停。默认是 running running、pauser
animation-name 指定 @keyframes 动画的名称

CSS 动画只需要定义一些关键的帧,而其余的帧,浏览器会根据计时函数插值计算出来,通过 @keyframes 来定义关键帧。

​ 因此,如果想要让元素旋转一圈,只需要定义开始和结束两帧即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@keyframes rotate{
from{
transform: rotate(0deg);
}
to{
transform: rotate(360deg);
}
}
/*或者使用百分比刻画生命周期*/
@keyframes rotate{
0%{
transform: rotate(0deg);
}
50%{
transform: rotate(180deg);
}
100%{
transform: rotate(360deg);
}
}
/*使用*/
animation: rotate 2s;

重绘与重排

是什么?

重排:布局引擎会根据各种样式计算每个盒子在页面上的大小与位置

重绘:当计算好盒模型的位置、大小及其他属性后,绘制引擎根据每个盒子特性进行绘制

触发时机

重排触发时机

​ 回流这一阶段主要是计算节点的位置和几何信息,那么当页面布局和几何信息发生变化的时候,就需要回流,如下面情况:

  • 添加或删除可见的DOM元素
  • 元素的位置发生变化
  • 元素的尺寸发生变化(包括外边距、内边框、边框大小、高度和宽度等)
  • 内容发生变化,比如文本变化或图片被另一个不同尺寸的图片所替代
  • 页面一开始渲染的时候(这避免不了)
  • 浏览器的窗口尺寸变化(因为回流是根据视口的大小来计算元素的位置和大小的)

还有一些容易被忽略的操作:获取一些特定属性的值

offsetTop、offsetLeft、 offsetWidth、offsetHeight、scrollTop、scrollLeft、scrollWidth、scrollHeight、clientTop、clientLeft、clientWidth、clientHeight

这些属性有一个共性,就是需要通过即时计算得到。因此浏览器为了获取这些值,也会进行回流

重绘触发时机

​ 触发回流一定会触发重绘。此外:颜色改变、文本方向改变、阴影改变也会触发重绘。

浏览器自身优化机制

​ 由于每次重排都会造成额外的计算消耗,因此大多数浏览器都会通过队列化修改并批量执行来优化重排过程。浏览器会将修改操作放入到队列里,直到过了一段时间或者操作达到了一个阈值,才清空队列。当你获取布局信息的操作的时候,会强制队列刷新,包括前面讲到的offsetTop等方法都会返回最新的数据。因此浏览器不得不清空队列,触发回流重绘来返回正确的值。

减少重排的方式(table、动画、fragment、离线操作)

  • 如果想设定元素的样式,通过改变元素的 class 类名 (尽可能在 DOM 树的最里层)
  • 避免设置多项内联样式
  • 应用元素的动画,使用 position 属性的 fixed 值或 absolute
  • 避免使用 table 布局,table 中每个元素的大小以及内容的改动,都会导致整个 table 的重新计算
  • 对于那些复杂的动画,对其设置 position: fixed/absolute,尽可能地使元素脱离文档流,从而减少对其他元素的影响
  • 使用css3硬件加速,可以让transformopacityfilters这些动画不会引起回流重绘
  • 避免使用 CSS 的 JavaScript 表达式
  • 使用 JavaScript 动态插入多个节点时, 可以使用DocumentFragment. 创建后一次插入. 就能避免多次的渲染性能
  • 离线操作。通过通过设置元素属性display: none,将其从页面上去掉,然后再进行后续操作,这些后续操作也不会触发回流与重绘,这个过程称为离线操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 离线前
const container = document.getElementById('container')
container.style.width = '100px'
container.style.height = '200px'
container.style.border = '10px solid red'
container.style.color = 'red'

//离线后
let container = document.getElementById('container')
container.style.display = 'none'
container.style.width = '100px'
container.style.height = '200px'
container.style.border = '10px solid red'
container.style.color = 'red'
...(省略了许多类似的后续操作)
container.style.display = 'block'

响应式设计

是什么?

​ 响应式网站设计(Responsive Web design)是一种网络页面设计布局,页面的设计与开发可以根据用户行为以及设备环境(系统平台、屏幕尺寸、屏幕定向等)进行相应的响应和调整。

响应式网站常见特点:

  • 同时适配PC + 平板 + 手机等
  • 标签导航在接近手持终端设备时改变为经典的抽屉式导航
  • 网站的布局会根据视口来调整模块的大小和位置

实现响应式布局的方式有如下:

  • 媒体查询
  • 百分比
  • vw/vh
  • rem
媒体查询

​ 通过媒体查询检测不同的设备屏幕尺寸做处理,为了处理移动端,页面头部必须有meta声明viewport

1
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no”>

属性对应如下:

  • width=device-width: 是自适应手机屏幕的尺寸宽度
  • maximum-scale:是缩放比例的最大值
  • initial-scale:是缩放的初始化
  • user-scalable:是用户的可以缩放的操作

​ 通过媒体查询,可以通过给不同分辨率的设备编写不同的样式来实现响应式的布局,比如我们为不同分辨率的屏幕,设置不同的背景图片。CSS中使用@media查询,可以针对不同的媒体类型定义不同的样式,如:

1
2
3
4
5
6
7
@media screen and (max-width: 1920px) { ... }

@media screen (min-width: 375px) and (max-width: 600px) {
body {
font-size: 18px;
}
}
百分比

heightwidth属性的百分比依托于父标签的宽高,但是其他盒子属性则不完全依赖父元素:

  • 子元素的top/left和bottom/right如果设置百分比,则相对于直接非static定位(默认定位)的父元素的高度/宽度
  • 子元素的padding如果设置百分比,不论是垂直方向或者是水平方向,都相对于直接父亲元素的width,而与父元素的height无关。
  • 子元素的margin如果设置成百分比,不论是垂直方向还是水平方向,都相对于直接父元素的width
  • border-radius不一样,如果设置border-radius为百分比,则是相对于自身的宽度

可以看到每个属性都使用百分比,会照成布局的复杂度,所以不建议使用百分比来实现响应式

vw/vh

vw表示相对于视图窗口的宽度,vh表示相对于视图窗口高度。 任意层级元素,在使用vw单位的情况下,1vw都等于视图宽度的百分之一

rem

rem是相对于根元素htmlfont-size属性,默认情况下浏览器字体大小为16px,此时1rem = 16px

为了更准确监听设备可视窗口变化,我们可以在css之前插入script标签,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
//动态为根元素设置字体大小
function init () {
// 获取屏幕宽度
var width = document.documentElement.clientWidth
// 设置根元素字体大小。此时为宽的10等分
document.documentElement.style.fontSize = width / 10 + 'px'
}
//首次加载应用,设置一次
init()
// 监听手机旋转的事件的时机,重新设置
window.addEventListener('orientationchange', init)
// 监听手机窗口变化,重新设置
window.addEventListener('resize', init)

​ 无论设备可视窗口如何变化,始终设置remwidth的1/10,实现了百分比布局。

响应式布局的优缺点

优点:

  • 面对不同分辨率设备灵活性强
  • 能够快捷解决多设备显示适应问题

缺点:

  • 仅适用布局、信息、框架并不复杂的部门类型网站
  • 兼容各种设备工作量大,效率低下
  • 代码累赘,会出现隐藏无用的元素,加载时间加长
  • 其实这是一种折中性质的设计解决方案,多方面因素影响而达不到最佳效果
  • 一定程度上改变了网站原有的布局结构,会出现用户混淆的情况

优化CSS(提高CSS性能的方法)

实现方式

  • 内联首屏关键CSS
  • 异步加载CSS
  • 资源压缩
  • 合理使用选择器
  • 减少使用昂贵的属性
  • 不要使用@import
内联首屏关键CSS

​ 在打开一个页面,页面首要内容出现在屏幕的时间影响着用户的体验,而通过内联css关键代码能够使浏览器在下载完html后就能立刻渲染。而如果外部引用css代码,在解析html结构过程中遇到外部css文件,才会开始下载css代码,再渲染。所以,CSS内联使用使渲染时间提前。

​ 注意:但是较大的css代码并不合适内联(初始拥塞窗口、没有缓存),而其余代码则采取外部引用方式。

异步加载CSS

​ 在CSS文件请求、下载、解析完成之前,CSS阻塞渲染,浏览器将不会渲染任何已处理的内容。前面加载内联代码后,后面的外部引用css则没必要阻塞浏览器渲染。这时候就可以采取异步加载的方案,主要有如下:

  • 使用javascript将link标签插到head标签最后
1
2
3
4
5
6
// 创建link标签
const myCSS = document.createElement( "link" );
myCSS.rel = "stylesheet";
myCSS.href = "mystyles.css";
// 插入到header的最后位置
document.head.insertBefore( myCSS, document.head.childNodes[ document.head.childNodes.length - 1 ].nextSibling );
资源压缩

​ 利用webpackgulp/gruntrollup等模块化工具,将css代码进行压缩,使文件变小,大大降低了浏览器的加载时间

合理使用选择器

css匹配的规则是从右往左开始匹配,例如#markdown .content h3匹配规则如下:

  • 先找到h3标签元素
  • 然后去除祖先不是.content的元素
  • 最后去除祖先不是#markdown的元素

​ 如果嵌套的层级更多,页面中的元素更多,那么匹配所要花费的时间代价自然更高。

​ 所以我们在编写选择器的时候,可以遵循以下规则:

  • 不要嵌套使用过多复杂选择器,最好不要三层以上
  • 使用id选择器就没必要再进行嵌套
  • 通配符和属性选择器效率最低,避免使用
减少使用昂贵的属性

​ 在页面发生重绘的时候,昂贵属性如box-shadow/border-radius/filter/透明度/:nth-child等,会降低浏览器的渲染性能。

不要使用import

​ css样式文件有两种引入方式,一种是link元素,另一种是@import@import会影响浏览器的并行下载,使得页面在加载时增加额外的延迟,增添了额外的往返耗时。而且多个@import可能会导致下载顺序紊乱。比如一个css文件index.css包含了以下内容:@import url("reset.css")。那么浏览器就必须先把index.css下载、解析和执行后,才下载、解析和执行第二个文件reset.css

实现单行/多行文本溢出的省略样式

单行文本溢出省略

1
2
3
4
5
p{
overflow: hidden;/*文本溢出限定的宽度就隐藏内容*/
text-overflow: ellipsis;/*省略号*/
white-space: nowrap; /*不换行*/
}

多行文本溢出省略

基于高度截断:伪元素+定位
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<style>
.demo {
position: relative;
line-height: 20px;
height: 40px;
overflow: hidden;
}
.demo::after {
content: "...";
position: absolute;
bottom: 0;
right: 0;
padding: 0 20px 0 10px;
}
</style>
<body>
<div class='demo'>这是一段很长的文本</div>
</body>

实现原理就是通过伪元素绝对定位到行尾并遮住文字,再通过 overflow: hidden 隐藏多余文字

这种实现具有以下优点:

  • 兼容性好,对各大主流浏览器有好的支持
  • 响应式截断,根据不同宽度做出调整
基于行数截断: 移动端大多数是使用webkit, 所以移动端常用该形式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<style>
p {
width: 400px;
border-radius: 1px solid red;
-webkit-line-clamp: 2;/*用来限制在一个块元素显示的文本的行数,为了实现该效果,它需要组合其他的WebKit属性)*/
display: -webkit-box;/*和1结合使用,将对象作为弹性伸缩盒子模型显示*/
-webkit-box-orient: vertical;/*和1结合使用 ,设置或检索伸缩盒对象的子元素的排列方式*/
overflow: hidden;/*文本溢出限定的宽度就隐藏内容*/
text-overflow: ellipsis;
}
</style>
<p>
这是一些文本这是一些文本这是一些文本这是一些文本这是一些文本
这是一些文本这是一些文本这是一些文本这是一些文本这是一些文本
</p >

CSS完成视差滚动效果

是什么?

​ 视差滚动(Parallax Scrolling)是指多层背景以不同的速度移动,形成立体的运动效果,带来非常出色的视觉体验。多层指背景层、内容层、悬浮层。

实现方式

使用css形式实现视觉差滚动效果的方式有:

  • background-attachment
  • transform:translate3D

background-attachment

​ 作用是设置背景图像是否固定或者随着页面的其余部分滚动。

​ 值分别有如下:

  • scroll:默认值,背景图像会随着页面其余部分的滚动而移动
  • fixed:当页面的其余部分滚动时,背景图像不会移动
  • inherit:继承父元素background-attachment属性的值

​ **完成滚动视觉差就需要将background-attachment属性设置为fixed**,让背景相对于视口固定。即使一个元素有滚动机制,背景也不会随着元素的内容而滚动。也就是说,背景一开始就已经被固定在初始的位置。

1
2
3
4
5
.g-img {
background-image: url(...);
background-attachment: fixed;
background-size: cover;/*覆盖背景区域*/
}

transform: translate3D

transform与perspective:

  • transform: css3 属性,可以对元素进行变换(2d/3d),包括平移 translate,旋转 rotate,缩放 scale,等等
  • perspective: css3 属性,当元素涉及 3d 变换时,perspective 可以定义我们眼睛看到的 3d 立体效果,即空间感
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<style>
html {
overflow: hidden;
height: 100%
}

body {
/* 视差元素的父级需要3D视角 */
perspective: 1px;
transform-style: preserve-3d;
height: 100%;
overflow-y: scroll;
overflow-x: hidden;
}
#app{
width: 100vw;
height:200vh;
background:skyblue;
padding-top:100px;
}
.one{
width:500px;
height:200px;
background:#409eff;
transform: translateZ(0px);
margin-bottom: 50px;
}
.two{
width:500px;
height:200px;
background:#67c23a;
transform: translateZ(-1px);
margin-bottom: 150px;
}
.three{
width:500px;
height:200px;
background:#e6a23c;
transform: translateZ(-2px);
margin-bottom: 150px;
}
</style>
<div id="app">
<div class="one">one</div>
<div class="two">two</div>
<div class="three">three</div>
</div>

而这种方式实现视觉差动的原理如下:

  • 容器设置上 transform-style: preserve-3d 和 perspective: 1px,那么处于这个容器的子元素就将位于3D空间中,
  • 子元素设置不同的 transform: translateZ(),这个时候,不同元素在 3D Z轴方向距离屏幕(我们的眼睛)的距离也就不一样
  • 滚动滚动条,由于子元素设置了不同的 transform: translateZ(),那么他们滚动的上下距离 translateY 相对屏幕(我们的眼睛),也是不一样的,这就达到了滚动视差的效果

CSS画一个三角形

三角形

实心三角形

1
2
3
4
5
6
7
.border {
width: 0;
height: 0;/*width和height用于设置中间空白矩形*/
border-style:solid;
border-width: 0 50px 50px;/*隐藏上边三角*/
border-color: transparent transparent #d9534f;/*隐藏上边、左边和右边的border*/
}

添加伪元素画空心三角形

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
.border {
width: 0;
height: 0;
border-style:solid;
border-width: 0 50px 50px;
border-color: transparent transparent #d9534f;
position: relative;
}
.border::after{
content: '';
border-style:solid;
border-width: 0 40px 40px;
border-color: transparent transparent #96ceb4;
position: absolute;
top: 6px;
left: -40px;
}

为什么伪元素一定要指定一个content呢?

W3C上的描述:content的初始值为’normal’,在::before、::after上如果指定了content的初始值为’normal’,则等同于’none’,也就是不生成伪元素。

所以为了生成伪元素,至少需要指定一个看似无意义的content:’’来初始化content的值。

取消某条边框时,可能出现的情况:

  • 取消一条边的时候,与这条边相邻的两条边的接触部分会变成直的
  • 当仅有邻边时, 两个边会变成对分的三角
  • 当保留边没有其他接触时,极限情况所有东西都会消失

可以通过以上原理来设置直角三角形

1
2
3
4
5
6
7
8
9
10
11
.box {
/* 内部大小 */
width: 0px;
height: 0px;
/* 边框大小 只设置两条边*/
border-top: #4285f4 solid;
border-right: transparent solid;
border-width: 85px;
/* 其他设置 */
margin: 50px;
}

CSS预编语言

CSS存在的问题

​ CSS需要书写大量看似没有逻辑的代码,不方便维护及扩展,不利于复用。Css预处理器便是针对上述问题的解决方案。

CSS预处理语言

​ 扩充了 Css 语言,增加了诸如变量、混合(mixin)、函数等功能,让 Css 更易维护、方便。CSS预处理语言包含一套自定义的语法及一个解析器,根据这些语法定义自己的样式规则,这些规则最终会通过解析器,编译生成对应的 Css 文件。

主流的CSS预处理语言

  • sass
  • less
  • stylus:主要用来给 Node 项目进行 Css 预处理支持

区别

使用的主要特性:

  • 变量(variables)
  • 作用域(scope)
  • 代码混合( mixins)
  • 嵌套(nested rules)
  • 代码模块化(Modules)
变量

less声明的变量必须以@开头,后面紧跟变量名和变量值,而且变量名和变量值需要使用冒号:分隔开。

1
2
3
4
@red: #c00;
strong {
color: @red;
}

sass声明的变量必须以$开头

作用域

sass中不存在全局变量。

1
2
3
4
5
6
7
8
9
10
$color: black;
.scoped {
$bg: blue;
$color: white;
color: $color;
background-color:$bg;
}
.unscoped {
color:$color;
}

​ 编译后:

1
2
3
4
5
6
7
.scoped {
color:white;/*是白色*/
background-color:blue;
}
.unscoped {
color:white;/*白色(无全局变量概念)*/
}

lessstylus的作用域跟javascript十分的相似,首先会查找局部定义的变量,如果没有找到,会像冒泡一样,一级一级往上查找.

1
2
3
4
5
6
7
8
9
10
@color: black;
.scoped {
@bg: blue;
@color: white;
color: @color;
background-color:@bg;
}
.unscoped {
color:@color;
}

​ 编译后:

1
2
3
4
5
6
7
.scoped {
color:white;/*白色(调用了局部变量)*/
background-color:blue;
}
.unscoped {
color:black;/*黑色(调用了全局变量)*/
}
混入

​ 混入(mixin)是预处理器最精髓的功能之一了,简单点来说,**Mixins可以将一部分样式抽出,作为单独定义的模块,被很多选择器重复使用。**可以在Mixins中定义变量或者默认参数。

1
2
3
4
5
6
7
8
9
10
11
.alert {
font-weight: 700;
}
.highlight(@color: red) {
font-size: 1.2em;
color: @color;
}
.heads-up {
.alert;
.highlight(red);
}

编译后:

1
2
3
4
5
6
7
8
.alert {
font-weight: 700;
}
.heads-up {
font-weight: 700;
font-size: 1.2em;
color: red;
}
模块化

​ 模块化就是将Css代码分成一个个模块。scsslessstylus三者的使用方法都如下所示:

1
2
3
4
@import './common';
@import './github-markdown';
@import './mixin';
@import './variables';

让chrome支持小于12px的文字

  • zoom:改变页面上元素的尺寸
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<style type="text/css">
.span1{
font-size: 12px;
display: inline-block;
zoom: 0.8;
}
.span2{
display: inline-block;
font-size: 12px;
}
</style>
<body>
<span class="span1">测试10px</span>
<span class="span2">测试12px</span>
</body>
  • -webkit-transform: scale()【缩放】
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<style type="text/css">
.span1{
font-size: 12px;
display: inline-block;
-webkit-transform:scale(0.8);
}
.span2{
display: inline-block;
font-size: 12px;
}
</style>
<body>
<span class="span1">测试10px</span>
<span class="span2">测试12px</span>
</body>
  • -webkit-text-size-adjust: none
1
2
3
html{ 
-webkit-text-size-adjust: none;
}

浮动

为什么要浮动?

​ 块级元素往往独占一行,如果想要多个块级元素在一行上显示就要用到浮动。浮动后块级元素之间是紧紧挨着的,不存在间距。而inline-block虽然也能在一行显示,但是中间会存在间距且不好去除。

​ 浮动产生的最根本的原因是实现文字环绕效果。

清除浮动的本质是

​ 清除浮动主要是为了解决父级元素因为子元素浮动而引起内部高度为0 的问题。清除浮动后,父元素根据浮动的盒子自动检测高度,父级有了高度就不会影响下面的标准流了。

清除浮动的方法

  • 给父元素设置一个高度。只适合高度固定的布局。
  • clear: both;这个属性用于表示框的哪边不应该挨着浮动框。这个规则只能影响使用清除的元素本身,不能影响其他元素。
  • overflow: hidden;BFC。BFC中会计算浮动元素的高度。给浮动元素的父元素添加此属性,这个属性能清除子元素浮动给页面的影响,必须定义width或zoom:1,同时不能设定height,浏览器会自动检查浮动区域的高度。

使用rem适配不同屏幕

  1. 在header中设置meta标签
1
<meta name="viewport" content="initial-scale=1,maximum-scale=1,minimum-scale=1"></meta>
  1. 在header中写上script标签
1
2
3
4
5
<!-- 此处是设置html标签的font-size,因为使用rem的时候是相对于html标签中的font-size为基础的 -->
<script type="text/javascript">
document.documentElement.style.fontSize = document.documentElement.clientWidth/640*100+'px';
// 此处假设设计稿的宽度为640,设备物理宽度为clientWidth。如果不*100,那么这个值可能会小于12,有可能会造成计算错误,所以先*100方便计算,后面设置数值的时候/100就行
</script>
  1. 场景:设计稿是640px,有一个红色盒子宽高是320px,里面的文字是32px
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1, minimum-scale=1">
<script type="text/javascript">
document.documentElement.style.fontSize = document.documentElement.clientWidth / 640*100 + 'px';
</script>
</head>
<body style="margin: 0 ;padding: 0;font-size: 0.32rem">
<div style="width: 3.2rem;height: 3.2rem ;background: red">
<span>danny.xie</span>
</div>
</body>
</html>

渲染层与合成层

渲染层

处于相同坐标空间(Z轴空间)的渲染对象,都将归并到同一个渲染层中,因此根据层叠上下文,不同坐标空间的渲染对象将形成多个渲染层,以体现它们的层叠关系。

合成层

满足某些特殊条件的渲染层,会被浏览器提升为合成层,交由GPU处理。

常见的合成层

i. transforms

ii. 通过CSS动画实现的opacity动画转换

iii.video、canvas等元素

iv. position: fixed

合成层元素特点
  • 合成层的位图会交由GPU合成,比CPU处理快得多
  • 当需要重绘时,只需要重绘本身,不会影响其他层
  • 元素提升为合成层后,transform和opacity才不会出发重绘,如果不是合成层,则依然会触发chong

calc函数布局

  • 基本理论:calc可以作用于任何具有大小的东西,比如border、margin、padding、font-size等属性设置动态值。支持的计算单位:rem、em、%、px。
  • 注意点:calc内部的表达式,在使用运算符号时,两边必须加上空格。
1
2
3
width: calc(10 * 10px);
width: calc(50% - 50px);
width: calc(50% + 5em);

requestAnimation

优点

  1. 更平滑的动画效果:requestAnimation可以在浏览器下一次重绘之前调用动画函数,从而避免了抖动和卡顿问题,使动画效果更加平滑。
  2. 更好的性能:requestAnimation可以避免在不必要的时候进行重绘。如果动画某一帧没有发生任何变化,那么浏览器就无需重绘,则会跳过这一帧,等到下一帧再进行绘制。而普通JS编写的函数无法做到。
  3. 更少的代码:requestAnimation无需手动计算动画的时间间隔,而是使用浏览器提供的帧率来计算动画的时间间隔。

有一个动画,分别使用requestAnimation包裹和使用原生JS写,当页面切换到后台时,动画是否还会继续执行呢?

​ 均不会。当页面被切换到后台后,浏览器会将页面的渲染和JS执行暂停,不论是requestAnimation还是普通的JS动画,都会被暂停。