CSS学习笔记(4):CSS3新特性概述

CSS3选择器

主要选择器种类

CSS3中主要的选择器有:

  • div 标签选择器
  • .box 类名选择器
  • #box id选择器
  • div p 后代选择器
  • div.box 交集选择器
  • div,p,span 并集选择器
  • div>p 子代选择器
  • * : 通配符
  • div+p 选中div后面相邻的第一个p
  • div~p 选中的div后面所有的p

属性选择器

属性选择器的标志性符号是 []。

匹配含义:^:开头;$:结尾;*:包含。

格式:

  • E[title] 选中页面的E元素,并且E存在 title 属性即可。
  • E[title=”abc”]选中页面的E元素,并且E需要带有title属性,且属性值完全等于abc。
  • E[attr~=val] 选择具有 att 属性且属性值为:用空格分隔的字词列表,其中一个等于 val 的E元素。
  • E[attr|=val] 表示要么是一个单独的属性值,要么这个属性值是以“-”分隔的。
  • E[title^=”abc”] 选中页面的E元素,并且E需要带有 title 属性,属性值以 abc 开头。
  • E[title$=”abc”] 选中页面的E元素,并且E需要带有 title 属性,属性值以 abc 结尾。
  • E[title*=”abc”] 选中页面的E元素,并且E需要带有 title 属性,属性值任意位置包含abc。

结构伪类选择器

伪类选择器的标志性符号是单冒号:。

CSS中有一些伪类选择器,比如:link、:active、:visited、:hover,这些是动态伪类选择器。

CSS3又新增了结构伪类选择器,即通过结构来进行筛选

关于数量的结构伪类选择器

各种基于数量的结构伪类选择器格式为:

  • E:first-child 匹配父元素的第一个子元素E。
  • E:last-child 匹配父元素的最后一个子元素E。
  • E:nth-child(n) 匹配父元素的第n个子元素E。注意,盒子的编号是从1开始算起,不是从0开始算起,但是n是从0算起的,无效的n值会被忽略。
  • E:nth-last-child(n) 匹配父元素的倒数第n个子元素E。

理解:

(1)这里我们要好好理解父元素的含义,它指的是:以 E 元素的父元素为参考。

(2)注意:以上选择器中所选到的元素的类型,必须是指定的类型E,如果选不中,则无效。具体可以看CSS参考手册中的E:nth-child(n)的示例。我们可以理解成:先根据选择器找到选中的全部位置,如果发现某个位置不是类型E,则该位置失效。

对于E:nth-child(n)选择器,使用是很灵活的,如:

  • 如果选择器写成li:nth-child(2),则表示第2个 li。
  • 如果选择器写成li:nth-child(n),则表示所有的li。因为此时的 n 表示 0,1,2,3,4,5,6,7,8…..
  • 如果选择器写成li:nth-child(2n),则表示所有的第偶数个 li。
  • 如果选择器写成li:nth-child(2n+1),则表示所有的第奇数个 li。
  • 如果选择器写成li:nth-child(-n+5),则表示前5个 li。
  • 如果选择器写成li:nth-last-child(-n+5),则表示最后5个 li。
  • 如果选择器写成li:nth-child(7n),则表示选中7的倍数。

总之要注意n 表示 0,1,2,3,4,5,6,7,8…..,而盒子编号从1开始,非法的n值会直接被忽略。

关于类型的结构伪类选择器

与类型相关进行选择的结构伪类选择器:

  • E:first-of-type 匹配同类型中的第一个同级兄弟元素E。
  • E:last-of-type 匹配同类型中的最后一个同级兄弟元素E。
  • E:nth-of-type(n) 匹配同类型中的第n个同级兄弟元素E。
  • E:nth-last-of-type(n) 匹配同类型中的倒数第n个同级兄弟元素E。

即先在同级里找到所有的E类型,然后根据 n 进行匹配。

其他结构伪类选择器

此外还有两个结构伪类选择器:

  • E:empty 匹配没有任何子节点(包括空格等text节点)的元素E。
  • E:target 匹配相关URL指向的E元素。要配合锚点使用。

伪元素选择器

内容外伪元素

用于在元素的内容外(前后)充当伪元素的选择器:

  • E::before 设置在 元素E 前面(依据对象树的逻辑结构)的内容,配合content属性一起使用。
  • E::after 设置在 元素E 后面(依据对象树的逻辑结构)的内容,配合content属性一起使用。

E:after、E:before 在旧版本里是伪类,在 CSS3 这个新版本里是伪元素。新版本里,E:after、E:before会被自动识别为E::after、E::before,按伪元素来对待,这样做的目的是用来做兼容处理。

如以下例子:

1
2
3
4
5
6
7
8
9
10
11
span::before{
content: "可爱的";
color: red;
}
span::after{
content: "的博客";
color: green;
}
span{
border: 1px solid #000;
}

效果如下:

大森

其中红字是通过::before来添加的,绿字是通过::after来添加的,不属于文档内容。

可以看到:

  • 通过伪元素选择器,就可以添加出类似于span标签的效果(记得要结合 content 属性使用)。
  • 添加的伪元素是在标签的内容部分的前后添加的,可以看到span的边框包含了两个伪元素。
  • 通过这两个属性添加的伪元素是行内元素,需要转换成块元素才能设置宽高。

内容内伪元素

这些伪元素设置了元素内部分内容的样式:

  • E::first-letter 设置元素 E 里面的第一个字符的样式。
  • E::first-line 设置元素 E 里面的第一行的样式。
  • E::selection 设置元素 E 里面被鼠标选中的区域的样式(一般设置颜色和背景色)。

CSS3动画

过渡

transition的中文含义是过渡。过渡是CSS3中具有颠覆性的一个特征,可以实现元素不同状态间的平滑过渡(补间动画),经常用来制作动画效果:

  • 补间动画:自动完成从起始状态到终止状态的的过渡。不用管中间的状态。
  • 帧动画:通过一帧一帧的画面按照固定顺序和速度播放。如电影胶片。

transition 包括以下属性:

  • transition-property: all; 如果希望所有的属性都发生过渡,就使用all。
  • transition-duration: 1s; 过渡的持续时间。
  • transition-timing-function: linear; 运动曲线。属性值可以是:
    • linear 线性
    • ease 减速
    • ease-in 加速
    • ease-out 减速
    • ease-in-out 先加速后减速
  • transition-delay: 1s; 过渡延迟,多长时间后延迟执行这个过渡动画。

上面的四个属性也可以写成综合属性transition,属性书写的顺序即为:过渡属性、持续时间、运动曲线、延迟时间。如:

1
transition: all 3s linear 0s;

这样设置即会使元素的所有属性在变化时均进行过渡。

2D转换

转换是 CSS3 中具有颠覆性的一个特征,可以实现元素的位移、旋转、变形、缩放,甚至支持矩阵方式。

转换再配合过渡和动画,可以取代大量早期只能靠 Flash 才可以实现的效果。

在 CSS3 当中,通过 transform 转换来实现 2D 转换或者 3D 转换。

2D转换包括:缩放、移动、旋转。

要注意2D变换不会把别的DOM挤走

缩放

缩放使用scale函数来实现,格式为scale(x, y)。 x表示水平方向的缩放倍数,y表示垂直方向的缩放倍数,如果只写一个值就是等比例缩放。大于1表示放大,小于1表示缩小。不能为百分比。如:

1
2
transform: scale(2, 0.5);
transform: scale(3);

位移

格式为translate(水平位移, 垂直位移),如:

1
transform: translate(-50%, -50%);

参数为百分比,相对于自身移动。正值表示向右和向下,负值表示向左和向上。如果只写一个值,则表示水平移动,即第二个参数可省略。

对于绝对定位的盒子,我们想让它在父元素中居中,可以这样:

1
2
3
4
5
6
7
8
9
div {
width: 600px;
height: 60px;
position: absolute; /*绝对定位的盒子*/
left: 50%; /*首先,让左边线居中*/
top: 0;
/*然后,向左移动宽度(600px)的一半*/
margin-left: -300px;
}

这里也可以用transform来做,即:

1
2
3
4
5
6
7
8
9
10
div {
width: 600px;
height: 60px;
background-color: red;
position: absolute; /*绝对定位的盒子*/
left: 50%; /*首先,让左边线居中*/
top: 0;
/*然后,利用translate,往左走自己宽度的一半*/
transform: translate(-50%);
}

