CSS学习笔记

Evan MVP+

CSS 基础概念

基础语法

CSS 的基础语法是:

1
2
3
选择器 {
属性: 属性值;
}

引入方式

CSS 样式有三种引入方式,分别是:

  • 行内样式:通常通过 js 添加,最终效果如 <p style="color: gray; font-size: 16px">这是第二段文字</p>
  • 内部样式:直接在 style 标签中书写【学习使用】
  • 外部样式:引入外部的 CSS 文件,如 <link rel="stylesheet" href="style.css" />【开发使用】

CSS 选择器

基础选择器

CSS 中选择器是一个很重要的概念,所有 html 元素都需要先选中,才能给它们添加或修改样式,这就是选择器的功能。CSS 基础选择器有以下几种:

  • 标签选择器:如 p{} span{}
  • 类选择器:如 .nav{} .title{} 【最常用】
  • id 选择器:如 #nav{} #title{}
  • 通配符选择器:即 *{} ,通常用来清除内外边距
  • id 选择器和标签的关系是一对一的,类选择器多对多(一个类选择器可以对应多个标签,一个标签也可以有多个类名)
  • 类名要见名知意,可以使用-和_符号,不能用中文,不能用数字开头,最好不要使用拼音
  • 在实际开发中,这些选择器通常会配合使用

后代选择器

选择所有后代中的特定元素

1
2
3
.nav a {
color: red;
}

子代选择器

选择特定的直接子元素

1
2
3
.nav > a {
color: red;
}

区别:后代选择器可以跨多级寻找,子代选择器只会寻找下一级

并集选择器

同时选择多个类型的元素,以统一应用相同的样式,可以使用并集选择器:

1
2
3
4
5
6
7
8
9
10
/* 正确写法 */
.dad a,
.mom a {
color: green;
}
/* 错误写法:dad类中的a标签不会被应用样式 */
.dad,
.mom a {
color: black;
}

并集选择器的优先级比后代选择器低,所以一起使用时要注意

交集选择器

选择同时满足多个条件的元素,使可以用交集选择器:

1
2
3
4
/* 选择a标签且类名是mark的元素 */
a.mark {
color: red;
}

伪类选择器

选择特定状态的元素,常见的伪类有:

  • :link 链接未被访问时的样式,只能作用于 a 标签
  • :visited 链接已经访问过的样式,只能作用于 a 标签
  • :hover 鼠标经过时的样式【常用】
  • :active 鼠标按下未松手时的样式
1
2
3
4
5
6
7
8
9
10
11
12
a:link {
color: blue;
}
a:visited {
color: gray;
}
a:hover {
color: red;
}
a:active {
color: orange;
}

如果四个属性一起写,顺序必须是:love hate

我们一般给 a 链接设置样式都是直接设置,极少用到 :link :visited :active 这三个伪类

结构伪类选择器

我们可以根据 HTML 元素结构来选择元素:

1
2
3
4
5
6
7
8
/* 选择第一个li(不是孩子) */
.mom ul li:first-child {
background-color: pink;
}
/* 选择最后一个li(不是孩子) */
.mom ul li:last-child {
background-color: blue;
}

image-20230714145141775

这里要求 ul 的第一个孩子必须是 li 标签才能选中,若写成 .mom ul :last-child 对第一个孩子是谁没有要求

为了能够选择更多的元素,CSS 还提供了 :nth-child() 结构伪类选择器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/* 【1】单词 */
/* even 表示偶数(元素从1开始) */
.dad ul li:nth-child(even) {
background-color: skyblue;
}
/* odd 表示奇数(元素从1开始) */
.dad ul li:nth-child(odd) {
background-color: pink;
}
/* 【2】数字*n */
/* 表示数字的0,1,2...倍,n表示0,1,2... */
/* 5*0 5*1 5*2... */
.dad ul li:nth-child(5n) {
background-color: red;
}
/* 2*0+1 2*1+1 2*2+1... */
.dad ul li:nth-child(2n + 1) {
background-color: purple;
}
/* 【3】数字 */
/* 表示第几个(元素从1开始) */
.dad ul li:nth-child(3) {
background-color: blue;
}

image-20230714151602350

使用 nth-child 属性进行连选:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/* 选择前5个 0+5 -1+5 -2+5 -3+5 -4+5 -5+5 */
.dad ul li:nth-child(-n + 5) {
background-color: pink;
}

/* 选择从第5个开始后面所有的元素 0+5 1+5... */
.dad ul li:nth-child(n + 5) {
background-color: gray;
}

/* 选择后5个 :nth-last-child从后往前数 */
.dad ul li:nth-last-child(-n + 5) {
background-color: skyblue;
}

image-20230714153140318

:nth-child 的功能非常强大,它支持数字、单词、表达式等多种方式选择元素,唯一需要注意的是 html 元素是从 1 开始数的,n 是从 0 开始的

结构伪类选择器补充

image-20230715094004038

1
2
3
4
5
6
7
/* 只看li元素,对第一个元素没有要求 */
.nav ul li:first-of-type {
background-color: skyblue;
}
.nav ul li:last-of-type {
background-color: red;
}

image-20230715161031821

伪元素选择器

伪元素用来摆放装饰性的内容,常用的伪元素有:

  • ::before 在元素内部最前面添加一个伪元素
  • ::after 在元素内部最后面添加一个伪元素
1
2
3
4
5
6
.box::before {
content: "锄禾";
}
.box::after {
content: "当午";
}

image-20230714160836925

伪元素的几个注意点:

  • content 属性必填,用于设置伪元素的内容【可以为空】
  • 添加的伪元素是一个行内元素,不能直接设置宽高
  • 在权重计算中,伪元素也相当于一个标签

