权重叠加

当后代选择器中出现多种选择器时,需要计算权重,计算方式我们可以把优先级拿二进制进行类比:

权重等级 选择器
0,0,0,0 继承性或者 *
0,0,0,1 标签选择器
0,0,1,0 类选择器 伪类选择器
0,1,0,0 ID选择器
1,0,0,0 行内style
无穷大 !important

以下的这种计算方式会出现累加,但是没有进位。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<head>
<style>
/* 权重0,0,0,1+0,0,0,1=0,0,0,2 */
ul li {
color: green;
}
/* 权重0,0,0,1 */
li {
color: red;
}
</style>
</head>

<body>
<ul>
<li>我是绿色</li>
</ul>
</body>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<head>
<style>
/* 权重0,0,0,1+0,0,0,1=0,0,0,2 */
ul li {
color: green;
}
/* 权重0,0,0,1 */
li {
color: red;
}
/* 权重0,0,1,0+0,0,0,1=0,0,1,1 */
.nav li {
color: blue;
}
</style>
</head>

<body>
<ul class='nav'>
<li>我是蓝色</li>
</ul>
</body>

所以,我们使用css实际操作时应该格外注意权重的问题:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<head>
<style>
/* 权重0,0,1,1 */
.nav li {
color: green;
}
/* 权重0,0,1,0 */
.blue {
color: blue;
font-weight: 700;
}
</style>
</head>

<body>
<ul class="nav">
<li class="blue">我加粗了,但为什么我还是绿色?</li>
<li>我是绿色</li>
<li>我是绿色</li>
</ul>
</body>

我们可以使用同等级权重的选择器累加权重,达到覆盖的效果:

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
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
/* 权重0,0,1,1 */
.nav li {
color: green;
}
/* 权重0,0,2,0 */
.nav .blue {
color: blue;
font-weight: 700;
}
</style>
</head>

<body>
<ul class="nav">
<li class="blue">我是加粗的蓝色</li>
<li>我是绿色</li>
<li>我是绿色</li>
</ul>
</body>

盒子模型

网页布局的过程:

网页的元素基本都为Box,先准备好相关的元素,利用CSS设计好样式,摆放到相应的位置,然后往盒子里装内容。

盒子模型就是一个矩形盒子,封装HTML元素,包括边框,内外边距和实际内容。

盒子组成

盒子模型的基本组成有:border(边框)、content(内容)、padding(内边距)、margin(外边距)。

边框

border可以设置元素的边框,包括边框宽度,边框样式和边框颜色。

1
border: border-width border-style border-color

边框粗细:一般情况用px作为单位。

边框样式:参数:none、hidden、dotted(点)、dashed(虚线)、solid(实心,最常用)、double(双线)、groove(3D凹槽)、ridge(菱形)、inset(3D凹边)、outset(3D凸边)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<head>
<style>
div {
text-align: center;
line-height: 100px;
width: 150px;
height: 100px;
border: 2px solid pink;
}
</style>
</head>

<body>
<div>这是一个盒子</div>
</body>
这是一个盒子

当然,边框允许分开写,分别使用right,left,top,bottom定义四个边:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<head>
<style>
div {
text-align: center;
line-height: 60px;
width: 150px;
height: 60px;
border-top: 2px solid pink;
border-bottom: 2px solid skyblue;
}
</style>
</head>

<body>
<div>这是一个盒子</div>
</body>
这是一个盒子

表格边框

对于表格,我们可以使用html语法加边框,不过边框比较生硬,学习了css后我们可以使用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
<head>
<style>
table,
td {
/* 合并相邻的边框 */
border-collapse: collapse;
border: 3px solid skyblue;
}
</style>
</head>

<body>
<table>
<tr>
<td>第一个单元格</td>
<td>第二个单元格</td>
<td>第三个单元格</td>
</tr>
<tr>
<td>第四个单元格</td>
<td>第五个单元格</td>
<td>第六个单元格</td>
</tr>
</table>
</body>
第一个单元格 第二个单元格 第三个单元格
第四个单元格 第五个单元格 第六个单元格

注意,边框会影响盒子的实际大小。盒子宽高相同的情况下,边框宽度越大,盒子越大。

内边距

padding用于设置内边距,即边框和内容之间的距离,分开有padding-left、padding-right、padding-top、padding-bottom四个属性,合并起来有padding属性。

padding属性也会增加盒子的大小。

我们如果不设置内边距的话,盒子的文字默认是顶着左上角的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<head>
<style>
div {
width: 200px;
height: 100px;
border: 5px solid red;
background-color: pink;
}
</style>
</head>

<body>
<div>这是一个盒子,我要在盒子里打一些文字</div>
</body>
这是一个盒子,我要在盒子里打一些文字

当我们设置好内边距后,盒子内容会和边框产生距离:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<head>
<style>
div {
width: 200px;
height: 100px;
border: 5px solid red;
background-color: pink;
padding: 5px;
}
</style>
</head>

<body>
<div>这是一个盒子,我要在盒子里打一些文字</div>
</body>
这是一个盒子,我要在盒子里打一些文字