旋转

使用rotate来实现,即rotate(角度),如:

1
transform: rotate(45deg);

参数正值为顺时针旋转;负值为逆时针旋转。

设置旋转动画时,除了给盒子设置 transform 中的 rotate 旋转,同时还要给盒子设置 transition 过渡。如果没有这行过渡的代码,旋转会直接一步到位,不会有中间动作。

rotate 旋转时,默认是以盒子的正中心为坐标原点的。如果想改变旋转的坐标原点,可以用transform-origin属性:

1
2
3
transform-origin: 50px 50px;
/*旋转时,以盒子底部的中心为坐标原点*/
transform-origin: center bottom;

3D转换

三维旋转

按照绕三个坐标轴旋转的角度分别设置(左手竖直坐标系):

1
2
3
transform: rotateX(360deg);    /*绕 X 轴旋转360度*/
transform: rotateY(360deg); /*绕 Y 轴旋转360度*/
transform: rotateZ(360deg); /*绕 Z 轴旋转360度*/

在设置三维旋转时最好给图片的父盒子加一个透视属性,如:

1
perspective: 110px;

没有这个属性的话,图片旋转的时候,像是压瘪了一样。

三维移动

同样依次设置三个坐标方向:

1
2
3
transform: translateX(100px);    /*沿着 X 轴移动*/
transform: translateY(360px); /*沿着 Y 轴移动*/
transform: translateZ(360px); /*沿着 Z 轴移动*/

同样,如果不给父盒子加透视属性,是看不到translateZ的效果的。

透视

在上面两个例子里都使用了透视属性:

1
perspective: 500px;

电脑显示屏是一个 2D 平面,图像之所以具有立体感(3D效果),其实只是一种视觉呈现,通过透视可以实现此目的。

透视可以将一个2D平面,在转换的过程当中,呈现3D效果。但仅仅只是视觉呈现出 3D 效果,并不是真正的3D。

3D呈现

3D元素构建是指某个图形是由多个元素构成的,可以给这些元素的父元素设置transform-style: preserve-3d来使其变成一个真正的3D图形。属性值可以如下:

1
2
3
4
/* 让子盒子位于三维空间里 */
transform-style: preserve-3d;
/* 让子盒子位于此元素所在的平面内(子盒子被扁平化) */
transform-style: flat;

如以下立方体的例子:

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
.box {
width: 250px;
height: 250px;
border: 1px dashed red;
margin: 100px auto;
position: relative;
border-radius: 50%;

/* 让子盒子保持3d效果*/
transform-style: preserve-3d;

/*transform:rotateX(30deg) rotateY(-30deg);*/
animation: gun 8s linear infinite;
}

.box > div {
width: 100%;
height: 100%;
position: absolute;
text-align: center;
line-height: 250px;
font-size: 60px;
color: #daa520;
}

.left {
background-color: rgba(255, 0, 0, 0.3);
/* 变换中心*/
transform-origin: left;
/* 变换*/
transform: rotateY(90deg) translateX(-125px);
}

.right {
background: rgba(0, 0, 255, 0.3);
transform-origin: right;
/* 变换*/
transform: rotateY(90deg) translateX(125px);
}

.forward {
background: rgba(255, 255, 0, 0.3);
transform: translateZ(125px);
}

.back {
background: rgba(0, 255, 255, 0.3);
transform: translateZ(-125px);
}

.up {
background: rgba(255, 0, 255, 0.3);
transform: rotateX(90deg) translateZ(125px);
}

.down {
background: rgba(99, 66, 33, 0.3);
transform: rotateX(-90deg) translateZ(125px);
}

@keyframes gun {
0% {
transform: rotateX(0deg) rotateY(0deg);
}

100% {
transform: rotateX(360deg) rotateY(360deg);
}
}
</style>
</head>
<body>
<div class="box">
<div class="up"></div>
<div class="down"></div>
<div class="left"></div>
<div class="right"></div>
<div class="forward"></div>
<div class="back"></div>
</div>
</body>
</html>

效果如下:

动画

动画是CSS3中具有颠覆性的特征,可通过设置多个节点 来精确控制一个或一组动画,常用来实现复杂的动画效果。

定义动画的步骤

定义动画的步骤如下:

  • 通过@keyframes定义动画;
  • 将这段动画通过百分比,分割成多个节点;然后各节点中分别定义各属性;
  • 在指定元素里,通过 animation 属性调用动画。

在 CSS3 中定义动画的时候,也是先定义,再调用,如下格式:

定义动画:

1
2
3
4
@keyframes 动画名{
from{ 初始状态 }
to{ 结束状态 }
}

调用:

1
animation: 动画名称 持续时间;

其中,animation属性的完整格式如下:

1
animation: 定义的动画名称 持续时间 执行次数 是否反向 运动曲线 延迟执行;

执行次数中infinite 表示无限次。如:

1
2
animation: move1 1s  alternate linear 3;
animation: move2 4s;

可以看到只有动画名称和持续时间是必须的。

如以下例子:

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
.box {
width: 100px;
height: 100px;
margin: 100px;
background-color: red;
}

.box:hover {
/* 调用动画*/
/* animation: 动画名称 持续时间 执行次数 是否反向 运动曲线 延迟执行。infinite 表示无限次*/
/*animation: move 1s alternate linear 3;*/
animation: move2 4s;
}

/* 方式一:定义一组动画*/
@keyframes move1 {
from {
transform: translateX(0px) rotate(0deg);
}
to {
transform: translateX(500px) rotate(555deg);
}
}

/* 方式二:定义多组动画*/
@keyframes move2 {
0% {
transform: translateX(0px) translateY(0px);
background-color: red;
border-radius: 0;
}

25% {
transform: translateX(500px) translateY(0px);

}

/*动画执行到 50% 的时候,背景色变成绿色,形状变成圆形*/
50% {
/* 虽然两个方向都有translate,但其实只是Y轴上移动了200px。
因为X轴的500px是相对最开始的原点来说的。可以理解成此时的 translateX 是保存了之前的位移 */
transform: translateX(500px) translateY(200px);
background-color: green;
border-radius: 50%;
}

75% {
transform: translateX(0px) translateY(200px);
}

/*动画执行到 100% 的时候,背景色还原为红色,形状还原为正方形*/
100% {
/*坐标归零,表示回到原点。*/
transform: translateX(0px) translateY(0px);
background-color: red;
border-radius: 0;
}
}
</style>
</head>
<body>
<div class="box"></div>
</body>
</html>

效果如下:
(PC端将鼠标放在盒子上触发动画;移动端点击盒子触发动画)

动画属性

在调用动画时将合写属性拆分为以下:

(1)动画名称:

1
animation-name: move;

(2)执行一次动画的持续时间:

1
animation-duration: 4s;

注意:这前两个属性,是必选项,且顺序固定。

(3)动画的执行次数:

1
animation-iteration-count: 1;

属性值infinite表示无数次。

(4)动画的方向:

1
animation-direction: alternate;

属性值:normal 正常,alternate 反向。

(5)动画延迟执行:

1
animation-delay: 1s;

(6)设置动画结束时,盒子的状态:

1
animation-fill-mode: forwards;

属性值: forwards:保持动画结束后的状态(默认), backwards:动画结束后回到最初的状态。

(7)运动曲线:

1
animation-timing-function: ease-in;

属性值可以是:linear ease-in-out steps()等。

注意,如果把属性值写成steps(),则表示动画不是连续执行,而是间断地分成几步执行。比如可以实现时钟的指针特效等。

Flex布局

默认文档流中,在一个父容器里放置多个块级的子元素,那么,这些子元素会默认从上往下排列。如果给父容器加一个 display: flex属性,这些子元素的布局就会变为水平方向:

特点

flex 布局的子元素不会脱离文档流,很好地遵从了“流的特性”。

如果用 float 来做布局,float 属性的元素会脱离文档流,而且会涉及到各种 BFC、清除浮动的问题。浮动相关的问题,比较麻烦,所以也成了面试必问的经典题目。但有了 flex 布局之后,这些问题都不存在的。

flex 是一种现代的布局方式,是 W3C 第一次提供真正用于布局的 CSS 规范。 flex 非常提供了丰富的属性,非常灵活,让布局的实现更佳多样化,且方便易用。

