> 本文由云+社区发表
本文将通过三个简单的实例,实际应用上篇文章的基础理论知识,展示下Flex布局是如何解决CSS布局问题。
# 一.垂直居中
这里同时用非flex布局和flex布局两种方式来实现,可以对比两种实现方式的差异。
## 1.1用margin实现垂直居中
实现方式:
父元素采用相对定位,子元素采用绝对定位,先将元素的定点定位到父元素的中心,再使用margin负值法,即子元素自身宽度、高度的一半,将其拉回到父元素的中心。
实现效果:
![img](https://ask.qcloudimg.com/draft/2221081/1kxlpp4epq.png?imageView2/2/w/1620)
附上完整代码:
```js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>垂直居中--normal</title>
<style type="text/css">
body {
margin: 0;
padding: 0;
}
.container {
width: 500px;
height: 300px;
margin: 80px;
border: 1px solid blue;
position: relative;
}
.item {
width: 300px;
height: 200px;
border: 1px solid red;
position: absolute;
left: 50%;
top: 50%;
margin-left: -150px;
margin-top: -100px;
}
</style>
</head>
<body>
<div class="container">
<div class="item"></div>
</div>
</body>
</html>
```
## 1.2用flex实现垂直居中
实现方式:
父元素启用flex布局(display:flex),同时设置主轴上居中对齐(justify-content:center)、交叉轴上居中对齐(align-items:center)。子元素不需要额外设置样式。
实现效果:同上
附上完整代码:
```js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>垂直居中--flex</title>
<style type="text/css">
body {
margin: 0;
padding: 0;
}
.container{
width:500px;
height:300px;
margin:80px;
border:1px solid blue;
display:flex;
justify-content: center;
align-items: center;
}
.item{
width:300px;
height:200px;
border:1px solid red;
}
</style>
</head>
<body>
<div class="container">
<div class="item"></div>
</div>
</body>
</html>
```
# 二.圣杯布局
## 2.1 普通方式实现圣杯布局
在我之前的文章[圣杯布局与双飞翼布局](https://cloud.tencent.com/developer/article/1351068)中详细介绍过如何实现一个圣杯布局:
(1)中间的三栏布局,这里采用margin负值法:两边两栏宽度固定,中间栏宽度自适应,左栏、右栏、中间栏向左浮动,左栏的margin-left设为-100%,中间栏的width设为100%,右栏的margin-left设为-右栏宽度。
(2)给container设置padding-left和padding-right属性,值分别为左栏、右栏的宽度;
(3)将左右两栏设置为相对定位,同时左栏的left值设为-左栏宽度,右栏的right设为-右栏宽度。
实现效果:
![img](https://ask.qcloudimg.com/draft/2221081/3mry0lpa2u.png?imageView2/2/w/1620)
实现代码:
```js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>圣杯布局</title>
<style type="text/css">
body {
margin: 0;
padding: 0;
}
header,
footer {
height: 100px;
width: 100%;
background-color: #bbbbbb;
}
.container {
height: 300px;
/* 圣杯布局 */
padding-left: 200px;
padding-right: 300px;
}
.container div{
float: left;
/* 圣杯布局 */
position:relative;
}
.left {
width: 200px;
height: 300px;
background-color: #DC698A;
margin-left: -100%;
/* 圣杯布局 */
left:-200px;
}
.middle {
width: 100%;
height: 300px;
background-color: #3EACDD;
}
.right {
width: 300px;
height: 300px;
background-color: #8CB08B;
margin-left: -300px;
/* 圣杯布局 */
right:-300px;
}
</style>
</head>
<body>
<header>头部</header>
<div class="container">
<div class="middle">中间栏:内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容</div>
<div class="left">左栏</div>
<div class="right">右栏</div>
</div>
<footer>底部</footer>
</body>
</html>
```
## 2.2用flex实现圣杯布局
实现方式:
(1)holyGrail启用flex布局,设置holyGrail中的header、container、footer在交叉轴上竖向排列(flex-direction:column;)
(2)container中的三栏布局:container启用flex布局,设置container中的middle、left、right在主轴上横向排列(flex-direction:row,默认值可以不设)。由于html中先写的middle,所以为了让left在最左边,要设置left的order为这三栏中最小的,即-1(其他两栏order为默认值0)
可以看出Flex布局的实现方式更加简单,也更加直观。
实现效果:同上
实现代码:
```js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>圣杯布局--flex</title>
<style type="text/css">
body {
margin: 0;
padding: 0;
}
.holyGrail{
display: flex;
flex-direction: column;
}
header,
footer {
height: 100px;
width: 100%;
background-color: #bbbbbb;
flex: 1; /*flex:1; === flex:1 1 auto;*/
}
.container {
height: 300px;
display: flex;
flex-direction: row;/*可不写,默认值*/
flex:1;/*需要可自动扩展*/
}
.left {
width: 200px;
height: 300px;
background-color: #DC698A;
order:-1;/*左边栏放到最左边*/
}
.middle {
width: 100%;
height: 300px;
background-color: #3EACDD;
flex:1;
}
.right {
width: 300px;
height: 300px;
background-color: #8CB08B;
}
</style>
</head>
<body class="holyGrail">
<header>头部</header>
<div class="container">
<div class="middle">中间栏:内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容</div>
<div class="left">左栏</div>
<div class="right">右栏</div>
</div>
<footer>底部</footer>
</body>
</html>
```
# 三.固定栏-可扩展栏页面布局
实现效果:
![img](https://ask.qcloudimg.com/draft/2221081/j2mg3uwrr3.gif)
实现代码:
```js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>flex</title>
<style type="text/css">
body {
margin: 0;
padding: 0;
}
.container {
width: 300px;
height: 200px;
border: 1px solid blue;
display: flex;
flex-direction: column;
}
.nav {
height: 50px;
background-color: grey;
display: flex;
flex-direction: row;
}
.nav-item {
min-width: 60px;
border: 1px solid orangered;
}
.main {
display: flex;
flex-direction: row;
flex: 1;
/*main区域需要自动扩展*/
}
.main-left {
width: 100px;
/*main中的left区域固定*/
background-color: #DC698A;
}
.main-right {
background-color: #3EACDD;
flex: 1;
/*main中的right区域需要自动扩展*/
}
</style>
<script src="http://code.jquery.com/jquery-3.1.1.min.js"></script>
</head>
<body>
<div class="container">
<div class="nav">
<div class="nav-item">nav1</div>
<div class="nav-item">nav2</div>
<div class="nav-item">nav3</div>
</div>
<div class="main">
<div class="main-left">固定栏:内容内容内容内容内容内容内容内容内容内容</div>
<div class="main-right">可扩展栏:内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容</div>
</div>
</div>
</body>
<script type="text/javascript">
(function run() {
$(".container").animate({ width: 500, height: 300 }, 1500,
() => {
$(".container").animate({ width: 300, height: 200 }, 1500, run)
}
)
}());
</script>
</html>
```
# 四.小结
本文主要提供了三个实例,来实际应用下flex的属性。通过对比其他的实现方式,可以看出使用Flex布局可以优雅地实现相同的CSS布局问题。如有问题,欢迎指正。
**此文已由作者授权腾讯云+社区发布**
**搜索关注公众号「云加社区」,第一时间获取技术干货,关注后回复1024 送你一份技术课程大礼包!**
有疑问加站长微信联系(非本文作者)