padding复合属性中,只用一个值代表上下左右都设置内边距;用两个值时,第一个值代表上下内边距、第二个值代表左右内边距;用三个值时,第一个为上,第二个为左右,第三个为下;如果四个都使用,那么四个属性值分别代表上右下左。

外边距

属性:margin,用于设置外边距,控制盒子和盒子之间的距离。

分开写也包含right、left、top、bottom四个属性。

margin简写的方式和padding的方式一致。

盒子水平居中

需要满足两个条件:盒子必须指定了宽度,左右外边距都设为auto。

常见的三种写法(auto为自适应):

1
2
3
margin-left: auto; margin-right: auto;
margin: auto;
margin: 0 auto;

第三种写法最为常见。

外边距合并

①相邻块元素垂直外边距合并:

当上下两个相邻的块元素相遇,上面的块元素有下外边距margin-bottom,下面的块元素有上外边距margin-top,最终外边距舍弃较小的值,只保留较大的值。

②嵌套块元素垂直外边距塌陷:

对于两个嵌套关系的块元素,父元素有上边距子元素也有上边距,那么父元素会往下塌陷较大的外边距值。

解决方案:为父元素定义上边框,或者为父元素定义上内边距,或者为父元素添加overflow: hidden。

清除内外边距

网页元素很多都带有默认的内外边距,不同的浏览器默认的也不一致,所以我们布局前需要清除网页元素的内外边距:

1
2
3
4
* {
margin: 0;
padding: 0;
}

行内元素为了照顾兼容性,通常只设置左右内外边距,不设置上下内外边距,如果必须设置需要转换为块级或者行内块元素。

三个实例

实例3:新浪导航栏

样式预览:

代码:

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
<!DOCTYPE html>
<html lang="zh-CN">

<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>新浪导航栏</title>
<style>
#main {
border-top: 3px solid #ff8500;
border-bottom: 1px solid #edeef0;
width: 100%;
height: 41px;
}
#main a {
display: inline-block;
color: #4c4c4c;
height: 41px;
line-height: 41px;
font-size: 12px;
text-decoration: none;
padding: 0 20px;
}
a:hover {
background-color: #eee;
}
</style>
</head>

<body>
<div id="main">
<a href="">设为首页</a>
<a href="">手机新浪网</a>
<a href="">移动客户端</a>
<a href="">博客</a>
<a href="">微博</a>
<a href="">关注我</a>
</div>
</body>

</html>

注意,如果盒子本身没有指定宽高,那么padding属性不会撑开盒子大小。

实例4:产品模块

样式预览:

代码:

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
<!DOCTYPE html>
<html lang="zh-CN">

<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>产品模块</title>
<style>
.box {
width: 312px;
height: 460px;
border: 1px rgb(230, 230, 230) solid;
margin: 0 auto;
}
.name {
text-align: center;
font-size: 20px;
margin-bottom: 0;
}
.feature {
color: rgb(172, 172, 172);
text-align: center;
font-size: 16px;
margin-top: 5px;
}
.info {
text-align: center;
margin: 25px 0;
}
#now {
color: rgb(255, 140, 0);
font-weight: bold;
}
#past {
color: rgb(153, 153, 153);
text-decoration: line-through;
}
</style>
</head>

<body>
<div class="box">
<img src="1.webp" alt="">
<p class="name">Redmi Buds 3</p>
<p class="feature">轻巧半入耳丨通话降噪丨20小时长续航</p>
<div class="info"><span id="now">159元 </span><span id="past">199元</span></div>
</div>
</body>

</html>

注意标签的语义,在合理的地方用合理的标签,比如标题用h,文字段落用p等等。

实例5:快报

样式预览:

代码:

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="zh-CN">

<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>快报</title>
<style>
.box {
border: 1px solid rgb(186, 186, 186);
width: 255px;
height: 158px;
margin: 0 auto;
}
.content {
color: gray;
font-size: 14px;
padding: 5px 0;
height: 120px;
}
#name {
border-bottom: 1px solid rgb(205, 205, 205);
margin: 5px 0;
font-size: 15.5px;
color: rgb(81, 81, 81);
height: 27px;
padding-left: 15px;
}
p {
margin: 6px auto;
padding-left: 5px;
}
</style>
</head>

<body>
<div class="box">
<div id='name'>品优购快报</div>
<div class="content">
<p>【特惠】爆款耳机5折秒!</p>
<p>【特惠】母亲节,健康好礼低至5折!</p>
<p>【特惠】9.9元洗100张照片!</p>
<p>【特惠】长虹智能空调立省1000!</p>
</div>
</div>
</body>

</html>

盒子美化

圆角盒子

属性:border-radius

属性值为圆角的长度,数值更大越接近于圆。

这个属性后可跟四个值,不过不常用也不美观。分开写有:

border-top-right-radius
border-top-left-radius
border-bottom-right-radius
border-bottom-left-radius

原理为圆和边框交集形成圆角。

矩形我们让圆角值为高度的一半能有椭圆按钮的效果。