flex 唯一的缺点就在于,它不支持低版本的 IE 浏览器。如果你的页面不需要处理 IE浏览器的兼容性问题,则可以放心大胆地使用 flex 布局。

概念

在Flex布局中主要有以下概念:

  • 弹性盒子:指的是使用 display:flex 或 display:inline-flex 声明的父容器。
  • 子元素/弹性元素:指的是父容器里面的子元素们(父容器被声明为 flex 盒子的情况下)。
  • 主轴:flex容器的主轴,默认是水平方向,从左向右。
  • 侧轴:与主轴垂直的轴称作侧轴,默认是垂直方向,从上往下。

弹性盒子

使用 display:flex 或 display:inline-flex 声明一个父容器为弹性盒子。此时,这个父容器里的子元素们,会遵循弹性布局。一般 display:flex属性用得较多,display:inline-flex用得较少。

flex-direction 属性用于设置盒子中子元素的排列方向。属性值可以是:

  • row:从左到右水平排列子元素(默认值)。
  • column:从上到下垂直排列子元素。
  • row-reverse:从右向左排列子元素。
  • column-reverse:从下到上垂直排列子元素。

flex-wrap 属性控制子元素溢出时的换行处理。

justify-content 属性控制子元素在主轴上的排列方式。属性值可以是:

  • flex-start 从主轴的起点对齐(默认值)。
  • flex-end 从主轴的终点对齐。
  • center 居中对齐。
  • space-around 在父盒子里平分。
  • space-between 两端对齐 平分。

align-items 属性设置子元素在侧轴上的对齐方式。属性值可以是:

  • flex-start 从侧轴开始的方向对齐。
  • flex-end 从侧轴结束的方向对齐。
  • baseline 基线 默认同flex-start。
  • center 中间对齐。
  • stretch 拉伸。

弹性元素

主要有flex属性:设置子盒子的权重。根据权重分配子盒子的宽度比例。

Web字体

常见字体格式

TureTpe格式:(.ttf)

.ttf 字体是Windows和Mac的最常见的字体,是一种RAW格式。

支持这种字体的浏览器有IE9+、Firefox3.5+、Chrome4+、Safari3+、Opera10+、iOS Mobile、Safari4.2+。

OpenType格式:(.otf)

.otf 字体被认为是一种原始的字体格式,其内置在TureType的基础上。

支持这种字体的浏览器有Firefox3.5+、Chrome4.0+、Safari3.1+、Opera10.0+、iOS Mobile、Safari4.2+。

Web Open Font Format格式:(.woff)

woff字体是Web字体中最佳格式,他是一个开放的TrueType/OpenType的压缩版本,同时也支持元数据包的分离。

支持这种字体的浏览器有IE9+、Firefox3.5+、Chrome6+、Safari3.6+、Opera11.1+。

Embedded Open Type格式:(.eot)

.eot字体是IE专用字体,可以从TrueType创建此格式字体,支持这种字体的浏览器有IE4+。

SVG格式:(.svg)

.svg字体是基于SVG字体渲染的一种格式。

支持这种字体的浏览器有Chrome4+、Safari3.1+、Opera10.0+、iOS Mobile Safari3.2+。

使用Web字体

(1)第一步:使用font-face声明字体

1
2
3
4
5
6
7
@font-face {font-family: 'webfont';
src: url('webfont.eot'); /* IE9*/
src: url('webfont.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('webfont.woff') format('woff'), /* chrome、firefox */
url('webfont.ttf') format('truetype'), /* chrome、firefox、opera、Safari, Android, iOS 4.2+*/
url('webfont.svg#webfont') format('svg'); /* iOS 4.1- */
}

(2)第二步:定义使用webfont的样式

1
2
3
4
5
6
.web-font{
font-family:"webfont" !important;
font-size:16px;font-style:normal;
-webkit-font-smoothing: antialiased;
-webkit-text-stroke-width: 0.2px;
-moz-osx-font-smoothing: grayscale;}

(3)第三步:为文字加上对应的样式

1
<i class="web-font">Web字体</i>



* 你好,我是大森。如果文章内容帮到了你,你可通过下方付款二维码支持作者 *