伪元素选择器补充

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* 设置文本首行样式 */
p::first-line {
background-color: pink;
}
/* 设置文本首字母样式 */
p::first-letter {
color: red;
font-size: 30px;
font-weight: 700;
}
/* 设置选中时的样式 */
p::selection {
color: #fff;
background-color: skyblue;
}
/* 设置提示文本样式 */
input::placeholder {
color: pink;
}

image-20230714163227429

CSS 文字属性

文字大小

font-size 属性用来设置文字的大小,可以使用 px 单位,通常设置为偶数

  • 谷歌浏览器默认文字大小为 16px
  • font-size: 0;可以隐藏文字

文字粗细

font-weight 属性用来设置文字的粗细。它的属性值可以是数字,也可以是英文单词:

1
2
3
4
/* 加粗文字的两种写法 */
span {
font-weight: 700; /* 相当于font-weight:bold; */
}

我们也可以反其道行之:

1
2
3
4
/* 将文字粗细恢复正常 */
strong {
font-weight: 400; /* 相当于font-weight:normal; */
}
  • 在实际开发中,推荐使用纯数字的写法
  • 如果将 font-weight 调到 100~300,文字就会变得比正常文字更细

文字倾斜

font-style 属性指定文字是否倾斜:

1
2
3
4
/* 将span文字倾斜显示 */
span {
font-style: italic;
}

在实际开发中,由于我们经常使用 <i></i> 标签来显示图标,所以我们一般会在初始化时设置:

1
2
3
4
/* i标签中的文字和图标正常显示,不倾斜 */
i {
font-style: normal;
}

文字行高

行高是两行文字基线之间的距离,也可以看做是顶线之间的距离。行高包括文字的高度

image-20230711101210092

line-height 属性用来设置文字的行高。我们常用行高属性来 垂直居中单行文本

1
2
3
4
5
6
7
.box {
width: 200px;
height: 200px;
background-color: pink;
/* 当行高等于盒子高度时,盒子内的‘单行文本’会在盒子中垂直居中 */
line-height: 200px;
}

如果我们在设置行高时没有指定单位,表示行高是当前文字大小的若干倍:

1
2
3
4
.box {
font-size: 16px
line-height: 1.5; /* 行高为32px */
}

字体族

font-family 属性可以指定若干字体,浏览器会从前往后寻找,直到找到可用的字体:

1
2
3
body {
font-family: "黑体", "华文彩云", "幼圆", sans-serif;
}

image-20230711105557775

sans-serif 是一系列字体,表示计算机默认的无衬线字体,这种字体没有笔锋,不容易造成视觉疲劳,在计算机上经常使用,如微软雅黑等

CSS 文本属性

文本缩进

text-indent 属性用来使一段文本首行缩进显示:

1
2
3
4
p {
/* 首行缩进两个字符的大小 */
text-indent: 2em;
}

1em 等于当前文字的大小

文本修饰

text-decoration 属性用来修饰文本,就是加下划线什么的。一个常用用法是 去除 a 标签的下划线修饰

1
2
3
4
5
6
7
8
9
10
11
12
/* 清除a标签默认的下划线 */
a {
text-decoration: none;
}
span {
/* 添加上划线 */
/* text-decoration: overline; */
/* 添加删除线 */
/* text-decoration: line-through; */
/* 添加下划线 */
text-decoration: underline;
}

文本对齐

text-align 属性用来定义盒子中的文本在水平方向上的对齐方式,属性值可以是 left、center、right 其中之一

1
2
3
4
5
6
<div class="one">Promise</div>
<div class="two">
<a href="#">百度</a>
<a href="#">百度</a>
<a href="#">百度</a>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
.one {
width: 200px;
height: 200px;
background-color: pink;
/* 垂直居中 */
line-height: 200px;
/* 水平居中 */
text-align: center;
}
.two {
text-align: center;
}

image-20230711151123443

text-align 是给父元素添加,让 子元素(可以是文本,行内元素,图片、表单控件等) 在父元素中水平对齐。

text-align 不能控制块级元素的水平对齐方式!

CSS 背景属性

背景颜色

background-color 属性用来设置元素的背景颜色

1
2
3
4
5
.box {
width: 100px;
height: 100px;
background-color: pink;
}

元素单独设置背景颜色、背景图片不会生效,块元素要有宽高,行内元素要有内容

在使用绝对定位后,块元素会脱标,如果没有指定宽度,则宽度为 0 ,不能在页面中显示

背景图

background-image 属性用来设置元素的背景图片:

1
2
3
4
5
.logo {
width: 80px;
height: 80px;
background-image: url(./logo.png);
}

image-20230712141443647

背景图平铺

当给元素设置的宽高小于图片尺寸时,图片默认只显示左上角那一部分;当元素宽高大于图片尺寸时,默认图片会平铺多次,以占满元素的全部空间

background-repeat 属性用来设置背景图片的平铺方式:

image-20230712144919054

背景图位置

background-position 属性用来设置背景图片在元素中的位置:

image-20230712152205919

背景图片默认会在元素左上方显示

背景图尺寸

background-size 属性用来设置背景图片的尺寸,它的属性值有:

  • 数字
  • cover: 等比例缩放图片,让图片把盒子填满(图片部分可能超出盒子区域)
  • contain: 等比例缩放图片,让图片完整地显示在盒子内(盒子内部可能留有空白)
1
2
/* 使用数字直接定义图片尺寸 设置单个值作为宽度,高度会等比例缩放 */
background-size: 250px;

image-20230712160642415

1
2
/* 等比例缩放图片, 让图片把盒子填满*/
background-size: cover;

image-20230712160542604

1
2
/* 等比例缩放图片,让图片完整地显示出来 */
background-size: contain;

image-20230712160515461

记忆口诀:contain “包含” 图片

背景图固定

background-attachment 属性用来设置背景图是否跟随页面滚动:

  • scroll:随页面滚动【默认】
  • fixed:固定在页面的某一位置
1
2
3
4
5
6
body {
background-image: url(./bg.jpg);
background-repeat: no-repeat;
background-size: cover;
background-attachment: fixed;
}

