今天学习web开发——flex布局
目标:
- 能说出flex盒子的布局 原理
- 能使用flex布局的常用属性
- 能独立完成携程移动端首页案例
一、flex布局体验
1.1 传统布局和flex布局
传统布局 :
- 兼容性好
- 布局繁琐
- 局限性,不能在移动端很好的布局
flex布局 :
- 操作方便,布局极为简单,移动端应用广泛
- PC端浏览器支持情况较差
- IE 11或更低版本,不支持或仅部分支持
建议:
- PC端布局,还是用传统布局
- 移动端或者不考虑兼容性问题的PC端页面布局,用flex布局
1.2 初体验
<title>flex初体验</title>
<style>
div {
/* 可以让span行内元素拥有行内块元素属性,可以设置宽度 */
display: flex;
width: 80%;
height: 300px;
background-color: pink;
/* 水平居中 */
justify-content: space-around;
}
div span {
/* width: 150px; */
height: 100px;
background-color: green;
margin-right: 5px;
/* 平均分成了3等分 */
flex: 1;
}
</style>
</head>
<body>
<div>
<span>1</span><span>2</span><span>3</span>
</div>
</body>
二、flex布局原理
2.1 布局原理
flex是flexible box的缩写——弹性布局,用来给盒状模型提供最大的灵活性,任何一个容器都可以指定为flex布局。
- 当我们给父盒子设为flex布局后,子元素的float、clear和vertical-align 属性将失效
- 伸缩布局=弹性布局=伸缩盒布局=弹性盒布局=flex布局
采用flex布局的元素,叫flex容器(flex container;子元素叫flex项目 (flex item)
- 体验中div是flex父容器
- span是子容器 flex项目
- 子容器可以横向排列,也可以纵向排列
总结flex布局原理:
就是通过给父盒子添加flex属性,来控制子盒子的位置和排列方式。
三、flex布局父项常见属性
3.1 常见父项属性
- flex-direction :设置主轴的方向
- justify-content:设置主轴上子元素的排列方式
- flex-wrap:设置子元素是否换行
- align-content:设置侧轴上子元素的排列方式(多行)
- align-items:设置侧轴上子元素的排列方式(单行)
- flex-flow:复合属性,相当于同时设置了flex-direction和flex-wrap
3.2 flex-direction设置主轴方向
- 主轴和侧轴
- 默认主轴方向是x轴,水平向右,行
- 默认侧轴方向是y轴,垂直向下,列
- 属性值
- row 行
- row-reverse 行翻转
- column 列
- column-reverse 列翻转
<title>flex-direction 主轴方向</title>
<style>
div {
/* 给父亲添加flex属性 */
display: flex;
width: 800px;
height: 300px;
background-color: green;
/* 默认的主轴是x轴,行row */
/* flex-direction: row; */
/* 翻转,简单了解 */
/* flex-direction: row-reverse; */
/* 竖着显示 设置y轴 列column 为主轴 那么x轴是侧轴*/
flex-direction: column;
/* 翻转 */
/* flex-direction: column-reverse; */
}
div span {
width: 150px;
height: 100px;
background-color: pink;
}
</style>
</head>
<body>
<div>
<span>1</span>
<span>2</span>
<span>3</span>
</div>
</body>
3.3 justify-content:设置主轴上子元素的排列方式
- justify-content: flex-start;
- justify-content: flex-end;
- justify-content: center;
-
justify-content: space-around;
-
justify-content: space-between;
<title>justify-content:设置主轴上子元素的排列方式</title>
<style>
div {
display: flex;
width: 800px;
height: 400px;
background-color: green;
/* 默认主轴是x轴 */
flex-direction: row;
/* flex-direction: column; */
/* 默认靠左排列 */
/* justify-content: flex-start; */
/* 靠右排列,不是翻转flex-direction:row-reverse */
/* justify-content: flex-end; */
/* 让子元素居中对齐 */
/* justify-content: center; */
/* 平均分配剩余空间 */
/* justify-content: space-around; */
/* 先两边贴边,再平均分配剩余空间 */
justify-content: space-between;
}
div span {
width: 150px;
height: 100px;
background-color: pink;
}
</style>
</head>
<body>
<div>
<span>1</span>
<span>2</span>
<span>3</span>
<span>4</span>
</div>
</body>
3.4 flex-wrap:设置子元素是否换行
-
flex-wrap: nowrap;
-
flex-wrap: wrap;
<title>flex-wrap设置子元素是否换行</title>
<style>
div {
display: flex;
width: 600px;
height: 500px;
background-color: green;
/* flex-wrap: nowrap; */
/* 换行 */
flex-wrap: wrap;
}
div span {
width: 150px;
height: 100px;
background-color: pink;
margin: 10px;
}
</style>
</head>
<body>
<div>
<span>1</span>
<span>2</span>
<span>3</span>
<!-- flex默认让盒子一行显示, 不换行 -->
<!-- 盒子摆不开了,会挤进去压缩其他盒子 -->
<span>4</span>
</div>
</body>
3.5 align-content:设置侧轴上子元素的排列方式(多行)
-
align-content: center;
-
align-content: space-around;
-
align-content: space-between;
主轴为x轴:
<title> align-content:设置侧轴上子元素的排列方式(多行)</title>
<style>
div {
display: flex;
width: 600px;
height: 500px;
background-color: green;
/* flex-direction: column; */
flex-wrap: wrap;
justify-content: center;
/* align-items: center; */
align-content: center;
/* align-content: space-around; */
/* align-content: space-between; */
}
div span {
width: 150px;
height: 100px;
background-color: pink;
margin: 10px;
}
</style>
</head>
<body>
<div>
<span>1</span>
<span>2</span>
<span>3</span>
<span>4</span>
<span>5</span>
<span>6</span>
</div>
</body>
主轴是y轴:
<title> align-content:设置侧轴上子元素的排列方式(多行)</title>
<style>
div {
display: flex;
width: 600px;
height: 500px;
background-color: green;
flex-direction: column;
flex-wrap: wrap;
justify-content: center;
/* align-items: center; */
align-content: center;
/* align-content: space-around; */
align-content: space-between;
}
div span {
width: 150px;
height: 100px;
background-color: pink;
margin: 10px;
}
</style>
</head>
<body>
<div>
<span>1</span>
<span>2</span>
<span>3</span>
<span>4</span>
<span>5</span>
<span>6</span>
<span>6</span>
<span>6</span>
</div>
</body>
3.6 align-items:设置侧轴上子元素的排列方式(单行)
-
align-items: center;
-
align-items: flex-start;
-
align-items: flex-end;
-
align-items: stretch;
主轴为x轴:
<title>align-items侧轴子元素排列1 单行</title>
<style>
div {
display: flex;
width: 600px;
height: 500px;
background-color: green;
/* flex-direction: row; */
/* 先主轴居中,再侧轴居中 */
justify-content: center;
align-items: center;
/* 贴上边 */
/* align-items: flex-start; */
/* 贴下边 */
/* align-items: flex-end; */
/* 拉伸,盒子不要给高度 */
/* align-items: stretch; */
}
div span {
width: 150px;
height: 100px;
background-color: pink;
margin: 10px;
}
</style>
</head>
<body>
<div>
<span>1</span>
<span>2</span>
<span>3</span>
</div>
</body>
主轴为y轴:
<title>align-items侧轴子元素排列2 单行</title>
<style>
div {
display: flex;
width: 600px;
height: 500px;
background-color: green;
flex-direction: column;
justify-content: center;
align-items: center;
/* align-items: stretch; */
}
div span {
width: 150px;
height: 100px;
background-color: pink;
margin: 10px;
}
</style>
</head>
<body>
<div>
<span>1</span>
<span>2</span>
<span>3</span>
</div>
</body>
3.7 flex-flow:复合属性
相当于同时设置flex-direction和flex-wrap
flex-flow: column wrap;
<title>flex-flow复合属性</title>
<style>
div {
display: flex;
width: 600px;
height: 500px;
background-color: pink;
/* flex-wrap: wrap;
flex-direction: column; */
/* 设置主轴方向和换行 */
flex-flow: column wrap;
}
div span {
width: 150px;
height: 100px;
background-color: green;
}
</style>
</head>
<body>
<div>
<span>1</span>
<span>2</span>
<span>3</span>
<span>4</span>
<span>5</span>
<span>6</span>
<span>7</span>
</div>
</body>
四、flex布局子项常见属性
- flex子项目占的份数
- align-self 控制子项目自己在侧轴的排列方式
- order 属性定义子项目的排序顺序(前后顺序)
4.1 flex属性 ※
flex属性定义子项目分配剩余空间,用flex 来表示占多少份数。
<title> flex属性</title>
<style>
section {
display: flex;
width: 60%;
height: 250px;
background-color: pink;
margin: 0 auto;
}
/* 左右两侧盒子固定,中间盒子可以伸缩 */
section div:nth-child(1) {
width: 100px;
height: 150px;
background-color: green;
}
section div:nth-child(2) {
/* 剩余的空间分成1分全部给2号盒子 */
flex: 1;
background-color: purple;
}
section div:nth-child(3) {
width: 100px;
height: 150px;
background-color: blue;
}
p {
display: flex;
width: 60%;
height: 150px;
background-color: pink;
margin: 50px auto;
}
p span {
flex: 1;
}
p span:nth-child(2) {
flex: 2;
background-color: green;
}
</style>
</head>
<body>
<section>
<div>1</div>
<div>2</div>
<div>3</div>
</section>
<p>
<!-- 不给盒子宽度,则整个p都是剩余空间 -->
<span>1</span>
<span>2</span>
<span>3</span>
</p>
</body>
4.2 align-self 控制子项目自己在侧轴的排列方式
允许单个项目的排列方式
<title>align-self控制子项目自己在侧轴的排列方式</title>
<style>
div {
display: flex;
width: 800px;
height: 300px;
background-color: pink;
/* 单行子元素侧轴全部往下对齐 */
/* align-items: flex-end; */
}
div span {
width: 150px;
height: 100px;
background-color: green;
margin-right: 5px;
}
/* 让第三个子项目在侧轴最下面对齐 */
div span:nth-child(3) {
align-self: flex-end;
}
</style>
</head>
<body>
<div>
<span>1</span>
<span>2</span>
<span>3</span>
</div>
</body>
4.3 order 属性定义子项目的排序顺序(前后顺序)
数值越小,排列越靠前,默认0
<title>order 属性定义子项目的排序顺序(前后顺序) </title>
<style>
div {
display: flex;
width: 800px;
height: 300px;
background-color: pink;
}
div span {
width: 150px;
height: 100px;
background-color: green;
}
div span:nth-child(n+3) {
/* 默认0 -1比0小,所以在前面 */
order: -1;
}
</style>
</head>
<body>
<div>
<span>1</span>
<span>2</span>
<span>3</span>
<span>4</span>
</div>
</body>
五、携程网首页案例制作
5.1 技术选型
方案:单独制作移动页面
技术:flex布局
5.2 搭建相关文件夹结构
5.3 书写代码
- 引入normalize.css和index.css样式
- index.css样式里写上:flex布局body样式
- 统筹携程从上往下布局结构:【搜索search-index模块】---【焦点图focus模块】---【单行导航栏local-nav】---【主导航栏nav】---【双行导航栏subnav-entry】---【活动模块sales-box】---
- 宽度不用给,给高度
5.4【搜索模块search-index】
- 顶部用固定定位做,分成左右两部分,用flex布局
- 【search】可以放大缩小搜索栏
- 【user】大小不变
- 先把【user】宽高固定,【search】用flex=1分配剩余部分
.search-index {
display: flex;
/* 固定定位不以父盒子,以屏幕为准 */
position: fixed;
top: 0;
left: 50%;
-webkit-transform: translateX(-50%);
transform: translateX(-50%);
/* 固定的盒子要有宽度 */
width: 100%;
min-width: 320px;
max-width: 540px;
height: 44px;
background-color: #f3f3f3;
border-top: 1px solid #ccc;
border-bottom: 1px solid #ccc;
}
.search {
flex: 1;
height: 26px;
line-height: 24px;
border: 1px solid #ccc;
margin: 8px 10px;
border-radius: 5px;
font-size: 12px;
color: #666;
box-shadow: 0 2px 4px rgba(0, 0, 0, .3);
}
.search::before {
content: '';
display: inline-block;
width: 15px;
height: 15px;
background: url(../images/sprite.png) no-repeat -59px -279px;
background-size: 104px auto;
vertical-align: middle;
margin: 0 10px;
}
.user {
width: 44px;
height: 44px;
font-size: 12px;
text-align: center;
color: #099fde;
}
.user::before {
content: '';
display: block;
width: 23px;
height: 23px;
background: url(../images/sprite.png) no-repeat -59px -193px;
background-size: 104px auto;
margin: 3px auto -2px;
}
5.5 焦点图focus模块
- 简单img标签放【focus】里
.focus {
margin-top: 44px;
}
.focus img {
width: 100%;
}
5.6 导航栏local-nav
- ul>li
- flex平分
- li里面上下
.local-nav {
display: flex;
height: 64px;
background-color: #fff;
margin: 3px 4px;
border-radius: 5px;
}
.local-nav li {
flex: 1;
margin-top: 6px;
}
.local-nav a {
display: flex;
flex-direction: column;
align-items: center;
font-size: 12px;
}
.local-nav li [class^="local-nav-icon"] {
width: 32px;
height: 32px;
background: url(../images/localnav_bg.png) no-repeat 0 0;
background-size: 32px auto;
}
.local-nav li .local-nav-icon2 {
background-position: 0 -32px;
}
.local-nav li .local-nav-icon3 {
background-position: 0 -64px;
}
.local-nav li .local-nav-icon4 {
background-position: 0 -96px;
}
.local-nav li .local-nav-icon5 {
background-position: 0 -128px;
}
5.7 主导航栏nav模块
- 背景线性渐变:
background:-webkit-linear-gradient (起始方向,颜色1,颜色2);
/* 主导航栏模块nav start */
.nav {
overflow: hidden;
border-radius: 8px;
margin: 0 4px 3px;
}
.nav-common {
display: flex;
height: 88px;
/* 线性渐变必须加浏览器前缀 */
background: -webkit-linear-gradient(left,#fa5e55,#fa7153);
margin-bottom: 3px;
}
.nav-common:nth-child(2) {
background: -webkit-linear-gradient(left,#4b90ed,#4c93ed);
}
.nav-common:nth-child(3) {
background: -webkit-linear-gradient(left,#35c2a8,#44c792);
}
.nav-items {
flex: 1;
display: flex;
flex-direction: column;
}
.nav-items:nth-child(-n+2) {
border-right: 2px solid #fff;
}
.nav-items a {
flex: 1;
text-align: center;
line-height: 44px;
color: #fff;
font-size: 14px;
/* 文字阴影 */
text-shadow: 1px 1px rgba(0, 0, 0, .3);
}
.nav-items a:nth-child(1) {
border-bottom: 1px solid #fff;
}
.nav-items:nth-child(1) a {
border: 0;
background: url(../images/hotel.png) no-repeat bottom center;
background-size: 121px auto;
}
/* 主导航栏模块nav end */
5.8 双行导航栏subnav-entry
- ul>li
- flex=20% 10个li分两行
- 其他和单行导航栏步骤一致
/* 双行导航栏subnav-entry start */
.subnav-entry {
display: flex;
border-radius: 8px;
background-color: #fff;
margin: 0 4px;
flex-wrap: wrap;
}
.subnav-entry li {
/* 可以写百分比 相对于父级来说的 */
flex: 20%;
}
.subnav-entry a {
display: flex;
flex-direction: column;
align-items: center;
}
.subnav-items {
width: 24px;
height: 24px;
background: url(../images/subnav-bg.png) no-repeat 0 0;
background-size: 24px auto;
margin: 15px 0 2px;
}
/* 双行导航栏subnav-entry end */
5.9 活动模块sales-box
- sales-hd:定位来做左h2标签 右a标签
- sales-bd:先行后列
/* 活动模块sales-box start */
.sales-box {
border-top: 1px solid #ccc;
background-color: #fff;
margin: 4px;
box-shadow: 1px 1px 4px rgba(0, 0, 0, .3);
}
.sales-hd {
position: relative;
height: 44px;
border-bottom: 1px solid #ccc;
}
.sales-hd h2 {
position: relative;
text-indent: -999px;
overflow: hidden;
}
.sales-hd h2::after {
position: absolute;
top: 8px;
left: 20px;
content: '';
width: 79px;
height: 15px;
background: url(../images/hot.png) no-repeat 0 -20px;
background-size: 79px auto;
}
.more {
position: absolute;
top: 0;
right: 5px;
background: -webkit-linear-gradient(left,#fa5e55,#d3a095);
border-radius: 5px;
padding: 3px 20px 3px 8px;
color: #fff;
}
.more::after {
content: '';
position: absolute;
top: 9px;
right: 9px;
width: 7px;
height: 7px;
border-top: 2px solid #fff;
border-right: 2px solid #fff;
transform: rotate(45deg);
}
.row {
display: flex;
border-bottom: 1px solid #ccc;
}
.row a {
flex: 1;
}
.row a:nth-child(1) {
border-right: 1px solid #ccc;
}
.row a img {
width: 100%;
}
/* 活动模块sales-box end */