盒子阴影

属性:box-shadow

属性值:

1
box-shadow: h-shadow v-shadow blur spread color inset;
描述
h-shadow 必需,水平阴影的位置,可为负值
v-shadow 必需,垂直阴影的位置,可为负值
blur 可选,模糊距离
spread 可选,阴影尺寸
color 可选,阴影颜色
inset 可选,改为内部阴影

阴影不占用边距等,只属于装饰。

文字阴影

属性:text-shadow

属性值:

1
text-shadow: h-shadow v-shadow blur color;

CSS浮动

网页布局的本质:css摆放盒子。

css提供了三种传统的布局方式(如何排列盒子顺序):普通流(标准流、文档流) 、浮动、定位。

标准流就是标签按照规定好默认方式排列:块元素独占一行从上向下、行内元素从左到右排列,遇到父元素边缘自动换行、行内块元素……标准流是最基本的布局方式。

实际开发中一个页面基本都包含了三种布局方式。

为什么需要浮动?

如何让多个div元素放在一行?

可以用行内块元素,但是之间会有空白缝隙,不好控制。

如何实现盒子的左右对齐?

以上问题用标准流很难达到效果,这里就可以使用浮动完成布局。

浮动最典型的应用:多个块元素一行内排列显示

1
float: left;

float属性用于创建浮动框,将其移动到一边,直到左边缘或者右边缘触及包含块或者另一个浮动框边缘。

属性值:none、left、right

浮动特性

1.浮动元素脱离标准流(脱标),不再保留原先的位置。

2.浮动元素会一行内显示而且顶部对齐。

3.浮动的元素具有行内块元素的特性,如果行内元素设置了浮动,那么不需要转换为块级或者行内块元素就可以直接设置高度和宽度。

浮动布局

为了约束浮动元素的位置,在网页布局上的策略是:先用标准流的父元素排列上下位置,之后内部子元素采取浮动排列左右位置,符合网页布局的第一准则。

布局案例

小米主页banner布局:

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
<!DOCTYPE html>
<html lang="zh-CN">

<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box {
width: 1200px;
height: 460px;
margin: 0 auto;
}
.left {
width: 230px;
height: 460px;
background-color: pink;
float: left;
}
.right {
width: 970px;
height: 460px;
background-color: skyblue;
float: right;
}
</style>
</head>

<body>
<div class="box">
<div class="left"></div>
<div class="right"></div>
</div>
</body>

</html>

实例布局:

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
<!DOCTYPE html>
<html lang="zh-CN">

<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.box li {
list-style: none;
width: 296px;
height: 285px;
background-color: skyblue;
margin-right: 14px;
float: left;
}
.box {
width: 1226px;
height: 285px;
background-color: pink;
margin: 0 auto;
}
#last {
margin-right: 0;
}
</style>
</head>

<body>
<ul class="box">
<li></li>
<li></li>
<li></li>
<li id="last"></li>
</ul>
</body>

</html>

组合布局:

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
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>浮动布局</title>
<style>
.box {
width: 1226px;
height: 615px;
background-color: pink;
margin: 0 auto;
}

.left {
float: left;
width: 234px;
height: 615px;
background-color: purple;
}

.right {
float: right;
width: 992px;
height: 615px;
background-color: skyblue;
}
.right>div {
margin-left: 14px;
margin-bottom: 14px;
float: left;
width: 234px;
height: 300px;
background-color: pink;
}
</style>
</head>

<body>
<div class="box">
<div class="left"></div>
<div class="right">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
</div>
</div>
</body>

</html>

网页布局

从上往下分为:top、banner、main、footer。

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
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>浮动布局</title>
<style>
* {
margin: 0;
padding: 0;
}

.top {
height: 50px;
background-color: gray;
}

.banner {
width: 980px;
height: 150px;
background-color: gray;
margin: 10px auto;
}

li {
list-style: none;
}

.box {
width: 980px;
margin: 0 auto;
height: 300px;
background-color: pink;
}

.box li {
width: 237px;
height: 300px;
background-color: gray;
float: left;
margin-right: 10px;
}

.box .last {
margin-right: 0;
}

.footer {
height: 200px;
background-color: gray;
margin-top: 10px;
}
</style>
</head>

<body>
<div class="top">top</div>
<div class="banner">banner</div>
<div class="box">
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li class="last">4</li>
</ul>
</div>
<div class="footer">footer</div>
</body>

</html>

写通栏时不需要设置宽度,默认和浏览器一样宽。

注意点

在网页布局时,先用标准流父元素排列上下位置,然后内部子元素采取浮动排列左右位置。

当一个盒子里有多个子盒子,如果一个盒子浮动了,其他兄弟盒子也应该浮动,要不然会出问题。

浮动盒子会影响后面的兄弟盒子标准流,不会影响前面的标准流。

取消浮动

当父盒子高度不确定时,应该让子盒子撑开父盒子,有多少子盒子那么父盒子就该有多高。

因为浮动元素会脱标,父盒子没有高度就为0,不会被撑开盒子。