背景复合属性

background 是所有背景属性的复合属性,可以将不同的背景属性值连写:

image-20230712163701690

当然,一般我们都这样使用背景复合属性:

1
background: url(./logo.png) no-repeat; /* 注意不要写成background-image */

CSS 三大特性

继承性

子标签可以继承父标签的特定样式。在 CSS 中,文字属性、文本属性默认是可继承的,而关于背景、盒子、定位、布局的属性,都不能够被继承

image-20230714103050983

如果标签有默认样式,继承的属性就不会生效。像继承的 color 无法影响 a 标签,继承的 font-size、font-weight 无法影响 h1 标签等。这种情况需要单独设置

层叠性

层叠性主要是为了解决样式冲突的问题,它规定了当一个标签设置了多个相同的属性时,哪个属性会被覆盖,哪个属性最终会生效

image-20230714114909085

隐藏属性问题

在使用连写属性时,因为有一些默认的属性值,可能在不经意间就不小心覆盖了前面的相关属性:

1
2
3
/* background连写,默认背景颜色是transparent,所以下面的background-color会被覆盖 */
background-color: pink;
background: url(./logo.png) no-repeat; /* 实际转换为 background: transparent url(./logo.png) no-repeat; */

image-20230714114545601

再比如:

1
2
3
4
5
6
7
width: 200px;
height: 200px;
background-color: pink;
text-align: center;
line-height: 200px;
/* font连写,默认行高为normal,所以会把上面的line-height覆盖掉,导致文字并没有垂直居中 */
font: 16px 黑体;

image-20230714114736678

优先级

对于两个简单选择器,优先级的基本规则是:【重要】

1
2
!important > 行内样式 > id选择器 > 类选择器 > 标签选择器 > 浏览器默认样式 >
继承(未选中)

对于复杂的选择器,可以通过计算权重来确定其优先级:CSS 样式表的继承性和层叠性

一个通过计算权重确定优先级的例子:

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
/* 【1】 0,1,2 */
.nav li a {
color: green;
}
/* 【2】 0,1,3 */
/* 权重比【1】高,覆盖 */
.nav ul li a {
color: red;
}
/* 【3】 0,1,0 */
/* 不生效,权重低 */
.last {
color: orange;
}
/* 【4】 0,2,0 */
/* 生效,提高了权重 */
.nav .last {
color: purple;
}
/* 【5】 0,1,1 */
/* 不生效,权重低 */
a:hover {
color: gray;
}
/* 【6】 0,2,1 */
/* 生效,提高了权重 */
/* 伪类也算一个类选择器 */
.nav a:hover {
color: blue;
}
</style>
</head>
<body>
<div class="nav">
<ul>
<li><a href="#">索隆</a></li>
<li><a href="#">路飞</a></li>
<li><a href="#" class="last">山治</a></li>
</ul>
</div>
</body>
</html>

image-20230714142250315

hover 之后:

image-20230714142328052

当我们添加的样式语法正确,样式却不生效时,就可以看看是否是选择器的权重太低了,如果是,提高一下权重就可以了

CSS 显示模式

显示模式分类

HTML 中的所有元素都是以下三种显示模式之一:

image-20230712172923366

可以把 img、input 看做行内块元素,或者说是行内替换元素来理解 为什么 img、input 等内联元素可设置宽高?

显示模式转换

元素的显示模式不是一成不变的,我们可以使用 display 属性改变元素的显示模式:

  • block: 显示为块元素【常用】
  • inline-block: 显示为行内块元素【常用】
  • inline: 显示为行内元素

我们一般都是使用 display 将行内元素转换为块元素或行内块元素,这样元素就可以设置宽高了

一个使用行内块制作导航栏的例子:

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
.nav {
text-align: center;
}
.nav a {
/* 转换为行内块元素,使宽高生效 */
display: inline-block;
width: 80px;
height: 50px;
color: #eee;
background-color: pink;
text-decoration: none;
text-align: center;
line-height: 50px;
}
.nav a:hover {
background-color: skyblue;
}
</style>
</head>
<body>
<div class="nav">
<a href="#">宫保鸡丁</a>
<a href="#">麻婆豆腐</a>
<a href="#">鱼香肉丝</a>
<a href="#">水煮肉片</a>
<a href="#">老八汉堡</a>
</div>
</body>
</html>

image-20230712182625396

CSS 盒模型

盒模型分类

网页是由一个一个盒子组成的,盒子用来布局网页,摆放子盒子和内容。一个盒子由四部分组成:

  1. content 内容
  2. padding 内边距
  3. border 边框
  4. margin 外边框

盒模型有两种:1. 标准盒模型 2. IE 盒模型

标准盒模型

标准盒模型是现代浏览器默认的盒模型,盒子的实际尺寸=内容(设置的宽高)+内边距+边框,也就是说,盒子的大小会受到内边距和边框的影响【可能撑大盒子】

1
box-sizing: content-box; /* 默认就是标准盒模型 */

image-20230714202047842

添加内边距和边框后,盒子尺寸被撑大了(虽然我们设置的宽高是 200px,但盒子大小已经是 242px 了)

IE 盒模型

IE 盒模型是另一种盒模型,这种盒模型下,盒子的实际尺寸=设置的宽高=内容内边距+边框,也就是说,盒子的大小固定,宽高设多少就一定是多少

转换为 IE 盒模型:

1
box-sizing: border-box;

image-20230714202143029

转换为 IE 盒模型后,盒子的宽高就固定了,此时再添加内边距和边框,盒子大小也不会被改变,只是会向内挤压内容区域

边框

border 属性用来给元素添加边框,例如:

1
border: 1px solid red;

border 属性其实是下面三个属性的连写:

  • border-width: 边框粗细,默认 3px
  • border-style: 边框样式(solid 实线,dashed 虚线,dotted 点线)【必填】
  • border-color:边框颜色,默认黑色

