CSS——知识点补充(二)页面布局
前言
对于CSS来说,页面布局应该是其中最重要也是最难的一个知识点了,本篇文章将对页面布局部分的内容进行详细的描述,主要涉及盒子模型中各个属性的应用。需要注意的是由于行内元素的盒模型相对来说比块元素要简单,应用也比较少,所以文章主要讲述的还是块元素的盒模型。
一、文档流
网页是一个多层的结构,一层叠着一层,通过css我们可以分别为每一层来设置样式,作为用户来讲只能看到最顶上一层。这些层中,最底下的一层称为文档流,文档流是网页的基础,我们所创建的元素默认都是在文档流中进行排列。
我们可以看一下不同类型的元素在文档流中的表现如何:
(1)块元素
- 块元素会在页面中独占一行(自上向下垂直排列)
- 默认宽度是父元素的全部(会把父元素撑满)
- 默认高度是被内容撑开(子元素)
(2)行内元素
- 行内元素不会独占页面的一行,只占自身的大小
- 行内元素在页面中左向右水平排列,如果一行之中不能完全显示,则元素会换到第二行继续自左向右排列(书写习惯-行内元素的默认宽度和高度都是被内容撑开
<head>
<meta charset="UTF-8">
<title>文档流</title>
<style>
#root div:nth-of-type(odd){
background-color: skyblue;
}
#root div:nth-of-type(even){
background-color: yellowgreen;
}
#root2 span:nth-of-type(odd){
background-color: skyblue;
}
#root2 span:nth-of-type(even){
background-color: yellowgreen;
}
</style>
</head>
<body>
<div id="root">
<div>aa</div>
<div>bb</div>
<div>cc</div>
</div>
<div id="root2">
<span>aa</span>
<span>bb</span>
<span>cc</span>
</div>
</body>
二、盒子模型
盒子模型可以说是CSS布局中绕不开的一个关键的知识点了,CSS将页面中的所有元素都设置为了一个矩形的盒子,
将元素设置为矩形的盒子后,对页面的布局就变成将不同的盒子摆放到不同的位置上
每一个盒子都由一下几个部分组成:
- 内容区(content)
- 内边距(padding)
- 边框(border)
- 外边距(margin)
(一)内容区
内容区其实很好理解,就是我们定义的页面元素的内容,内容区的大小取决于width
和height
两个属性
<head>
<meta charset="UTF-8">
<title>内容区</title>
<style>
#root{
width: 200px;
height: 200px;
background-color: violet;
}
</style>
</head>
<body>
<div id="root"></div>
</body>
比如上面这个例子,我们div元素的内容区就是200px * 200px
(二)边框 Border
边框(border)可以理解为是内容的描边,边框属于盒子边缘,边框里边属于盒子内部,出了边框都是盒子的外部,边框的大小会影响到整个盒子的大小。
要设置边框,需要至少设置三个样式:
边框的宽度:border-width
边框的颜色:border-color
边框的样式:border-style
<head>
<meta charset="UTF-8">
<title>边框</title>
<style>
#root{
/* 设置内容区的大小 */
width: 20em;
height: 20em;
background-color: skyblue;
/* 设置边框 */
border-width: 10px;
border-color: tomato;
border-style: solid;
}
</style>
</head>
<body>
<div id="root"></div>
</body>
我们可以看到,我们实际的内容区宽是320px(默认1em=默认字体大小=16px),而因为我们加上了border-width
属性,所以上下左右四个方向都新增了10px的边框,此时元素的宽也变成了10 + 320 + 10 = 340px
。
默认的Border属性
虽然上面说要想设置边框,border-width
和border-color
这两个属性是必须要设置的,但实际上如果我们没有写的话,还是会有默认的值的,border-width
宽度是2.4px,边框颜色是黑色。
Border的border-width属性
border-width属性不仅仅可以同时设置四个方向的边框,还可以对每个方向进行分别设置:
值和边框方向的关系如下:
四个值:上 右 下 左
三个值:上 左右 下
两个值:上下 左右
一个值:上下左右
例如:
<style>
#root{
/* 设置内容区的大小 */
width: 20em;
height: 20em;
background-color: skyblue;
/* 设置边框 */
border-width: 10px 20px 30px 40px;
border-color: tomato;
border-style: solid;
}
</style>
<body>
<div id="root"></div>
</body>
Border的border-color属性
除了可以分别指定边框的长度以外,我们还可以分别指定边框的颜色,使用的规则和border-width
一致。
<head>
<meta charset="UTF-8">
<title>边框</title>
<style>
#root{
/* 设置内容区的大小 */
width: 20em;
height: 20em;
background-color: skyblue;
/* 设置边框 */
border-width: 10px 20px 30px 40px;
border-color: tomato green lightgray brown;
border-style: solid;
}
</style>
</head>
<body>
<div id="root"></div>
</body>
Border的border-style属性
border-style属性是使用边框所必须要指定的属性(因为其默认值是none),我们可以根据需要对边框设置实线(solid)、圆形虚线(dotted)、普通虚线(dashed)等多种样式。
<head>
<meta charset="UTF-8">
<title>边框</title>
<style>
#root{
/* 设置内容区的大小 */
width: 20em;
height: 20em;
background-color: skyblue;
/* 设置边框 */
border-width: 10px 20px 30px 40px;
border-color: tomato green lightgray brown;
border-style:dotted ;
}
</style>
</head>
<body>
<div id="root"></div>
</body>
Border的简写
除了通过分别指定边框的style
、width
、color
这种方式来定义边框之外,CSS还提供了一种定义边框的简写方式给我们:
<head>
<meta charset="UTF-8">
<title>边框</title>
<style>
#root{
/* 设置内容区的大小 */
width: 20em;
height: 20em;
background-color: skyblue;
border: dashed orange 10px;
}
</style>
</head>
<body>
<div id="root"></div>
</body>
(三)内边距 Padding
内容区和边框之间的距离是内边距,可以理解为是快递盒和商品之间并不会完全贴合,总会留有空间来塞一些塑料泡沫啥的,内边距一共有四个方向;
- padding-top
- padding-right
- padding-bottom
- padding-left
内边距的设置会影响到盒子的大小,且内容区的背景颜色会延伸到内边距上,一个盒子的可见框的大小由内容区 + 内边距 + 和边框
共同决定,所以在计算盒子大小时,需要将这三个区域加到一起计算
<head>
<meta charset="UTF-8">
<title>内边距</title>
<style>
#root{
width: 200px;
height: 200px;
background-color: skyblue;
/* 设置边框 */
border: orange solid 10px;
/* 设置内边距 */
padding-top: 10px;
padding-left: 20px;
padding-right: 30px;
padding-bottom: 40px;
}
</style>
</head>
<body>
<div id="root"></div>
</body>
我们可以看到,内容区的背景颜色延伸到了内边距上:
Padding的简写方式
Padding也提供了简写方式来方便我们使用,简写的规则和border-width
相似:
<head>
<meta charset="UTF-8">
<title>内边距</title>
<style>
#root{
width: 200px;
height: 200px;
background-color: skyblue;
/* 设置边框 */
border: orange solid 10px;
/* 设置内边距 */
padding:10px 20px 30px 40px;
}
</style>
</head>
<body>
<div id="root"></div>
</body>
(四)外边距 Margin
外边距可以理解为盒子和盒子之间的间距,外边距不会影响盒子可见框的大小,但是外边距会影响盒子的位置。
一共有四个方向的外边距,
- margin-top
上外边距,设置一个正值,元素会向下移动 - margin-right
默认情况下设置margin-right不会产生任何效果 - margin-bottom
下外边距,设置一个正值,其下边的元素会向下移动(也就是会挤开下方的元素) - margin-left
左外边距,设置一个正值,元素会向右移动
<head>
<meta charset="UTF-8">
<title>外边距</title>
<style>
#root{
width: 200px;
height: 200px;
background-color: skyblue;
/* 设置边框 */
border: orange solid 10px;
/* 设置外边距 */
margin-top: 20px;
margin-left: 20px;
margin-bottom: 40px;
}
#root2{
width: 200px;
height: 200px;
background-color: skyblue;
}
</style>
</head>
<body>
<div id="root"></div>
<div id="root2"></div>
</body>
margin也可以设置负值,如果是负值则元素会向相反的方向移动,元素在页面中是按照自左向右的顺序排列的,所以默认情况下如果我们设置的左和上外边距,则会移动元素自身;而设置下和右外边距,则会移动其他元素。
margin的简写属性
margin 可以同时设置四个方向的外边距,用法和padding一样,且margin会影响到盒子实际占用空间
<head>
<meta charset="UTF-8">
<title>外边距</title>
<style>
#root{
width: 200px;
height: 200px;
background-color: skyblue;
/* 设置边框 */
border: orange solid 10px;
/* 设置外边距 */
margin:20px 10px;
}
#root2{
width: 200px;
height: 200px;
background-color: skyblue;
}
</style>
</head>
<body>
<div id="root"></div>
<div id="root2"></div>
</body>
三、元素的水平方向布局
(一)子元素水平方向布局等式(不考虑溢出)
元素在其父元素中水平方向的位置由以下几个属性共同决定:
margin-left
、border-left
、padding-left
、width
、padding-right
、border-right
、margin-right
一个元素在其父元素中,水平布局必须要满足以下的等式
margin-left + border-left + padding-left + width + padding-right + border-right + margin-right
= 其父元素内容区的宽度
我们可以来看一下下面这个案例:
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>元素的水平布局</title>
<style>
#root{
height: 200px;
width: 800px;
background-color: skyblue;
border: red solid 10px;
}
#child{
height: 200px;
width: 300px;
background-color: orange;
margin-left: 300px;
}
</style>
</head>
<body>
<div id="root">
<div id="child"></div>
</div>
</body>
水平布局的等式必须满足,如果相加结果使等式不成立,则称为过渡约束,则等式会自动调整:
(1)如果这七个值中没有为 auto 的情况,则浏览器会自动调整margin-right
值以使等式满足
(2)如果我们设置了某个值为auto,则默认会使用这个值来进行调整,需要注意的是如果将两个外边距设置为auto,宽度为固定值,则会将外边距设置为相同的值,所以我们经常利用这个特点来使一个元素在其父元素中水平居中。
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>元素的水平布局</title>
<style>
#root{
height: 200px;
width: 800px;
background-color: skyblue;
border: red solid 10px;
}
#child{
height: 200px;
width: 300px;
background-color: orange;
margin-left: auto;
margin-right: auto;
}
</style>
</head>
<body>
<div id="root">
<div id="child"></div>
</div>
</body>
(二) overflow属性:处理子元素溢出
子元素是在父元素的内容区中排列的,如果子元素的大小超过了父元素,则子元素会从父元素中溢出。使用overflow属性来设置父元素如何处理溢出的子元素。
可选值 | 效果 |
---|---|
visible | 默认值子元素会从父元素中溢出,在父元素外部的位置显示 |
hidden | 溢出内容将会被裁剪不会显示 |
scroll | 生成两个滚动条,通过滚动条来查看完整的内容 |
auto | 根据需要生成滚动条 |
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>元素的水平布局</title>
<style>
#root{
height: 300px;
width: 300px;
background-color: skyblue;
border: red solid 10px;
overflow: auto;
}
#child{
height: 200px;
width: 500px;
background-color: orange;
}
</style>
</head>
<body>
<div id="root">
<div id="child"></div>
</div>
</body>
四、元素的垂直方向布局
(一)垂直外边距的重叠(折叠)
兄弟元素
- 相邻的垂直方向外边距会发生重叠现象
- 兄弟元素间的相邻孚直外边距会取两者之间的较大值(两者都是正值)
- 特殊情况
(1) 如果相邻的外边距一正一负,则取两者的和
(2)如果相邻的外边距都是负值,则取两者中绝对值较大的
兄弟元素之间的外边距的重叠,对于开发是有利的,所以我们不需要进行处理
父子元素
-父子元素间相邻外边距,子元素的会传递给父元素(上外边距)
-父子外边距的折叠会影响到页面的布局,必须要进行处理
<head>
<meta charset="UTF-8">
<title>元素的垂直布局</title>
<style>
#root1{
width: 150px;
height: 150px;
background-color: skyblue;
margin-bottom: 100px;
}
#root2{
width: 150px;
height: 150px;
background-color: orange;
margin-top: 100px;
}
</style>
</head>
<body>
<div id="root1"></div>
<div id="root2"></div>
</body>
五、行内元素的盒模型
行内元素的盒模型相对于块元素来说,要多了一些限制:
(1)行内元素不支持设置宽度和高度
(2)行内元素可以设置padding,但是垂直方向padding不会影响页面的布局
(3)行内元素可以设置border,垂直方向的border不会影响页面的布局
(4)行内元素可以设置margin,垂直方向的margin不会影响布局
<head>
<meta charset="UTF-8">
<title>行内元素的布局</title>
<style>
#root1{
height: 100px;
width: 100px;
background-color: skyblue;
margin: 100px 20px;
}
#root2{
height: 100px;
width: 100px;
background-color: orange;
margin: 10px 20px;
}
#root3{
height: 100px;
width: 100px;
background-color: pink;
margin: 10px 20px;
}
</style>
</head>
<body>
<span id="root1">aa</span>
<span id="root2">bb</span>
<br/>
<span id="root3">cc</span>
</body>