1.页面布局概述
网页布局方式有很多,各有各的特点:
- 传统的 DIV+CSS+float(浮动) 布局方式,适用于PC端。
- 自适应布局方式,要开发多套页面,服务器根据不同的客户端返回不同的页面。
- 响应式布局方式,开发一套页面,根据媒体查询返回的结果,跳转布局以适用不同的客户端。
- 多列布局方式,类似报纸排版的样式。
- 弹性布局,适用与PC端与移动端。
- … …
注意:本课程中只讲解弹性布局!
2.弹性布局(弹性盒子)
一个元素的display属性值设置为flex,那么这个元素中的子元素,就会遵循弹性布局的规则。
display:flex /*flex是flexible box的缩写*/
此时,这个元素就可以称为是一个弹性布局容器(弹性容器),它内部的子元素,将只按照弹性布局的规则来排列和对齐,以前的float、clear、块状与内联、vertical-align属性都不能用了。
2.1.重要概念:主轴与侧轴
弹性布局中的一个重要概念:主轴与侧轴:
弹性盒子中默认存在两根轴,一个是水平方向的主轴,一个是垂直方向的侧轴。
注意点:
- 主轴的开始位置叫做 main start、 结束位置叫做 main end;
- 侧轴的开始位置叫做cross start、结束位置叫做cross end;
- 侧轴永远垂直于主轴;
2.2.flex-direction样式
flex-direction属性就是用来设置主轴方向的。
flex-direction:row /*子元素沿主轴方向排列,也就是水平方向。 row为默认值*/
flex-direction:column /*子元素沿侧轴方向排列,也就是垂直方向。*/
一个完整的例子:
<!DOCTYPE html><html><head><meta charset="utf-8"><title></title><style>body{display: flex; /*将body设置为弹性布局*/flex-direction: column; /*这里设置为侧轴方向排列*/}.son{width: 100px;height: 100px;border: solid 2px #f90;background-color: yellow;}</style></head><body><div class="son">1</div><div class="son">2</div><div class="son">3</div><div class="son">4</div><div class="son">5</div></body></html>

总结:
- 在弹性容器中,子元素想要水平方向排列,那就在弹性盒子中设置:flex-direction:row
- 在弹性容器中,子元素想要垂直方向排列,那就在弹性盒子中设置:flex-direction:column
- 在弹性容器中,以前的“块状元素独占一行”,“内联元素不独占一行”,“元素水平排列时需要浮> 动”等等规则,一律不再有效。
2.3.flex-wrap样式
由于弹性布局中的子元素能自动伸缩,所以,当父容器此次小于子元素整体尺寸时,子元素不会自动换行,而是自动收缩。
body{display: flex;}

那么,如果想要让子元素自动换行,可以使用flex-wrap:wrap
body{display: flex;flex-wrap: wrap; /*当弹性布局容器尺寸小于所以子元素尺寸时,子元素会自动换行*/}

总结:
- 在弹性盒子中,默认子元素不换行,即使是容器宽度不够时,子元素也不换行,只是宽度缩小。
- 如果在父容器宽度不够时想要自动换行,那么设置:flex-wrap:wrap
2.4.justify-content样式
以主轴方向为例:子元素水平方向排列后,默认依次靠左排列。如果想让子元素居中、居右等,那么就可以设置justify-content样式。值有五种:
- flex-start(默认):左对齐。
- flex-end:右对齐。
- center:居中。
- space-between:两端对齐,子元素之间间距都相等。
- space-around:每个子元素两侧的间距相等。所以子元素之间间距比子元素到边框 间距大一倍。
例如:
body{display: flex;justify-content: space-between; /*两端对齐,子元素之间间距都相等。*/}

总结:在弹性盒子中,子元素主轴对齐方式使用justify-content来设置
2.5.align-items与align-content样式
以主轴方向为例:子元素水平方向排列后,如果想让子元素垂直居中,那么就可以设置align-items样式。常用值有三种:
- flex-start(默认):上对齐。
- flex-end:下对齐。
- center:居中。
html,body{height: 100%; /*html与body的高度默认为0,所以要设置高度*/}body{display: flex;flex-wrap: wrap; /*如果允许换行,那么换行后,多行元素中的每一行也会垂直居中*/justify-content: center;align-items: center; /*不论是一行,还是多行,都会垂直居中*/}

再来看align-content样式:align-content样式对单行没有效果,对多行有效果,而且是将多行整体作为一个整体附加效果的。
总结:在弹性盒子中,子元素侧轴对齐方式可以使用align-items或align-content
- align-items对单行和多行都有效,align-content对单行无效。
- 在多行中,align-items让每一行都在各自范围内垂直居中。 align-content将多行作为一个整> 体,然后居中。
2.6.flex样式
如果想让每个子元素所占空间不一致,那么可以使用flex给子元素分配空间。 使用flex时要注意一下两点:
- flex样式是设置在子元素上的。
- 如果设置了flex,那就说明要给子元素按比例分配空间,因此width与height就失效了。
实例1:
<!DOCTYPE html><html><head><meta charset="utf-8"><title></title><style>html,body{height: 100%;}body{display: flex;}.son{width: 100px;height: 100px;border: solid 2px #f90;background-color: yellow;}</style></head><body><div class="son" style="flex:1;">1</div><div class="son" style="flex:1;">2</div><div class="son" style="flex:2;">3</div><div class="son" style="flex:2;">3</div></body></html>

上面实例中:flex样式后跟1个值:表示子元素所占空间的比例。三个div的宽度分别是窗口宽度的:1/4、1/2、1/4
实例2:
<!-- 第一个div的宽度是400px,是不变的。第二个和第三个div将剩下宽度按比例分配:1/3、2/3 --><body><div class="son" style="flex:0 0 400px;">1</div><div class="son" style="flex:1;">2</div><div class="son" style="flex:2;">3</div></body>

上面实例中:flex样式后跟3个值:
- 第一个值:子元素尺寸自动放大值
- 第二个值:子元素尺寸自动缩小值
- 第三个值:子元素尺寸(”auto”或”%”、”px”、”em” 或任何其他长度单位的数字。)
例如:
- 0 1 auto(默认):父元素尺寸变化时,子元素不放大,只缩小,尺寸自动充满。
- 1 1 auto: 父元素尺寸变化时,子元素自动放大缩小,尺寸自动充满。
- 0 0 300px: 父元素尺寸变化时,子元素不放大缩小,尺寸固定。
总结:可以使用flex让一行内的所有子元素自动撑满窗口宽度。而且每个子元素的宽度可以按比例> 进行分配。
3.布局实例
3.1.典型1-3-1布局

<style>header,nav,article,section,aside,footer{background-color: #666;}p{line-height: 50px;}.container{width: 1200px;margin: 0 auto;}.container header{width: 100%;height: 60px;margin-bottom: 10px;}.container nav{width: 100%;height: 60px;margin-bottom: 10px;}/*网页主要内容部分不能设置高度*/.container .main{width:100%;display: flex;margin-bottom: 10px;}.container .main article{flex: 0 0 200px;}.container .main section{flex: 1;margin: 0 10px;}.container .main aside{flex: 0 0 200px;}.container footer{width: 100%;height: 60px;}</style><!-- 总容器 --><div class="container"><header></header><nav></nav><!-- 网页主要内容部分 --><div class="main"><article></article><section><p>内容部分</p><p>内容部分</p><p>内容部分</p><p>内容部分</p></section><aside></aside></div><footer></footer></div>
注意点:
- 由于PC端屏幕尺寸相对固定,所以采用定宽不定高的原则。
- 所有页面元素都放在一个总容器中,然后就可以使总容器水平居中了。
- 网页主要内容部分不能设置高度,而应该是由内容撑开的。
3.2.典型自适应高度后台管理布局

<style>html,body,.container {width: 100%;height: 100%;margin: 0;padding: 0;display: flex;flex-direction: column;}.container header {flex:0 0 60px;width: 100%;background-color: #B3C0D1;}/*撑满header与footer剩余的高度*/.container .main {flex:1;width: 100%;display: flex;}.container .main aside {flex: 0 0 200px;background-color: #D3DCE6;}.container .main section {flex: 1;background-color: #E9EEF3;}.container footer {flex:0 0 60px;width: 100%;background-color: #B3C0D1;}</style><!-- 总容器 --><div class="container"><header></header><!-- 网页主要内容部分 --><div class="main"><aside></aside><section></section></div><footer></footer></div>
注意点:
- 后台管理页面布局的宽度和高度,一般都会自动撑满整个窗口。
- header和footer的高度可以固定,中间内容部分撑满剩余高度。
4.实战项目:小米官网首页
开发Vue官网首页:
index.html文件:
<!DOCTYPE html><html><head><meta charset="utf-8" /><title>小米官网 首页</title><link rel="stylesheet" href="css/reset.css"><link rel="stylesheet" href="css/index.css"></head><body><!-- 总容器--><div class="wrapper"><!-- 头部菜单--><header><div class="menu"><div class="menu-left"><ul><li><a>小米商城</a></li><li><a>MIUI</a></li><li><a>IoT</a></li><li><a>云服务</a></li><li><a>金融</a></li><li><a>有品</a></li><li><a>小爱开放平台</a></li><li><a>资质证照</a></li><li><a>协议规则</a></li><li><a>下载app</a></li><li><a>Select Location</a></li></ul></div><div class="menu-right"><ul><li><a onclick="location.href='login.html'">登录</a></li><li><a>注册</a></li><li><a>消息通知</a></li></ul><div class="cart">购物车(0)</div></div></div></header><!-- 企业logo部分--><div class="logo"><div class="logo-img"><img src="img/logo.png"></div><ul><li class="logo-box-li"><a>小米手机</a></li><li class="logo-box-li"><a>Redmi 红米</a></li><li class="logo-box-li"><a>电视</a></li><li class="logo-box-li"><a>笔记本</a></li><li class="logo-box-li"><a>家电</a></li><li class="logo-box-li"><a>路由器</a></li><li class="logo-box-li"><a>智能硬件</a><li class="logo-box-li"><a>服务</a></li><li class="logo-box-li"><a>社区</a></li></ul><div class="search"><input type="text" placeholder="小米10"><div class="search-icon-box"><img src="img/search.jpg"></div></div></div><!-- 横幅广告部分--><div class="banner"><div class="banner-lunbo"><img class="lunbo-img" src="img/lunbo5.jpg"></div><div class="banner-mengban"></div><ul><li><a>手机 电话卡</a><span>›</span></li><li><a>电视 盒子</a><span>›</span></li><li><a>笔记本 显示器 平板</a><span>›</span></li><li><a>家电 插线板</a><span>›</span></li><li><a>出行 穿戴</a><span>›</span></li><li><a>智能 路由器</a><span>›</span></li><li><a>电源 配件</a><span>›</span></li><li><a>健康 儿童</a><span>›</span></li><li><a>耳机 音箱</a><span>›</span></li><li><a>生活 箱包</a><span>›</span></li></ul></div><!-- 产品部分--><div class="product"><ul><li><img src="img/service1.png"><span>小米秒杀</span></li><li><img src="img/service2.png"><span>企业团购</span></li><li><img src="img/service3.png"><span>F码通道</span></li><li><img src="img/service4.png"><span>米粉卡</span></li><li><img src="img/service5.png"><span>以旧换新</span></li><li><img src="img/service6.png"><span>话费充值</span></li></ul><div class="product-img"><img src="img/product1.jpg"></div><div class="product-img"><img src="img/product2.jpg"></div><div class="product-img"><img src="img/product3.jpg"></div></div></div></body></html>
reset.css文件:
/************************ css 重置 ************************/html,body,div,span,h1,h2,h3,h4,h5,h6,ul,li,p{margin: 0;padding: 0;}html,body{width: 100%;/*按照小米官网设置*/font-family: Helvetica Neue,Helvetica,Arial,Microsoft Yahei,Hiragino Sans GB,Heiti SC,WenQuanYi Micro Hei,sans-serif;}ul{list-style: none;}a{text-decoration: none;}
index.css文件:
/************************ wrapper总容器 ************************/.wrapper{width: 100%;}/************************ header 头部 ************************/header{width: 100%;height: 40px;background-color: #333;}/************************ header menu ************************/header .menu{width: 1226px;height: 40px;margin: 0 auto;display: flex;justify-content: space-between;align-items: center;}/* menu中的两个ul样式是一样的 */header .menu ul{display: flex;height: 12px;}header .menu ul li{display: flex;align-items: center;border-right: solid 1px #424242;}header .menu ul li:last-child{border-right: none;}header .menu ul li a{color: #b0b0b0;font-size: 12px;margin: 0 8px;cursor: pointer;}header .menu ul li a:hover{color: #fff;}header .menu ul li:first-child a{margin-left: 0;}header .menu .menu-right{display: flex;align-items: center;}header .menu .menu-right .cart{width: 120px;height: 40px;background-color: #424242;margin-left: 20px;text-align: center;line-height: 40px;font-size: 12px;color: #b0b0b0;}header .menu .menu-right .cart:hover{background-color: #fff;color: #FF6700;cursor: pointer;/*user-select: none;是设置鼠标不能文本选中状态*/user-select: none;}/************************ 企业logo部分 ************************/.logo{width: 1226px;height: 100px;margin: 0 auto;display: flex;justify-content: space-between;align-items: center;}.logo .logo-img{width: 55px;height: 55px;background-color: #FF6700;display: flex;justify-content: center;align-items: center;}.logo ul{display: flex;}.logo ul li a{margin: 0 10px;font-size: 16px;color: #333;cursor: pointer;}.logo ul li a:hover{color:#FF6700;}.logo .search{width: 296px;height: 50px;box-sizing: border-box;border: solid 1px #e0e0e0;display: flex;justify-content: space-between;align-items: center;}.logo .search input{margin-left: 10px;width: 220px;border: none;outline: none;}.logo .search .search-icon-box{width: 48px;height: 48px;border-left: solid 1px #e0e0e0;}/************************ banner 横幅广告部分 ************************/.banner{width: 1226px;height: 460px;margin: 0 auto;/*横幅广告容器要做成相对定位,给子元素做父元素*/position: relative;}.banner .banner-lunbo,.banner .banner-lunbo img{width: 100%;height: 460px;}.banner .banner-mengban{width: 234px;height: 460px;background-color: #000;position: absolute;left: 0;top: 0;opacity: 0.3;}.banner ul{width: 234px;height: 420px;position: absolute;left: 0;top: 20px;}.banner ul li{width: 234px;height: 42px;cursor: pointer;display: flex;justify-content: space-between;align-items: center;}.banner ul li:hover{background-color: #FF6700;}.banner ul li a{margin-left: 30px;font-size: 14px;color: #fff;}.banner ul li span{margin-right: 30px;font-size: 24px;color: #fff;}/************************ product 产品部分 ************************/.product{width: 1226px;height: 170px;margin: 14px auto 100px;display: flex;justify-content: space-between;}.product ul{width:234px;height: 170px;background-color: #5f5750;display: flex;flex-wrap: wrap;}.product ul li{width:78px;height: 85px;display: flex;flex-direction: column;justify-content: center;align-items: center;font-size: 12px;color: #b0b0b0;user-select: none;cursor: pointer;/*在li中添加的横线与竖线是绝对定位的*/position: relative;}.product ul li img{margin-bottom: 3px;}.product ul li:hover{color: #fff;}.product .product-img,.product .product-img img{width: 316px;height: 170px;}/*::before表示在此元素前加元素*/.product ul li::before{width: 1px;height: 70px;background-color: #665e57;/*加的这个元素中必须要有内容,所以这里加一个空字符串*/content: "";position: absolute;right: 0;top: 7px}/*::before表示在此元素后加元素*/.product ul li::after{width: 64px;height: 1px;background-color: #665e57;content: "";position: absolute;left: 7px;bottom: 0;}