如果没有设置边框样式,那么另外两个属性将不会生效

盒子要有大小,边框才能够正常显示

清除边框:

1
border: 0; /* 或 border: none; */

内边距

padding 属性用来设置内边距,即内容和边框之间的距离。它可以接受多个值:

image-20230714203746370

记忆口诀:上右下左填值,没值看对面

给盒子设置背景颜色,会填充内容区域和 padding 区域

外边距

margin 属性用来设置外边距,外边距是两个元素之间的距离(在元素边框之外)。当子元素是一个块元素并且宽度小于父元素宽度时,剩余宽度会被 margin 占据

外边距的用法和内边距基本相同,其中外边距的一个常见用法是 使块元素水平居中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
body {
background-color: #eee;
}
.box {
width: 200px;
height: 200px;
background-color: pink;
/* 行内元素、行内块元素水平居中 */
text-align: center;
/* 块元素水平居中 */
/* 方式一 */
margin-left: auto;
margin-right: auto;
/* 方式二 */
margin: 0 auto;
/* 方式三 */
margin: auto;
}

image-20230715102505482

块元素水平居中的前提是,这个块元素要有自定义的宽度!

要给定位子元素拉开距离,左定位加右margin,右定位加左margin

使用外边距可能会有一些意想不到的问题:

问题一 外边距合并

垂直方向上并列的两个盒子,如果它们都设置了 margin,那么它们之间的外边距会合并【取较大值】

image-20230715142940215

image-20230715142902734

两个盒子之间的距离不是两者上下 margin 之和 150px,而是其中的较大值 100px

margin 在水平方向上叠加,在垂直方向上合并

问题二 外边距塌陷

嵌套的两个元素,给子元素设置 marign-top,会把父元素一起带下去:

image-20230715153059901

解决方法(BFC):

  • 给父元素设置 padding-top 代替
  • 给父元素设置 overflow: hidden;
  • 给父元素设置 border-top
  • 其他能够实现 BFC 的方法

清除默认边距

html 中大多数块元素都有默认的边距,为了消除对布局的影响,一般在开发前期就要清除默认边距:

1
2
3
4
5
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

image-20230715161819063

清除默认边距后:

image-20230715161900764

行内元素设置边距

行内元素只能设置水平方向上的边距,设置垂直边距会有问题:

image-20230715153717819

结果:垂直外边距没有生效

image-20230715153823209

结果:垂直内边距上下不一致,并且布局错乱

我们一般不会被行内元素设置上下边距,只会设置左右边距

CSS浮动

浮动的特点

浮动常用来做 PC 端网站布局。语法:

  • float: left 左浮动
  • float: right 右浮动

浮动的作用:让块元素水平排列

浮动的特点:【重要】

  • 浮动元素之间顶部对齐
  • 浮动元素具备行内块的特点(宽高可设置&在一行内显示)
  • 浮动元素不会超出父元素的范围
  • 浮动元素不会影响前面的元素
  • 浮动元素不会遮挡文字和内容
  • 浮动元素脱标,不占空间【在普通元素上方显示】
  • 如果子元素都浮动,并且父元素没有固定高度,那么需要给父元素清除浮动

浮动解决了直接使用行内块布局的一些问题:

  • 块元素换行有空格
  • 块内容可能非顶线对齐
  • 屏幕适配差

浮动原本是用来做文字环绕图片效果的(给图片加浮动),后来才被用于网页布局

清除浮动

默认在 html 标准流中,父元素大小可以由子元素撑开

然而,一旦子元素全部设置了浮动,就不能再撑开父元素

如果父元素没有设置高度,那么高度就是 0,这将导致后面的元素上移,页面布局错乱

这时就要用到清除浮动(清除浮动带来的影响,让父元素高度可以由内容撑开)

清除浮动的三种方法

1. 额外标签法

在父元素末尾添加新的块级子元素,并设置:

1
<div style="clear: both"></div>

2. overflow 属性

给父元素添加 overflow: hidden; 属性,实现 BFC

3. 单双伪元素法【常用】

给父元素添加 clearfix 类,然后利用伪元素清除浮动:

1
2
3
4
5
6
/* 单伪元素法 */
.clearfix::after {
content: "";
display: block;
clear: both;
}
1
2
3
4
5
6
7
8
9
/* 双伪元素法 */
.clearfix::before,
.clearfix::after {
content: "";
display: table;
}
.clearfix::after {
clear: both;
}

问:为什么不直接给父元素加一个高度呢?
答:因为有时父元素中的内容多少无法确定,父元素的高度也就没办法固定

浮动布局案例

使用浮动布局小米商城导航栏:

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
<div class="nav">
<!-- 版心区域 -->
<div class="nav-main w clearfix">
<!-- 左导航 -->
<ul class="nav-left clearfix">
<li><a href="#">小米官网</a><span>|</span></li>
<li><a href="#">小米商城</a><span>|</span></li>
<li><a href="#">MIUI</a><span>|</span></li>
<li><a href="#">IoT</a><span>|</span></li>
<li><a href="#">云服务</a><span>|</span></li>
<li><a href="#">天星数科</a><span>|</span></li>
<li><a href="#">有品</a><span>|</span></li>
<li><a href="#">小爱开放平台</a><span>|</span></li>
<li><a href="#">企业团购</a><span>|</span></li>
<li><a href="#">资质证照</a><span>|</span></li>
<li><a href="#">协议规则</a><span>|</span></li>
<li><a href="#">下载app</a><span>|</span></li>
<li><a href="#">Select Location</a><span>|</span></li>
</ul>
<!-- 右导航 -->
<ul class="nav-right clearfix">
<li><a href="#">登录</a><span>|</span></li>
<li><a href="#">注册</a><span>|</span></li>
<li><a href="#">消息通知</a></li>
</ul>
</div>
</div>
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
/* 清除默认样式和边距... */
.clearfix::after {
content: "";
display: block;
clear: both;
}
/* 通栏 不设置宽度 */
.nav {
/* 这里设置了高度,所以无论里面元素是否浮动,都不会对下面内容产生影响 */
height: 40px;
background-color: #333;
}
/* 版心 */
.w {
width: 1226px;
margin: 0 auto;
}
.nav-left {
float: left;
}
.nav-right {
float: right;
}
.nav li {
/* 让每个li水平排列 */
float: left;
line-height: 40px;
}
.nav li a {
color: #b0b0b0;
font-size: 12px;
}
.nav li span {
color: #424242;
margin: 0 4px;
}

