flex弹性盒模型

234 阅读8分钟
  1. 传统布局 float + display + position

    先看一张图,层次结构到底是什么样子的::

    注意:

  • 浮动元素并未脱离文档流,与内容、文字、图片在同一层级
  • 定位的元素脱离了文档流
  • zIndex设置的前提,是position已设置

  1. 弹性盒模型

  1. 容器属性
  • flex-direction 控制主轴的方向

  • flex-warp 决定项目是否换行

  • flex-flow 同时控制主轴方向和项目是否换行

    /* flex-flow: 主轴方向 换行方式; */

  • justift-content

  • align-items

  • align-self

  • align-content

  1. 项目属性
  • order
  • flex-grow
display: flex; 
    设置元素为弹性盒模型
     元素设置为弹性盒模型之后,排列方式,就会根据主轴方向进行排列
        flex-direction 弹性盒模型主轴设置
            row(默认值) 从左向右排列 (侧轴:从上到下)
            row-reverse 从右向左排列(侧轴:从上到下)
            column 从上到下进行排列 (侧轴:从左到右)
            column-reverse 从下到上进行排列(侧轴:从左到右)
        在弹性盒模型中,子元素超出默认不进行换行,而是压缩元素的尺寸
        flex-wrap: 子元素超出父级范围后,是否换行
            nowrap (默认值) 不换行
            wrap 正常换行
            wrap-reverse 反向换行
            (正常换行时,元素会沿着侧轴方向,正方向换行,从上到下或从左到右。反向换行时,和正常换行刚好相反,从下到上或从右到左)
            
主轴元素的排列设置: 
        富裕空间: 元素的空间 - 所有子元素的占位空间(width/height + margin + padding + border)之后
        justify-content 定义元素在主轴上的排列
           flex-start(默认值) 元素沿着主轴的开始方向进行排列,富裕空间保持在主轴方向的结束
           flex-end 元素排列在主轴方向的结束位置,富裕空间保持在主轴方向的开始位置
           center 元素排列在主轴中间,富裕空间平均分布在两侧
           space-between 子级平均分配在主轴上,富裕空间平均分派在子级之间 
           space-around 富裕空间平均分配在子级的左右两边
侧轴元素的排列设置:
        富裕空间: 元素的空间 - 所有子元素的占位空间之后
        align-items:
            stretch(默认值): 拉伸
            flex-start:交叉轴上起点对齐
            flex-end:交叉轴上终点对齐
            center:交叉轴居中对齐
            baseline:基线对齐,根据交叉轴文字基线进行对齐
行排列设置:
        align-content 行对齐方式
            flex-start 排列在侧轴开始位置
            flex-end 排列在侧轴的结束位置
弹性盒模型的子级设置
        order:定义项目排列顺序,数值越小,排列越靠前,默认为0,接受负值
        
        flex 伸缩性设置
                number 设置
                none 不伸缩
            默认情况下,宽度由内容撑开
            flex 计算:
                计算父级的剩余空间 690px;
                计算子级的 flex 之和: 15
                690/15 = 46
                flex 在计算时,如果计算后的空间,已经放不下内容,会保持内容大小
                
            flex-basis: 300px;
            初始值:
                1. 如果父级的空间放不下,会影响初始值,会对元素进行压缩
                2. 初始值优先级大于 width 会覆盖掉 width 
             
            flex-grow: 2;
            如果父级有富裕空间的放大设置
            
            flex-shrink: 2;
            数值越大压缩的空间越大
            
单独控制某一个元素的侧轴对齐
        align-self:
            stretch(默认值): 拉伸
            flex-start:交叉轴上起点对齐
            flex-end:交叉轴上终点对齐
            center:交叉轴居中对齐
            baseline:基线对齐,根据交叉轴文字基线进行对齐

可参考这里:www.ruanyifeng.com/blog/2015/0…

  1. 老版本的弹性盒模型设置
