五、CSS布局方式及相关技术
布局:确定内容的大小和位置的算法(分块)
- 依据元素、容器、兄弟节点和内容等信息来计算。
三种布局方式:
-
常规流(normal flow):块级规则,行级规则,table表格布局,FlexBox排版上下文,Grid布局
- 根元素、浮动和绝对定位的元素会脱离常规流
- 其他元素都在常规流之内
- 常规流中的盒子,在某种排版上下文(描述盒子的排布方式)中参与布局
-
浮动:通过将元素从常规流中移动并使其向左或向右浮动,来实现网页中元素的位置控制。浮动可以使元素脱离常规流,并且允许其他元素环绕在其周围。如将文字环绕图片的效果。
-
绝对定位:可以盖在常规流上面,任意改变元素的位置而不对常规流产生影响。
5.1 盒模型 box-sizing
width,height,padding,border,margin
- content-box:
默认情况下指定width,height通常指content的。
-
width:
- 指定的是content的宽度
- 取值为长度、百分数、auto
- auto由浏览器根据经其他属性确定
- 百分数:相对于容器(当前元素所在的盒子)的content box宽度
-
height:
- 同上
- auto取值由内容计算得来
- 容器有指定的高度时,百分数才生效
-
padding:
padding-top,padding-right,padding-bottom,padding-left- 百分数:相对于容器的宽度
- 正方形;上下、左右;顺时针
-
border:
-
三种属性:
border-width,border-style,border-color -
四个方向
-
可组合搭配:
当四条边框颜色不同,宽高为0时:可以改变粗细、颜色、透明度设置各种各样的图形
-
-
margin:
- 取值可以是长度、百分数、auto
- 百分数:相对于容器的宽度
margin-left: auto;margin-right: auto;:水平居中- margin collapse:垂直方向上margin会合并,取两者的最大值
-
border-box:
宽和高包括
border,padding,content
overflow属性:控制内容溢出盒子的高的部分该怎么展示
- visible:默认,仍然展示出溢出的部分
- hidden:溢出的部分不限时
- scroll:滚动条
- auto:超出了就滚动
5.2 盒模型中常见的布局规则
5.2.1 常规流
行级与块级
-
盒子的摆放规则不同:
块级盒子不和其他盒子并列摆放
行级盒子和其他行级盒子一起放在一行或拆成多行
-
块级元素生成块级盒子
body,article,div,main,section,h1-6,p,ul,li等
display : block
-
行级元素生成行级盒子,内容分散在多个行盒中
span,em,strong,cite,code等
display : inline
-
display属性:block , inline
inline-block:本身是行级,可以放在行盒中;可以设置宽高;作为一个整体不会被拆散成多行(inline-block里面的元素都是行级,整体是块级,例如:图片和文字放在同一行)
none:排版时完全被忽略
行级排版上下文
-
Inline Formatting Context (IFC)
-
只包含行级盒子的容器会创建一个IFC
-
IFC内的排版规则
- 盒子在一行内水平摆放
- 一行放不下时,换行显示
- text-align决定一行内盒子的水平对齐
- vertical-align决定一个盒子在行内的垂直对齐
- 避开浮动(float)元素
-
例:
div为块级元素,但内部只包含行级盒子,则div创建的为行级上下文
<div> This is a paragraph of text with long word Honorificabilitudinitatibus. Here is an image <img src="https://assets.codepen.io/59477/cat.png" alt="cat"> And <em>Inline Block</em> </div> <style> div { width: 10em; //overflow-wrap: break-word; background: #411; } em { display: inline-block; width: 3em; background: #33c; } </style>若将
em的display: inline-block;注释掉,//overflow-wrap: break-word;去掉注释,则变为:
块级排版上下文
-
Block Formatting Context(BFC)
-
某些容器会创建一个BFC,容器:
- 根元素,即
<html> - 浮动、绝对定位、inline-block
- Flex子项和Gird子项
- overflow值不是visible的块盒
- display:flow-root;
- 根元素,即
-
BFC内的排版规则
-
盒子从上到下摆放
-
垂直margin合并
-
BFC内的盒子的margin不会与外面的合并
(所以,若不想让两个盒子的margin合并,则可以把这两个盒子分散在不同的BFC里面,例如,给一个元素嵌套一个div,将该div设置成
display:flow-root;overflow:hidden创建了一个BFC,与下面的盒子分属于两个不同的BFC,不会合并) -
BFC不会和浮动元素重叠
-
例:行级盒子(文本内容:匿名行盒)和块级盒子同处于一个父级span里面(但不允许一个父级里面既有行级又有块级)所以创建两个匿名块级盒子把两段文字包起来。
实际的渲染结果可能是这样的:
- 创建匿名块级盒子(盒子A),其中包含行内文本 "This is a text and"。
- 创建块级盒子(盒子B),作为
<div>元素的容器,包含块级元素<div>。 - 创建匿名块级盒子(盒子C),其中包含文本 "and other text."。
盒子A和盒子C是匿名的块级盒子,用于包裹行内文本部分,以确保同时包含行内和块级内容的正确排版。
<span>
This is a text and
<div>block</div>
and other text.
</span>
<style>
span {
line-height: 3;
border: 2px solid red;
background: coral;
}
div {
line-height: 1.5;
background: lime;
}
</style>
块级和行级布局只能实现一些简单的效果,没法实现更灵活的布局方式,所以提出了更新的排版上下文。
Flex Box(弹性盒子布局)
通过flex box(常用布局)的一些属性控制容器内的子元素:
-
可以控制子集盒子的:
-
摆放的流向(→(默认) ← ↑ ↓)
flex-direction:决定了弹性项目的排列方向。row(→)、column(↓)、row-reverse(水平反向)或column-reverse(垂直反向)。
-
摆放顺序
order:用于控制弹性项目的显示顺序,设置为1等数字,从小到大排。
-
是否允许拆行(换行)
-
水平和垂直方向的对齐
- 分为主轴
justify-content和侧轴align-items(align-items设置在容器上,默认为stretch)。 align-self:针对某个特定的子元素设定一个样式,覆盖了父容器的align-items。
- 分为主轴
-
盒子的宽度和高度
-
Flexibility:设置子项的弹性,当容器有剩余空间时,伸展;容器空间不足时,收缩。
-
flex-grow、flex-shrink和flex-basis:用于控制弹性项目的增长、收缩和基础大小。 -
flex:是flex-grow、flex-shrink和flex-basis的简写属性。flex : 1即flex-grow:1、flex-shrink:1、flex-basis:auto -
<div class="container"> <div class="a">A</div> <div class="b">B</div> <div class="c">C</div> </div> <style> .container { display: flex; border: 2px solid #966; } .a, .b, .c { text-align: center; padding: 1em; } .a { background: #fcc; } .b { background: #cfc; } .c { background: #ccf; } </style> -
将剩余空间按照2:1分给A和B
<div class="container"> <div class="a">A</div> <div class="b">B</div> <div class="c">C</div> </div> <style> .container { display: flex; border: 2px solid #c66; height: 100px; } .a, .b, .c { width: 100px; text-align: center; padding: 1em; } .a { flex-grow: 2; } .b { flex-grow: 1; } </style> -
页面长度不够400,需要压缩。A为刚性,不能压缩;B和C宽度不够了 进行压缩,分配相同的宽度。
<div class="container"> <div class="a">A</div> <div class="b">B</div> <div class="c">C</div> </div> <style> .container { display: flex; border: 2px solid #c66; height: 100px; } .a, .b, .c { width: 400px; text-align: center; padding: 1em; } .a { flex-shrink: 0; } </style>
-
-
Grid布局(网格布局)
CSS布局中最强大的。 文档上解释比较详细,用法多。
步骤:
-
网格容器:
display: grid;使元素生成一个块级的Gird容器。 -
网格行和列:使用
gird-template相关属性将容器划分为网格。- 使用属性
grid-template-rows和grid-template-columns来定义网格容器的行和列。可以使用像像素、百分比、自动调整和分数等单位。 - 例:
- 例:
1fr:一份,列:即B与C各占一份;行:D将剩下的占满
- 使用属性
-
网格线和网格区域:设置每一个子项占哪些行列
grid-row-start+grid-column-start+grid-row-end+grid-column-end=grid-area- 例:
-
例:
5.2.2 float 浮动
为了实现文字环绕的效果。
给<img>设置了float属性,<p>标签仍从<section>最开始排版,但绕开<img>。
<section>
<img src="https://p4.ssl.qhimg.com/t017aec0e7edc961740.jpg" width="300" alt="mojave" />
<p>莫哈韦沙漠不仅纬度较高,而且温度要稍微低些,是命名该公园的短叶丝兰——约书亚树的特殊栖息地。约书亚树以从茂密的森林到远远间隔的实例等各种形式出现。
</p>
</section>
<style>
img {
float: left;
}
p {
font-size: 20px;
line-height: 1.8;
}
</style>
5.2.3 绝对定位
position属性:
-
static:默认值,非定位元素,参与常规流的布局
-
relative:相对于自身原本位置偏移,不脱离文档流
-
absolute:绝对定位,将一个元素从其正常在文档流中的位置脱离出来(即常规流布局时当absolute元素不存在一样),相对最近的非static祖先元素定位:设置
top、right、bottom和left属性 -
fixed:相对于视口(viewpoint)绝对定位,也脱离常规流
-
absolute例:
没有其他已定位的祖先元素,.box 将相对于文档的初始包含块进行定位。初始包含块通常是浏览器窗口的可视区域。
<h1>页面标题</h1>
<div class="container">
<div class="box"></div>
<p>段落内容段落内容 1</p>
<p>段落内容段落内容 2</p>
<p>段落内容段落内容 3</p>
<p>段落内容段落内容 4</p>
</div>
<style>
.container {
background: lightblue;
}
.box {
position: absolute;
top: 0;
left: 0;
width: 100px;
height: 100px;
background: red;
}
</style>
- fixed例:
<nav>
<a href="#">首页</a>
<a href="#">导航1</a>
<a href="#">导航2</a>
</nav>
<main>
<section>1</section>
<section>2</section>
<section>3</section>
<section>4</section>
<section>5</section>
</main>
<a href="#" class="go-top">返回顶部</a>
<style>
nav {
position: fixed;
line-height: 3;
background: rgba(0, 0, 0, 0.3);
width: 100%;
}
.go-top {
position: fixed;
right: 1em;
bottom: 1em;
color: #fff;
}
nav a {
padding: 0 1em;
color: rgba(255, 255, 255, 0.7);
}
nav a:hover {
color: #fff;
}
body {
margin: 0;
font-size: 14px;
}
a {
color: #fff;
text-decoration: none;
}
section {
height: 50vh;
color: #fff;
text-align: center;
font-size: 5em;
line-height: 50vh;
}
section:nth-child(1) {
background: #F44336;
}
section:nth-child(2) {
background: #3F51B5;
}
section:nth-child(3) {
background: #FFC107;
}
section:nth-child(4) {
background: #607D8B;
}
section:nth-child(5) {
background: #4CAF50;
}
</style>
流的嵌套
绝对定位元素内部的元素是一个新的常规流;flex布局子项也是一个新的流,等等。
六、调试CSS
右键点击页面,选择检查,可以直接看如何实现的一些效果。
快捷键:Ctrl+Shift+I