1、相关知识
1、普通流(常规流)
文档流(流式布局)分为 普通流、定位流、浮动流,不同流内的块级元素和行内元素的布局方式不同,布局方式用 FC(格式化上下文,含有 块级格式化上下文、内联格式化上下文、层叠格式化上下文、灵活格式化上下文等)来命名;
普通流中的布局规则默认为块级盒子从上到下,垂直排列;内联盒子从左到右,水平排列等;(书写模式(writing-mode)会对流布局产生影响;
2、position
属性有:
- static:默认值,元素依然按照 普通流 的定位规则定位;
- relative
- absolute
- sticky
- fixed
使用 position 会脱离常规流,成为定位流,并有其自己的定位规则;
3、float
属性有:
- left
- right
- none
- inherit
使用 float 会脱离常规流,成为浮动流,并有其自己的定位规则;
4、table
使用 HTML 标签来布局;
<table>
<tr>
<th></th>
<th></th>
</tr>
<tr>
<td></td>
<td></td>
</tr>
</table>
5、flex
2009 年 W3C 提供的方案,注意只有 IE 10+ 支持 flex;
重要的概念:flex 容器,flex 项目,主轴,交叉轴;
设置某个元素的属性 display: flex;
,此元素就成了 flex 容器,flex 容器内的元素是 flex 项目;
-
flex 容器的属性:
- flex-direction
- flex-wrap
- flex-flow
- justify-content
- align-items
- align-content
-
flex 项目的属性
- flex (flex-grow、flex-shrink、flex-basis)
- order
- align-self
6、grid
二维布局方式,相对于使用 HTML 结构实现的 table 布局,grid 布局都是在 CSS 中完成的;
重要的概念:grid 容器、grid 项目、行、列、单元格、网格线;
设置某个元素的属性 display: grid;
,此元素就成了 grid 容器,grid 容器的直接子元素就是 grid 项目;
-
grid 容器的属性
- grid-template-columns
- grid-template-rows
- gap(column-gap、row-gap)
- palce-items(justify-items、align-items)
- place-content(justify-content、align-content)
- grid-template-areas
- grid-auto-flow
- grid-auto-columns、grid-auto-rows
-
grid 项目的属性
-
grid-column-start、grid-column-end
grid-row-start、grid-row-end
grid-column
grid-row
-
grid-area
-
justify-self、align-self
place-self
-
2、常见布局效果
1、水平居中
-
对于子元素为行内元素,直接在父元素上加上
text-align:center;
-
对于子元素为块级元素或行内块级元素,直接在子元素上加上
margin:0 auto;
当子元素设置了绝对定位时
position:absolute;
, 需要在左右加上相等的定位距离left:0;right:0;
才能使用margin:0 auto;
为什么
margin: 0 auto;
会居中,见: www.cnblogs.com/sunhang32/p… -
使用定位
position:absolute;
+ 父元素宽度的 50% 的偏移left:50%;
+ 回退子元素宽度的 50%transform:translateX(50%);
-
使用定位
position:absolute;
+ 父元素宽度的 50% 的偏移left:50%;
+ 回退子元素宽度的 50%margin-left:-子元素宽度的一半;
水平居中时采用
margin-left:-子元素宽度的一半;
和transform: translateX(-50%);
两个方案的底层原理有什么不同:margin 会占据空间,transform 是移动,并不会占据原来的空间;补充一个知识点
margin: 50%;
是相对于父元素的百分比,transform: translate(50%, 50%);
是相对于元素本身的百分比; -
使用 flex 布局或 grid 布局;
2、垂直居中
-
对于单行文本,可以设置
line-height:父元素高度;
来达到垂直居中的目的; -
对于行内块级元素,可以通过增加高度为 100% 的伪元素,并增加
vertical-align:middle;
属性来改变父元素基线的位置;然后子元素通过vertical-align:middle;
达到垂直居中的目的;<!DOCTYPE html> <html lang="en"> <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> * { padding: 0; margin: 0; } .parent { width: 100px; height: 100px; border: 1px solid black; } .parent::after { content: ''; display: inline-block; height:100%; vertical-align:middle; } /* 行内块级元素*/ .child { display: inline-block; width: 50px; height: 50px; vertical-align:middle; /* 尝试注释这行代码 */ background-color: green; } /* 行内元素*/ .child1 { display: inline; background-color: red; } </style> </head> <body> <div class="parent"> <div class="child"></div> <div class="child1">ss1</div> </div> </body> </html>
child 元素不加
vertical-align:middle;
:child 元素加
vertical-align:middle;
: -
通过设置父元素为
display:table;
,子元素为display:table-cell;
,并通过vertical-align:middle;
来将子元素垂直居中; -
使用 flex 布局或 grid 布局;
2、两列布局
左边定宽,右边自适应
利用 float: left;
和 overflow: hidden;
实现;
.wrapper {
width: 50vw;
height: 100vh;
background-color: grey;
}
.left {
width: 100px;
background-color: red;
float: left;
}
.right {
background-color: green;
overflow: hidden;
zoom: 1; /*兼容 ie 浏览器*/
}
利用 flex 布局实现:
.wrapper {
width: 50vw;
height: 100vh;
display: flex;
}
.left {
width: 100px;
}
.right {
flex: 1;
}
利用 grid 布局实现:
.wrapper {
width: 50vw;
height: 100vh;
display: grid;
grid-template-columns: 100px auto;
/*或者:grid-template-columns: 100px 1fr*/
}
3、三列布局
左右列固定,中间列自适应,要求中间的 HTML 结构先解析;
注意 HTML 结构,这样使得 center 会优先加载:
<div class="wrapper">
<div class="center">content</div>
<div class="left">left</div>
<div class="right">right</div>
</div>
1)、flex 布局实现
.wrapper {
display: flex;
}
.center {
flex: 1;
background-color: yellow;
order: 1;
}
.left {
width: 100px;
/* flex: 1; */
background-color: red;
}
.right {
width: 100px;
background-color: green;
order: 2;
}
2)、grid 布局实现
.wrapper {
display: grid;
grid-template-columns: 100px 1fr 100px;
grid-auto-flow: row dense;
}
.center {
grid-column-start: 2;
background-color: yellow;
}
.left {
background-color: red;
}
.right {
background-color: green;
}
3)、圣杯布局
利用 float 将三列排到同一行,
再利用负的 margin 将 left 和 right 移动到 center 的两边;
最后增加 wrapper 的 padding,并用相对定位将 left 和 right 定位到 center 的 两边;
.wrapper {
padding: 0 100px;
}
.center {
width: 100%;
float: left;
background-color: yellow;
}
.left {
width: 100px;
float: left;
margin-left: -100%;
position: relative;
left: -100px;
background-color: red;
}
.right {
width: 100px;
float: left;
margin-left: -100px;
position: relative;
left: 100px;
background-color: green;
}
4)、双飞翼布局
利用 float 将三列排到同一行,
再利用负的 margin 将 left 和 right 移动到 center 的两边;
再在 center 中新增一个 div ,并设置其 margin: 0 100px;
给 left 和 right 留下宽度;
.wrapper {
min-width: 400px; /*需要有一个最小宽度*/
}
.center {
width: 100%;
float: left;
background-color: yellow;
}
.center > div {
margin: 0 100px; /*在 center 中增加了一个 div,并设置左右 margin 为 left 和 right 的宽度*/
}
.left {
width: 100px;
float: left;
margin-left: -100%;
background-color: red;
}
.right {
width: 100px;
float: left;
margin-left: -100px;
background-color: green;
}
参考资料: