Contents
  1. 1. 1. 圣杯布局
  2. 2. 2. 双飞翼布局
  3. 3. 3. flex弹性盒布局
    1. 3.0.1. display:flex;如果一个容器设置了这个属性,则这个盒子里的所有子元素都会变成伸缩项
  • 4. 4. 使用flex做的圣杯布局(by 阮一峰)
  • @[toc]

    1. 圣杯布局

    1. 我对header和footer没有设置宽度
    2. 对left 和right 有设置固定宽度
    3. 对left,right 和 middle 有设置高度
    4. 对middle 宽度设置为100%
    5. 使用定位和margin值将left 和 right 元素进行布局
      圣杯布局
      代码上附有步骤:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      75
      76
      <!DOCTYPE html>
      <html lang="en">
      <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
      <style>
      *{padding:0;margin: 0;}
      header{
      background-color: darkcyan;
      height: 50px;
      }
      .container{
      background-color:cyan;
      overflow: hidden;
      /*4. 因为文字会被left元素挡住,所以使用padding将内容显示出来,同时需要知道left的宽度*/
      padding-left:200px;
      padding-right: 300px;
      }
      .middle,.left, .right{
      float: left; /* 1. 三者都设置为float left,且三者都有高度*/
      height: 500px;
      /*5. 此时left也会跟着回来,所以使用相对定位*/
      position: relative;
      word-wrap: break-word;/*解决文字换行*/
      }
      .middle{
      background-color: palevioletred;
      width: 100%; /* 2. middle 宽度使用100% */

      }
      .left{
      width: 200px;
      background-color: tomato;
      margin-left: -100%; /*3. 使用margin-left: -100% 将left元素拉回来*/
      /*5.1 对left进行设置*/
      left: -200px;
      }
      .right{
      background-color: purple;
      width: 300px;
      /*5.2 将right盒子拉回*/
      margin-left: -300px;
      right: -300px;
      }
      footer{
      background-color: yellowgreen;
      height: 60px;
      }
      </style>
      </head>
      <body>
      <header>
      <h4>header</h4>
      </header>
      <div class="container">
      <div class="middle">
      <h4>middle</h4>
      <p>mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm</p>
      </div>
      <div class="left">
      <h4>left</h4>
      <p>llllllllllllllllllllllllllllllllllll</p>
      </div>
      <div class="right">
      <h4>right</h4>
      <p>rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr</p>
      </div>
      </div>
      <footer>
      <h4>footer</h4>
      <p>pppppppppppppppppp</p>
      </footer>
      </body>
      </html>

    2. 双飞翼布局

    注意:从图片上看感觉布局一样
    但还是要看代码哟,双飞翼布局没有使用position,而且container只包括了middle元素哦

    1. 设置了四个高度,分别是left right container,middle
    2. 对container设置了100%,使用margin 将left 和right 拉回来
    3. 对middle 进行设置,使用margin 为left和right 进行留白
    4. 底部使用clear:both 清除浮动
      双飞翼
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      75
      76
      77
      78
      79
      80
      81
      <!DOCTYPE html>
      <html lang="en">
      <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>双飞翼布局</title>
      <style>
      * {
      padding: 0;
      margin: 0;
      text-align: center;
      word-wrap: break-word;
      }

      header {
      background-color: darkcyan;
      height: 50px;
      }

      .container {

      width: 100%;/*2. width:100%*/

      }
      .container,.left,.right{
      float: left;/*1.float*/
      height: 500px;
      }
      .middle {
      background-color: palevioletred;
      margin-left: 300px;/*4.使用margin 将左右两边留白*/
      margin-right: 200px;
      height: 500px;
      }

      .left {
      background-color: tomato;
      width: 300px;
      margin-left: -100%; /*3.1 将left拉回来*/
      }

      .right {
      background-color: purple;
      width: 200px;
      margin-left: -200px; /*3.2 将right拉回来*/
      }

      footer {
      background-color: yellowgreen;
      height: 60px;
      clear: both;/*5.使底部恢复 clear 属性规定元素的哪一侧不允许其他浮动元素。*/
      }
      </style>
      </head>
      <body>
      <header>
      <h4>header</h4>
      </header>
      <div class="container">
      <div class="middle">
      <h4>middle</h4>
      <p>mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm</p>
      </div>
      </div>

      <div class="left">
      <h4>left</h4>
      <p>llllllllllllllllllllllllllllllllllll</p>
      </div>
      <div class="right">
      <h4>right</h4>
      <p>rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr</p>
      </div>

      <footer>
      <h4>footer</h4>
      <p>pppppppppppppppppp</p>
      </footer>
      </body>
      </html>

    3. flex弹性盒布局

    1. 设置了left middle right 的高度
    2. 设置了left 和 right 的宽度
    3. 对left middle right 的父级元素container设置display:flex后就会自动这样
      弹性盒布局
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      <!DOCTYPE html>
      <html lang="en">
      <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>flex弹性布局</title>
      <style>
      * {
      padding: 0;
      margin: 0;
      text-align: center;
      }

      header {
      background-color: darkcyan;
      height: 50px;
      }

      .container {
      background-color: cyan;
      display: flex;
      }

      .middle,
      .left,
      .right {
      height: 500px;
      word-wrap: break-word;
      /*解决文字换行*/
      }

      .middle {
      background-color: palevioletred;
      }

      .left {
      width: 200px;
      }

      .right {
      background-color: purple;
      }

      footer {
      background-color: yellowgreen;
      height: 60px;
      }
      </style>
      </head>
      <body>
      <header>
      <h4>header</h4>
      </header>
      <div class="container">
      <div class="left">
      <h4>left</h4>
      <p>llllllllllllllllllllllllllllllllllll</p>
      </div>
      <div class="middle">
      <h4>middle</h4>
      <p>mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm</p>
      </div>
      <div class="right">
      <h4>right</h4>
      <p>rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr</p>
      </div>
      </div>
      <footer>
      <h4>footer</h4>
      <p>pppppppppppppppppp</p>
      </footer>
      </body>
      </html>

    注意:
    我发现虽然设置了left 和 right 的宽度 但是随着,middle 里内容的文字增加,right的宽度会变化


    我对上面的代码进行了修改,如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>flex弹性布局</title>
    <style>
    * {
    padding: 0;
    margin: 0;
    text-align: center;
    word-wrap: break-word;
    }

    header {
    background-color: darkcyan;
    height: 50px;
    }

    .container {
    background-color: cyan;
    display: flex;/*1.设置flex属性*/
    }

    .middle,
    .left,
    .right {
    height: 500px;
    word-wrap: break-word;
    /*解决文字换行*/
    }

    .middle {
    background-color: palevioletred;
    flex-grow: 1;
    }

    .left {
    order: -1; /*2.设置布局,定义项目的排列顺序,越小越靠前,默认为0*/
    flex-basis:200px;
    }

    .right {
    background-color: purple;
    flex-basis:300px;
    }

    footer {
    background-color: yellowgreen;
    height: 60px;
    }
    </style>
    </head>
    <body>
    <header>
    <h4>header</h4>
    </header>
    <div class="container">
    <div class="middle">
    <h4>middle</h4>
    <p>mmmmmmmmmmmmmmmmmmmmmmmmm</p>
    </div>
    <div class="left">
    <h4>left</h4>
    <p>lllllllllllllllllllllllll</p>
    </div>
    <div class="right">
    <h4>right</h4>
    <p>rrrrrrrrrrrrrrrrrrrr</p>
    </div>
    </div>
    <footer>
    <h4>footer</h4>
    <p>pppppppppppppppppp</p>
    </footer>
    </body>
    </html>

    加入了flex-grow:使其剩下的填满
    flex-basis:设置规定值
    得到了下面的布局
    flex
    但是还是会随着每个内容的长度进行比例切换
    比如当m增加时,会这样,对于left 和right里内容也是这样
    在这里插入图片描述
    我又重新查了一下flex的属性

    display:flex;如果一个容器设置了这个属性,则这个盒子里的所有子元素都会变成伸缩项

    阮一峰大神 flex 布局实例

    • justify-content 设置子元素的排列方式 flex-start,flex-end,center
      • space-between
    • sapce-between 左右对齐父容器的开始和结束,中间平均分布,产生相同的间距
    • sapce-around 将多余的空间平均分布在每一个子元素的两边(主轴上的)中间的减减压是左右两边的两倍
    • flex-wrap 控制子元素是否换行 nwrap 不换行 wrap 换行
    • flex-direction:元素排列方向,主轴方向默认为row(水平方向)
      • row 水平方向–主轴 垂直方向 —侧轴 默认row-reverse
      • column 垂直方向–主轴 水平方向为–侧轴 column-reverse从上到下
    • flex-flow 由flex-wrap 和 flex-direction 组成
    • flex-grow 扩展了子元素的宽度,设置当前元素应该占据剩余空间的比例值(默认为0)
    • flex-shrink 定义收缩比例,通过设置的值来计算收缩空间(默认为1)
      • 比例值计算:flex-grow/所有兄弟的flex-grow的和
    • flex:用来设置当前伸缩子项占据剩余空间的比例值
    • align-item 设置子元素(伸缩项)在侧轴上的对齐方式
      • center 侧轴上居中对齐
      • stretch 侧轴方向上进行拉伸,填充满整个侧轴方向(默认值)
      • baseline 基线对齐
    • align-self:设置单个元素在侧轴方向上的对齐方式


    1
    2
    3
    4
    5
    .box {
    display: flex;
    justify-content: center;
    align-items: flex-end;
    }

    在这里插入图片描述
    使用sapce-between

    1
    2
    3
    4
    .box {
    display: flex;
    justify-content: space-between;
    }

    在这里插入图片描述

    1
    2
    3
    4
    5
    .box {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    }

    在这里插入图片描述
    align-self

    1
    2
    3
    4
    5
    6
    7
    .box {
    display: flex;
    }

    .item:nth-child(2) {
    align-self: center;
    }

    在这里插入图片描述

    4. 使用flex做的圣杯布局(by 阮一峰)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
    .HolyGrail {
    display: flex;
    min-height: 100vh;
    flex-direction: column;
    }

    header,
    footer {
    flex: 1;
    background-color: darkcyan;
    }

    .HolyGrail-body {
    display: flex;
    flex: 1;
    background-color: blueviolet;
    }

    .HolyGrail-content {
    flex: 1;
    background-color: red;
    }

    .HolyGrail-nav, .HolyGrail-ads {
    /* 两个边栏的宽度设为12em */
    flex: 0 0 12em;
    background-color: yellow;
    }

    .HolyGrail-nav {
    /* 导航放到最左边 */
    order: -1;
    }
    </style>
    </head>
    <body class="HolyGrail">
    <header>...</header>
    <div class="HolyGrail-body">
    <main class="HolyGrail-content">cccccccccccccccccccccccccccccccccccccccccccccccccccccccccc</main>
    <nav class="HolyGrail-nav">lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll</nav>
    <aside class="HolyGrail-ads">...</aside>
    </div>
    <footer>...</footer>
    </body>
    </html>

    在这里插入图片描述
    我在对body中加入了文字换行,但是结果布局的左边还是会被内容撑到变形
    在这里插入图片描述

    Contents
    1. 1. 1. 圣杯布局
    2. 2. 2. 双飞翼布局
    3. 3. 3. flex弹性盒布局
      1. 3.0.1. display:flex;如果一个容器设置了这个属性,则这个盒子里的所有子元素都会变成伸缩项
  • 4. 4. 使用flex做的圣杯布局(by 阮一峰)