这是我参与「第四届青训营」笔记创作活动的的第4天。
常规流 Normal Flow
在没有用任何CSS样式来改变网页布局,正常情况下网页会排版再一个常规流布局之中。
- 根元素、浮动和绝对定位的元素会脱离常规流
- 其它元素都在常规流之内(in-flow)
- 常规流中的盒子,在某种排版上下文中参与布局
块级 vs. 行级
| 块级元素 | 行级元素 |
|---|---|
| 生成块级盒子 | 生成行级盒子或内容分散在多个行盒 (line box) 中 |
| body、article、div、main、section、h1-6、p、ul、li 等 | span、em、strong、cite、code 等 |
| display: block | display: inline |
| 不和其它盒子并列摆放 | 和其它行级盒子一起放在一行或拆开成多行 |
| 适用所有的盒模型属性 | 盒模型中的width、height不适用 |
display 属性
| block | 块级盒子 |
|---|---|
| inline | 行级盒子 |
| inline-block | 本身是行级,可以放在行盒中;可以设置宽高;作为一个整体不会被拆散成多行 |
| none | 排版时完全被忽略 |
IFC(行级排版上下文)
- Inline Formatting Context (IFC)
- 只包含行级盒子的容器会创建一个IFC
- IFC 内的排版规则
- 盒子在一行内水平摆放
- 一行放不下时,换行显示
- text-align 决定一行内盒子的水平对齐
- vertical-align 决定一个盒子在行内的垂直对齐
- 避开浮动(float)元素,float元素会优先排列
例子:多行文本垂直居中 当一个块要在环境中水平居中时,设置其为inline/inline-block则会在外层产生IFC,通过text-align则可以使其水平居中,然后设置父级元素的"行高等于盒子的高",即可使其垂直居中。
<style>
.text_container {
text-align: center;
width: 100%;
height: 300px;
background-color: aquamarine;
line-height: 300px;
}
p {
display: inline-block;
background-color: antiquewhite;
}
</style>
<body>
<div class="text_container">
<p>
东风夜放花千树,更吹落,星如雨。宝马雕车香满路。凤箫声动,玉壶光转,一夜鱼龙舞。蛾儿雪柳黄金缕,笑语盈盈暗香去。
<strong>众里寻他千百度,蓦然回首,那人却在,灯火阑珊处。</strong>
</p>
</div>
</body>
或 给父元素设置display:table-cell; 和vertical-align: middle;
.text_container {
text-align: center;
width: 100%;
height: 63px;
background-color: aquamarine;
/* line-height: 63px; */
display: table-cell;
vertical-align: middle;
}
注意:vertical-align属性只对行内元素有效,对块内元素无效!
BFC(块级排版上下文)
- Block Formatting Context (BFC)
- 某些容器会创建一个BFC
- 根元素
- 浮动、绝对定位、inline-block
- Flex子项和Grid子项
- overflow 值不是 visible 的块盒
- display: flow-root;
BFC 内的排版规则
- 盒子从上到下摆放
- 垂直 margin 合并
- BFC 内盒子的 margin 不会与外面的合并
- BFC 不会和浮动元素重叠
例子:解决高度塌陷的问题(inline-block可以设置宽高)
<style>
.box {
float: left;
width: 180px;
height: 180px;
background: cornflowerblue;
margin: 60px;
}
.outer_box {
display: inline-block;
background: lightblue;
}
</style>
<body>
<div class="outer_box">
<div class="box">moly</div>
<div class="box">edwin</div>
</div>
</body>
父级盒子加display: inline-block;前:
后:
FFC(弹性格式化上下文)
当 display 的值为 flex 或 inline-flex 时,将生成弹性容器(Flex Containers), 一个弹性容器为其内容建立了一个新的弹性格式化上下文环境(FFC)
FFC布局规则
- 设置为
flex的容器被渲染为一个块级元素。 - 设置为
inline-flex的容器被渲染为一个行内元素。 - 弹性容器中的每一个子元素都是弹性项目。它可以控制子级盒子的:
- 摆放的流向 ( → ← ↑ ↓ )
- 摆放顺序
- 盒子宽度和高度
- 水平和垂直方向的对齐
- 是否允许折行
⚠️注意:FFC布局中,float、clear、vertical-align属性不会生效。 Flex 布局是轴线布局,只能指定"项目"针对轴线的位置,可以看作是一维布局。
FFC应用场景
(1)装填子弹
<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>
<body>
<div class="container">
<div class="a">A</div>
<div class="b">B</div>
<div class="c">C</div>
</div>
</body>
(2)flex-grow
<style>
.container {
display: flex;
}
.a,
.b,
.c {
width: 100px;
}
.a {
background: #fcc;
flex-grow: 2;
}
.b {
background: #cfc;
flex-grow: 1;
}
.c {
background: #ccf;
}
</style>
<body>
<div class="container">
<div class="a">A</div>
<div class="b">B</div>
<div class="c">C</div>
</div>
</body>
(3)flex-shrink
<style>
.container {
display: flex;
}
.a,
.b,
.c {
width: 400px;
}
.a {
flex-shrink: 0;
background: #fcc;
}
.b {
background: #cfc;
}
.c {
background: #ccf;
}
</style>
<body>
<div class="container">
<div class="a">A</div>
<div class="b">B</div>
<div class="c">C</div>
</div>
</body>
其他属性:
- flex-direction
- justify-content
- align-items
- order
- Flexibility
flex简写
| flex: 1 | flex-grow: 1 |
|---|---|
| flex: 100px | flex-basis: 100px |
| flex: 2 1 | flex-grow: 2; flex-shrink: 1 |
| flex: 1 100px | flex-grow: 1; flex-basis: 100px |
| flex: 2 0 100px | flex-grow: 2; flex-shrink: 0; flex-basis: 100px |
| flex: auto | flex: 1 1 auto |
| flex: none | flex: 0 0 auto |
GFC(栅格格式化上下文)
GFC布局规则
display: grid或display: inline-grid使元素生成一个块级的 Grid 容器- 使用 grid-template 相关属性将容器划分为网格
- 设置每一个子项占哪些行/列
GFC应用场景
例1:划分网格
<style>
.a {
background: orchid;
}
.b {
background: orange;
}
.c {
background: blue;
}
.d {
background: lightcoral;
}
.e {
background-color: lightgreen;
}
.box {
border-radius: 5px;
margin: 5px;
}
.wrapper {
display: grid;
grid-template-columns: 100px 100px 200px;
grid-template-rows: 100px 100px;
height: 300px;
width: 500px;
border: black solid 1px;
}
</style>
<body>
<div class="wrapper">
<div class="box a">A</div>
<div class="box b">B</div>
<div class="box c">C</div>
<div class="box d">D</div>
<div class="box e">E</div>
</div>
</body>
grid-template-columns: 30% 30% auto;
grid-template-rows: 100px auto
grid-template-columns: 100px 1fr 1fr;
grid-template-rows: 100px 1fr