<style>
        /* 
        - box-orient:horizontal || vertical  水平还是垂直排列,类似flex-direction
        - box-direction:normal || reverse 是否颠倒顺序,类似flex-direction:row-severse
        - box-pack:start || end || center || justify  主轴方向对齐,类似justify-content
        - box-align:start || center || end 交叉轴方向对齐,类似align-items
        */
        
        /*
            这里flex要写在box后面,则遇到可识别flex的情况即覆盖box
        */
        #box {
            border: 2px solid #000;
            display: -webkit-box;
            display: -moz-box;
            display: -ms-box;
            display: -o-box;
            display: flex;
            -webkit-box-pack: justify;
            -webkit-box-align: center;
            justify-content: space-around;
            align-items: center;
            width: 900px;
            height: 500px;
        }
        #box div {
            margin: 2px;
            /* width: 100px; */
            height: 100px;
            background: red;
            font: 20px/100px "宋体";
            color: #ffffff;
            text-align: center;
            word-break: break-all;
        }
        /*
            - box-flex:number  类似 flex-grow
            - box-ordinal-group:number 类似于 orde
        */
        #box div:nth-child(1) {
            -webkit-box-ordinal-group: 4;
            -webkit-box-flex: 1;
            order: 4;
            flex: 1;
        }
        #box div:nth-child(2) {
            -webkit-box-ordinal-group: 1;
            -webkit-box-flex: 2;
            order: 1;
            flex: 2;
        }
        #box div:nth-child(3) {
            -webkit-box-ordinal-group: 5;
            -webkit-box-flex: 3;
            order: 5;
            flex: 3;
        }
        #box div:nth-child(4) {
            -webkit-box-ordinal-group: 3;
            -webkit-box-flex: 4;
            order: 3;
            flex: 4;
        }
        #box div:nth-child(5) {
            -webkit-box-ordinal-group: 2;
            -webkit-box-flex: 5;
            order: 2;
            flex: 5;
        }
    </style>
<body>
   <div id="box">
       <div>1</div>
       <div>2</div>
       <div>3</div>
       <div>4</div>
       <div>5</div>
   </div>   
</body>

运行结果:

  1. margin 子级的上下margin auto 会等分父级上下的富裕空间 子级的左右margin auto 会等分父级左右的富裕空间
<style>
        #box {
            border: 2px solid #000;
            display: flex;
            width: 400px;
            height: 600px;
        }
        #box div {
            margin: auto;
            width: 100px;
            height: 100px;
            background: red;
            font: 100px/100px "宋体";
            color: #ffffff;
            text-align: center;
            word-break: break-all;
            flex-shrink: 0;
        }
    </style>
<div id="box">
   <div>1</div>
   <div>2</div>
</div>

运行结果:图中可见1个div和2个div的排列区别

