今天学习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 */