image-20230717153044888

CSS Flex 布局

什么是 Flex

flex 是一种新兴的网页布局方式,与浮动相比,使用 flex 布局网页更简单更灵活,而且也不会有因元素脱标而导致的页面布局错乱问题

使用 flex 布局的元素可以自适应屏幕尺寸大小,这在移动端网页布局中很常见

Flex 布局属性

掌握 flex 布局的第一步是了解它的一系列相关属性,一起来看看吧~

flex 弹性布局 动画详解

display

display: flex 创建一个 flex 容器,直接子元素成为弹性元素,可以自动拉伸或被父元素挤压

  • 弹性容器的主轴默认在水平方向,侧轴默认在垂直方向
  • 如果子元素没有设置高度,默认会占满父元素高度
  • 父元素设置 display: flex 成为弹性容器后,所有子元素的 display 属性会失效【不是直接子元素可以】
  • 弹性元素就像行内块一样,可以直接设置宽高
justify-content

设置弹性元素沿弹性容器主轴的对齐方式,属性值有:

属性值特点
flex-start从起点开始依次向后排列【默认】
flex-end依次向后排列到终点结束
center弹性元素整体居中排列
space-between弹性元素两端对齐,然后均分中间空白区域 【常用】
space-around弹性元素两边均分空白区域
space-evenly弹性元素等分空白区域

看一下它们各自的效果:

image-20230720164055292

image-20230720164125621

image-20230720164154261

image-20230720164243074

image-20230720164313351

image-20230720164344445

align-content

设置弹性元素的侧轴对齐方式(多行),它的属性值和 justify-content 完全相同:

属性值特点
flex-start从起点开始依次向后排列【默认】
flex-end依次向后排列到终点结束
center弹性元素整体居中排列
space-between弹性元素两端对齐,然后均分中间空白区域 【常用】
space-around弹性元素两边均分空白区域
space-evenly弹性元素等分空白区域
align-items

设置弹性元素的侧轴对齐方式(单行)

属性值特点
flex-start从起点开始依次向后排列【默认】
flex-end依次向后排列到终点结束
center弹性元素整体居中排列
stretch弹性元素拉伸铺满弹性容器(在元素没有设置侧轴方向尺寸)

默认情况下,父元素必须有高度,align-items 属性值才会生效!

align-self

给某一个弹性元素设置其侧轴对齐方式(单个元素)

属性值特点
flex-start从起点开始依次向后排列【默认】
flex-end依次向后排列到终点结束
center弹性元素整体居中排列
stretch弹性元素拉伸铺满弹性容器(在元素没有设置侧轴方向尺寸)

align-self 属性和下面的 flex 属性都是直接作用于弹性子元素的!

flex

flex 弹性伸缩比,用于控制主轴方向上,弹性元素占父元素剩余空间的份数。属性值为整数数字

使用 flex 属性实现圣杯布局:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
.container {
width: 800px;
height: 500px;
border: 1px solid #333;
margin: 100px auto;
text-align: center;
display: flex;
}
/* 圣杯布局:中间内容区域随父元素弹性伸缩 */
/* 1. 左右固定宽度 */
/* 2. 内容区域弹性伸缩 */
.left,
.right {
width: 200px;
background-color: skyblue;
}
.content {
flex: 1;
background-color: pink;
}
1
2
3
4
5
<div class="container">
<div class="left">left</div>
<div class="content">content</div>
<div class="right">right</div>
</div>

image-20230720201638739

flex-wrap

flex 是一个弹性容器,当子元素大小超出弹性容器大小时,默认会被挤压

想让子元素在超出时换行显示,就要指定 flex-wrap: wrap; 属性

一个使用 flex-wrap 属性的例子:

image-20230720175431515

设置 display: flex; 后,可以看到,父元素宽度不够,子元素宽度默认被挤压了:image-20230720175401617

给父元素添加 flex-wrap: wrap; 属性,子元素在超出时会自动换行:

image-20230720175454126

flex-direction

我们知道,flex 布局的主轴默认在水平方向,相对应的侧轴在垂直方向。

使用 flex-direction 属性可以修改主轴方向:

image-20230720114029922

下面是一个使用该属性的例子:

1
2
3
4
5
6
7
8
/* 让上下排列的多个子元素垂直水平居中 */
.box {
/* ... */
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
1
2
3
4
5
<div class="box">
<img src="./img/3.webp" alt="" />
<h4>Redmi Note 12T Pro</h4>
<p>年度LCD屏幕之光</p>
</div>

image-20230720195505861

如果不改变主轴方向,就不能竖着排,而是会变成横着排:

image-20230720195731487

主轴为水平方向时,弹性元素默认高度为弹性容器高度;主轴为垂直方向时,弹性元素默认宽度是弹性容器宽度

关于 flex 布局的详细用法,请参照:Flex 布局图文详解原来 flex 布局还能那么细?

CSS 定位

什么是定位

定位的使用场景有:

  • 改变盒子在网页中的位置
  • 将盒子固定在网页的某一位置
  • 让盒子在其他盒子上方显示

image-20230723195955522

image-20230723195648254

定位模式

position 属性用来指定定位模式,属性值:

  • static:静态定位,盒子按页面正常文档流显示,不进行任何移动(默认)
  • relative:相对定位,以盒子原本的位置为基准,使用方位属性进行移动
  • absolute:绝对定位,以最近的非 static 定位祖先元素为基准,使用方位属性进行移动
  • fixed:固定定位,以浏览器视口为基准,使用方位属性进行移动,并且固定盒子位置,不随页面滚动而滚动

三种定位模式的对比

定位模式是否脱标是否转换显示模式
relative盒子不脱标盒子显示模式不变
absolute盒子脱标,不再占有标准流空间盒子显示模式转换为行内块,可直接设置宽高
fixed盒子脱标,不再占有标准流空间盒子显示模式转换为行内块,可直接设置宽高
  • 一般脱标的元素都具备行内块的特点,像绝对定位,固定定位,浮动等【flex 不脱标】
  • 我们在布局时,要遵循一个原则:子绝父相 (父元素使用相对定位不会影响后面的元素,子元素使用绝对定位方便移动)

边偏移

设置定位模式后,可以使用边偏移属性移动盒子位置

  • top:距离基准顶部的距离
  • bottom:距离基准底部的距离
  • left:距离基准左侧的距离
  • right:距离基准右侧的距离
  • 四个方位的属性值可以是 px、百分比单位的,正值往里走,负值往外走
  • top 和 bottom、left 和 right 相反方向只能设置一个,如果都设置,以 top 和 left 为准
  • 除非设置了 position 定位属性,否则设置任何边偏移都不会有效果

堆叠层级

定位后的元素层级提高,在普通元素上方显示

在 html 结构中,后定义的定位元素在先定义的定位元素上方显示

要改变定位元素之间的层叠顺序,可以使用 z-index 属性,该属性接受一个整数数字用来表明定位元素的层级,数值越大越靠上

image-20230723200316579

image-20230723200402173

定位居中

假设有这样的 html 结构:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!-- css -->
<style>
.dad {
position: relative;
width: 800px;
height: 500px;
background-color: skyblue;
margin: 100px auto;
}
.son {
width: 300px;
height: 150px;
background-color: pink;
}
</style>

<!-- html -->
<div class="dad">
<div class="son"></div>
</div>

image-20230723174512384

现在,我们想让粉色盒子在父元素中水平垂直居中,可以先将子元素向右、向下移动父元素宽高的一半,再将子元素向左、向上移动自身宽高的一半,此时子元素刚好在父元素中水平垂直居中

写法一

1
2
3
4
5
6
7
.son {
position: absolute;
left: 50%;
top: 50%;
margin-left: -150px;
margin-top: -75px;
}

写法二

1
2
3
4
5
6
7
.son {
position: absolute;
left: 50%;
top: 50%;
/* 这里的百分比,是子元素自身的百分比 */
transform: translate(-50%, -50%);
}

写法三

1
2
3
4
5
6
7
8
.son {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
}

image-20230723180003084

三种方式都要先设置父元素为相对定位,给子元素一个基准

关于更多 CSS 水平垂直居中的方式,请参考 CSS 实现水平垂直居中的 6 种方式

有关定位的详细介绍,请参考 CSS 的浮动和定位布局详细(全)

CSS 变换

opacity 透明度

opacity 用来设置整个元素的透明度【包含背景和内容】

  • 0:完全透明
  • 1:不透明

如果不想元素内容消失,可以用透明背景色代替

transition 过渡

通常当 CSS 的属性值更改后,浏览器会立即更新相应的样式

transition01

CSS 过渡效果可以让样式改变地更加平滑:

1
2
3
4
5
6
7
8
9
10
11
.box {
width: 200px;
height: 200px;
background-color: pink;
/* 可以简写为 transition: all 0.3s; */
transition: width 0.3s, background-color 0.3s;
}
.box:hover {
width: 500px;
background-color: red;
}

transition02

transition 属性语法

transition: property duration timing-function delay;

  • property:要过渡的属性【必填】
  • duration:过渡持续时间,单位 s【必填】
  • timing-function:运动曲线(先慢后快,还是先快后慢)
  • delay:(过渡开始时的)延迟时间

例 给卡卡西添加底部遮罩

  1. 先搭建元素基本结构和初始化样式
1
2
3
4
5
<div class="box">
<img src="./images/卡卡西.jpg" alt="卡卡西" />
<!-- 底部遮罩 -->
<div class="bottom-intro">我是卡卡西</div>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.box {
position: relative;
width: 500px;
height: 368px;
margin: 100px auto;
}
/* 底部遮罩 */
.bottom-intro {
width: 100%;
height: 80px;
background-color: rgba(0, 0, 0, 0.4);
color: #fff;
font-size: 24px;
line-height: 80px;
text-align: center;
}

image-20230724170012726

  1. 使用定位改变遮罩的位置,让它紧贴父元素的下边
1
2
3
4
5
6
.bottom-intro {
position: absolute;
/* 因为遮罩的高度为80px,所以bottom下移80px正好出去 */
bottom: -80px;
left: 0;
}

image-20230725142701114

  1. 先将遮罩隐藏掉,hover 时再上移
1
2
3
4
5
6
7
8
9
10
.box {
overflow: hidden;
}
.box:hover .bottom-intro {
bottom: 0;
}
/* 添加0.3s的过渡 */
.bottom-intro {
transition: all 0.3s;
}

kakaxi

过渡效果只能对数字属性值的属性变化生效(background-color 会转换为数字值)

谁做过渡谁加,而不是加在 hover 伪类中

关于过渡的详细用法,请参考 CSS transition(过渡效果)详解

transform 变换

transform-2d

transform-3d

transform 属性可以对元素进行移动、旋转和缩放

  • transform: translate(X, Y):移动元素,值为移动的距离,单位 px、百分比【百分比表示移动元素自身大小的百分比】
  • transform: rotate(deg): 旋转元素,值为旋转角度,单位 deg【正值顺时针旋转,负值逆时针旋转】
  • transform: scale(sx, sy):缩放元素,值为数字,表示将元素放大或缩小的倍数

变换后的元素与绝对定位的元素类似,不会影响周围的元素(可以和周围的元素重叠);不同的是,变换后的元素不脱标,在页面中仍然会占用原来的空间

例 hover 小米 logo

  1. 先搭建元素基本结构和初始化样式
1
2
3
<div class="logo">
<a href="https://www.mi.com"></a>
</div>
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
.logo {
width: 49px;
height: 49px;
background-color: #ff6a00;
margin: 100px auto;
}
/* 使用伪元素显示要切换的两张图片 */
.logo a::before {
content: "";
display: block;
width: 49px;
height: 49px;
background: red url(./mi-logo.png) no-repeat;
}
.logo a::after {
content: "";
display: block;
width: 49px;
height: 49px;
background: green url(./mi-home.png) no-repeat;
}
/* 让两个伪元素并排显示 */
.logo a {
display: flex;
width: 98px;
}

image-20230725143905549

  1. 给盒子添加溢出隐藏,在 hover 时,我们只需要移动 a 元素的位置,就能实现两张背景图的切换
1
2
3
4
5
6
7
8
9
10
11
12
13
/* 添加圆角和溢出隐藏 */
.logo {
border-radius: 16px;
overflow: hidden;
}
.logo a:hover {
/* 两张图片大小都是 49×49,所以将a左移49 */
transform: translate(-49px, 0);
}
/* 添加0.3s的过渡 */
.logo a {
transition: all 0.3s;
}

mi-logo

  1. 最后,去除两张图片的背景色,让 box 显示自身的背景色
1
2
3
4
.logo a::before,
.logo a::after {
background-color: transparent;
}

mi

我们移动的是外面的 a,而不是 a 中的两个伪元素

关于 transform 的详细用法,请参考

综合案例

例一 开关门案例

技术点:translate 平移,transition 过渡

  1. 先搭建元素基础结构和样式
1
<div class="box"></div>
1
2
3
4
5
6
.box {
width: 1366px;
height: 600px;
background: url(./images/bg.jpg);
margin: 100px auto;
}
  1. 使用伪元素创建 box 的两个子元素
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/* 使用一张图片的不同部分 */
.box::before {
content: "";
width: 50%;
height: 100%;
background: url(./images/fm.jpg);
}
.box::after {
content: "";
width: 50%;
height: 100%;
background: url(./images/fm.jpg);
background-position: right center;
}
/* 让两个子伪元素横排,可设置宽高 */
.box {
display: flex;
}
  1. hover 盒子时,移出两个子伪元素
1
2
3
4
5
6
7
8
9
10
11
12
13
.box:hover::before {
transform: translateX(-100%);
}
.box:hover::after {
transform: translateX(100%);
}
/* 添加过渡效果 */
.box::before {
transition: all 0.5s;
}
.box::after {
transition: all 0.5s;
}
  1. 最后将超出盒子的部分隐藏掉
1
2
3
.box {
overflow: hidden;
}

kaimen

例二 旋转扑克牌

技术点:rotate 旋转,transition 过渡

  1. 先搭建元素基础结构和样式
1
2
3
4
5
6
7
8
<div class="box">
<img src="./images/pk1.png" alt="" />
<img src="./images/pk2.png" alt="" />
<img src="./images/pk1.png" alt="" />
<img src="./images/pk2.png" alt="" />
<img src="./images/pk1.png" alt="" />
<img src="./images/pk2.png" alt="" />
</div>
1
2
3
4
5
6
7
8
9
.box {
width: 250px;
height: 350px;
margin: 400px auto 0;
}
.box img {
width: 100%;
height: 100%;
}
  1. 利用定位把图片全部定在一个位置
1
2
3
4
5
6
7
8
.box img {
position: absolute;
top: 0;
left: 0;
}
.box {
position: relative;
}
  1. hover box 时旋转每张图片
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
.box img {
/* origin 默认在中心点,这里移到左上角 */
transform-origin: 0 0;
transition: all 1s;
}
.box:hover img:nth-child(1) {
transform: rotate(60deg);
}
.box:hover img:nth-child(2) {
transform: rotate(120deg);
}
.box:hover img:nth-child(3) {
transform: rotate(180deg);
}
.box:hover img:nth-child(4) {
transform: rotate(240deg);
}
.box:hover img:nth-child(5) {
transform: rotate(300deg);
}
.box:hover img:nth-child(6) {
transform: rotate(360deg);
}

puke

CSS 动画

animation

CSS 动画和变换的区别:

  • 动画不需要手动触发,是自动完成的
  • 变换只能从一个状态到另一个状态,而动画可以在多个状态之间转换

【案例】

CSS 补充

Emmet 语法

参照 Emmet 语法让你的编码更高效! 学习使用 Emmet 语法快速书写 HTML 和 CSS 代码

下面是一些使用 Emmet 语法的例子:

image-20230712113233439

image-20230712113159818

精灵图

CSS 精灵图:将各种小图片整合到一张图片上,然后使用 background-position 来展示图片的不同部分

优点:减少图片请求次数,减轻服务器压力,提高页面加载速度

例 拼姓名案例

  1. 假设有一张这样的精灵图,量出自己姓名首字母的大小和位置

image-20230724110201083

  1. 使用背景图+背景图定位来拼出一个姓名:
1
2
3
4
5
<div class="myname">
<div class="w"></div>
<div class="l"></div>
<div class="x"></div>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
.myname {
display: flex;
width: 500px;
height: 300px;
margin: 100px auto;
}
.w {
width: 142px;
height: 108px;
background: url(./images/abcd.jpg);
background-position: -111px -561px;
}
.l {
width: 106px;
height: 113px;
background: url(./images/abcd.jpg);
background-position: 0 -273px;
}
.x {
width: 107px;
height: 107px;
background: url(./images/abcd.jpg);
background-position: -252px -560px;
}

image-20230724112336455

字体图标

在网页中添加简单的、颜色单一的小图标,这些字体图标可以使用字体属性修改样式

优点:体积小、不失真、样式可修改

image/iconfont

css 雪碧图(精灵图)与字体图标的介绍以及对比

光标样式

cursor 属性可以更改鼠标经过某元素时的光标样式,它的属性值有:

  • default:箭头(默认)
  • pointer:小手形状
  • text:文本输入
  • not-allowed:禁止点击
  • wait:等待完成

cursor.gif

渐变背景

关于线性渐变的详细用法:CSS 渐变

一个线性渐变背景的的例子:

1
2
3
body {
background-image: linear-gradient(45deg,rgb(118, 201, 255),rgb(247, 255, 222));
}

渐变属性不能直接过渡,但可以给元素的 opacity 属性添加过渡

边框圆角

border-radius 属性用来设置元素的外边框为圆角。可以设置多个方位的属性值,属性值可以是 px、百分比形式的圆角半径

image-20230718105718748

记忆口诀:从左上角开始顺时针赋值,没值看对角

实现正圆头像

给方形容器设置边框圆角值为宽高的一半或 50%

1
2
3
4
5
6
.box {
width: 200px;
height: 200px;
background-color: pink;
border-radius: 50%; /* 或 border-radius: 100px; */
}

实现胶囊按钮

给长方形容器设置边框圆角属性值为容器高度的一半

1
2
3
4
5
6
.box2 {
width: 100px;
height: 40px;
background-color: pink;
border-radius: 20px;
}

盒子阴影

box-shadow 用来给容器添加阴影效果,让界面更生动:

1
2
3
4
5
6
.box:hover {
width: 234px;
height: 300px;
background-color: #fff;
box-shadow: 2px 15px 30px rgba(0, 0, 0, 0.1);
}

属性值书写顺序:X 轴偏移 Y 轴偏移 模糊半径 扩散半径 颜色 内/外阴影

  • X 轴偏移、Y 轴偏移必填
  • 扩散半径为 0、不填都表示和容器大小一致
  • 默认是外阴影,内阴影要加 inset

基线对齐

vertical-align 属性用来设置行内元素、行内块元素的垂直对齐方式。属性值:

  • baseline:基线对齐【默认】
  • middle:居中对齐【常用】
  • top:顶部对齐
  • bottom:底部对齐

解决图片底部空白间隙问题

image-20230725121911594

图片底部出现了空白间隙,这是由于 CSS 默认的图片和文字的基线对齐导致的,要解决这个问题,只需要给图片设置:

1
2
3
4
.box img {
/* 图片和文字底线对齐 */
vertical-align: bottom;
}

image-20230725122230918

1
2
3
4
.box img {
/* 图片和文字居中对齐 */
vertical-align: middle;
}

image-20230725122504885

实际上,我们也可以给放图片的盒子设置和图片大小一致的宽高,这样也不会有空白间隙

溢出隐藏

使用 overflow 属性可以改变内容超出元素尺寸时的处理方式

image-20230715154254363

image-20230715154344610

添加 overflow: hidden 后

image-20230715154407248

隐藏元素

overflow: hidden; 属性的用途有:

  • 隐藏超出元素部分的内容
  • 解决外边距塌陷的问题
  • 清除浮动

如果想要隐藏整个元素,就得使用下面的属性:

  • visibility: hidden:隐藏元素并保留空间

  • display: none:隐藏元素,不保留空间【常用】

例-hover 显示二维码

  1. 先搭建元素基本结构和初始化样式
1
2
3
4
5
<div class="box">
<span>来扫我呀</span>
<!-- 二维码放在盒子内部,才能在hover盒子时找到二维码这个元素设置样式 -->
<img src="./images/qr-code.png" alt="二维码" />
</div>
1
2
3
4
5
6
7
.box {
width: 100px;
height: 100px;
background-color: #999;
text-align: center;
line-height: 100px;
}
  1. 利用定位调整盒子位置和图片位置
1
2
3
4
5
6
7
8
9
10
11
12
/* 固定在屏幕右下方 */
.box {
position: fixed;
right: 50px;
bottom: 200px;
}
/* 定位在.box左侧 */
.box img {
position: absolute;
top: -20px;
left: -150px;
}

image-20230725114628635

  1. 将图片先隐藏起来,hover 时再显示就可以了
1
2
3
4
5
6
7
8
/* 隐藏图片 */
.box img {
display: none;
}
/* 鼠标经过.box 找到后代img设置样式 */
.box:hover img {
display: block;
}

hidden

例-给卡卡西添加遮罩

  1. 先搭建元素基本结构和初始化样式
1
2
3
4
5
<div class="box">
<a href="https://baike.baidu.com/item/旗木卡卡西/405593" target="_blank">
<img src="./images/卡卡西.jpg" alt="卡卡西" />
</a>
</div>
1
2
3
4
5
6
7
8
9
body {
background-color: #f5f5f5;
}
.box {
position: relative;
width: 500px;
height: 368px;
margin: 100px auto;
}
  1. 使用伪元素创建遮罩层,先隐藏起来,hover 时再显示
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/* 使用伪元素创建遮罩层并隐藏 */
.box a::after {
display: none;
position: absolute;
top: 0;
left: 0;
content: "";
width: 500px;
height: 368px;
/* 播放按钮 */
background: url(./images/arr.png) no-repeat center center;
/* 背景遮罩 */
background-color: rgba(0, 0, 0, 0.4);
}
/* 鼠标经过时再显示 */
.box a:hover::after {
display: block;
}

kakaxi-2

  • Title: CSS学习笔记
  • Author: Evan
  • Created at: 2023-08-02 22:36:55
  • Updated at: 2023-08-03 21:27:29
  • Link: https://blog.wyun521.cn/web-base/CSS学习笔记/
  • License: This work is licensed under CC BY-NC-SA 4.0.
 Comments