7. 栗子:实现骰子点数布局

 <div class="first-face">
    <span class="pip"></span>
  </div>
  <div class="second-face">
    <span class="pip"></span>
    <span class="pip"></span>
  </div>
  <div class="third-face">
    <span class="pip"></span>
    <span class="pip"></span>
    <span class="pip"></span>
  </div>
  <div class="fourth-face">
    <div>
      <span class="pip"></span>
      <span class="pip"></span>
    </div>
    <div>
      <span class="pip"></span>
      <span class="pip"></span>
    </div>
  </div>
  <div class="fifth-face">
    <div class="column">
      <span class="pip"></span>
      <span class="pip"></span>
    </div>
    <div class="column">
      <span class="pip"></span>
    </div>
    <div class="column">
      <span class="pip"></span>
      <span class="pip"></span>
    </div>
  </div>
  <div class="sixth-face">
    <div class="column">
      <span class="pip"></span>
      <span class="pip"></span>
      <span class="pip"></span>
    </div>
    <div class="column">
      <span class="pip"></span>
      <span class="pip"></span>
      <span class="pip"></span>
    </div>
  </div>
  <div class="ninth-face">
    <div class="column">
      <span class="pip"></span>
      <span class="pip"></span>
      <span class="pip"></span>
    </div>
    <div class="column">
      <span class="pip"></span>
      <span class="pip"></span>
      <span class="pip"></span>
    </div>
     <div class="column">
      <span class="pip"></span>
      <span class="pip"></span>
      <span class="pip"></span>
    </div>
  </div>
 /* OTHER STYLES  这部分复制原文的 S*/

 * {
    box-sizing: border-box;
  }

  html, body {
    height: 100%;
  }

  body {
    display: flex;
    align-items: center;
    justify-content: center;
    vertical-align: center;
    flex-wrap: wrap;
    align-content: center;
    font-family: 'Open Sans', sans-serif;
    
    background: linear-gradient(top, #222, #333);
  }

  [class$="face"] {
    margin: 16px;
    padding: 4px;
    
    background-color: #e7e7e7;
    width: 104px;
    height: 104px;
    object-fit: contain;
    
    box-shadow:
      inset 0 5px white, 
      inset 0 -5px #bbb,
      inset 5px 0 #d7d7d7, 
      inset -5px 0 #d7d7d7;
    
    border-radius: 10%;
  }

  .pip {
    display: block;
    width: 24px;
    height: 24px;
    border-radius: 50%;
    margin: 4px;
    background-color: #333;
    box-shadow: inset 0 3px #111, inset 0 -3px #555;
  }
/* OTHER STYLES  这部分复制原文的 E*/


// 实现骰子的代码部分
  .first-face {
    display: flex;
    justify-content: center;
    align-items: center;
  }
  .second-face {
    display: flex;
    justify-content: space-between;

    .pip:nth-child(2) {
        align-self: flex-end;
      }
  }
  .third-face {
    display: flex;
    justify-content: space-between;

    .pip {
        &:nth-child(2){
            align-self: center
        }
        &:nth-child(3){
            align-self: flex-end;
        }
    }
  }

  .fourth-face {
    display: flex;
    justify-content:space-between;
    flex-direction: column;

    div{
        display: flex;
        justify-content: space-between;
    }
  }

  .fifth-face {
    display: flex;
    flex-direction: column;
    justify-content: space-between;

    div {
        display: flex;
        justify-content: space-between;

        &:nth-child(2) {
            justify-content: center;
        }
    }
  }

  .sixth-face {
    display: flex;
    justify-content: space-between;

    div {
        display: flex;
        flex-direction: column;
        justify-content: space-between;
    }
  }

  .ninth-face {
    display: flex;
    justify-content: space-between;

    div {
        display: flex;
        flex-direction: column;
        justify-content: space-between;
    }
  }

运行结果:

  1. 栗子:当内容不足一屏幕时,底部导航固定
<body>
  <header>header</header>
  <section>123123</section>
  <footer>footer</footer>
</body>
body {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  margin: 0;
}
section {
  flex: 1;
}

运行结果:

  1. 栗子:圣杯布局
<style>
    body {
      margin: 0;
    }
    header {
      background: paleturquoise;
    }
    section {
      display: flex;
    }
    section div {
      flex: 1;
      border: 1px solid #333;
    }
    .div-left, .div-right {
      flex: 0 0 100px;
    } 
    footer {
      background: slategray;
    }
  </style>
<body>
  <header>header</header>
  <section>
    <div class="div-left">1</div>
    <div class="div-center">2</div>
    <div class="div-right">3</div>
  </section>
  <footer>footer</footer>
</body>

运行结果:

  1. 流式布局
  <style>
    body {
      margin: 0;
    }
    section {
      width: 500px;
      height: 500px;
      background: black;
      display: flex;
      flex-wrap: wrap;
      align-content: flex-start;
    }
    div {
      background: tan;
      box-sizing: border-box;
      flex-basis: 25%;
      height: 100px;
      border: 1px solid red;
    }
  </style>
<body>
  <section>
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <div>4</div>
    <div>5</div>
    <div>6</div>
    <div>7</div>
    <div>8</div>
    <div>7</div>
    <div>8</div>
  </section>
</body>

运行结果:

ps:

参考文章:www.ruanyifeng.com/blog/2015/0…