flex布局


前言

你有没有这种困惑,页面写了很久,但是对于布局都是有一种拼凑的感觉,很多布局都是靠margin,padding弄出来的,适配小屏就用媒体查询,flex就只是用来模块居中的,这样用法就太大材小用了,所以今天就系统的看一下flex的使用。

读完本篇文章你将会了解到

  • flex 布局的基本概念
  • 容器的属性
  • 项目的属性
  • flex 解决的实际问题

大局为重,概念先行

flex 是 flexible 简写,flex 布局就是弹性灵活的布局,现在大部分浏览器都能支持的布局,是目前最通用的布局方式之一。它有两个概念是容器和项目,容器是指的最外层的父组件,项目是里面每一个子组件,在这样一个平面上有横竖两条线,默认水平线是主轴,垂直线是交叉轴。

容器的属性

开启 flex 布局可以使用

display: flex

主轴方向

可以使用flex-direction来定义主轴的方向是在水平上还是垂直上(默认属性是 row),还可以添加 reverse 表示反向

/* 水平方向 */
flex-direction: row
flex-direction: row-reverse
/* 垂直方向 */
flex-direction: column
flex-direction: column-reverse

项目是否换行

使用 flex-wrap 可以让容器中的项目是否换行,默认不换行

/* 不换行 */
flex-wrap: nowrap
/* 换行 */
flex-wrap: wrap
/* 换行反转 */
flex-wrap: wrap-reverse

项目流向

指的是项目流的方向,和流向是否换行,使用 flex-flow 是主轴方向和是否换行的合写属性

flex-flow: <flex-direction> <flex-wrap>

项目对齐方式

主轴对齐方式
设置项目在主轴上的对齐方式可以用 justify-content 实现

/* 左对齐 */
justify-content: flex-start
/* 右对齐 */
justify-content:flex-end
/* 居中对齐 */
justify-content: center
/* 两端贴边对齐 */
justiify-content: space-between
/* 两端空隙对齐 */
justify-content: space-around

交叉轴对齐方式
交叉轴对齐方式分成两种,一种是只设置单行线 align-items 在交叉轴上对齐

/* 左对齐 */
align-items: flex-start

/* 右对齐 */
align-items: flex-end

/* 居中 */
align-items: center 

/* 拉伸 */
align-items: stretch

/* 基线对齐 */
align-items: baseline

第二种是设置交叉轴上的两条线以上的对齐方式 使用 align-content

/* 拥有 align-items 除基线对齐*/
/* 两端对齐 */
align-content: space-around
align-content: space-between

项目属性

项目的排列顺序

可以使用 order 来进行,数值越小越靠前,默认值是0

项目缩放

项目放大有空闲位置时放大比例 flex-grow 默认值0 不放大

flex-grow: 0

在空闲位置不够的时候,使用 flex-shrink 默认值 1 会缩小

flex-shrink: 1

项目本身的大小,可以用数值和百分比固定, auto 表示原本大小

flex-basis: auto

缩放和本身大小可以使用合写属性 flex 来表示

flex: <flex-grow> <flex-shrink> <flex-basis>
/* 缩写 */
flex: 1

/* flex: auto */
flex: 1 1 auto

/* flex: none */
flex: 0 0 auto

单独设置某个项目的对齐方式

/* 其余属性和align-items一样 */
align-self: auto

flex实战

网格布局

.Grid {
    display: flex;
  }
  .Grid-cell {
    background: #ccc;
    margin-left: 10px;
    flex: 1;
  }
  .Grid-cell.u-full {
    flex: 0 0 100%;
  }

  .Grid-cell.u-1of2 {
    flex: 0 0 50%;
  }

  .Grid-cell.u-1of3 {
    flex: 0 0 33.3333%;
  }

  .Grid-cell.u-1of4 {
    flex: 0 0 25%;
  }

<div class="Grid">
  <div class="Grid-cell u-1of4">...</div>
  <div class="Grid-cell">...</div>
  <div class="Grid-cell">...</div>
</div>

圣杯布局

  .HolyGrail {
    display: flex;
    min-height: 100vh;
    flex-direction: column;
  }
  header,
  footer {
    flex: 1;
    border: 1px solid #ccc;
  }
  .HolyGrail-body {
    display: flex;
    flex: 6;
  }
  .HolyGrail-nav,
  .HolyGrail-ads {
    flex: 0 0 12em;
    border: 1px solid #ccc;
  }
  .HolyGrail-ads {
    order: -1;
  }
  .HolyGrail-content {
    flex: 1;
  }
  @media (max-width: 765px) {
    .HolyGrail-body {
      flex-direction: column;
    }
    .HolyGrail-content,
    .HolyGrail-nav,
    .HolyGrail-ads {
      flex: auto;
    }
  }

<div class="HolyGrail">
  <header>...</header>
  <div class="HolyGrail-body">
    <main class="HolyGrail-content">...</main>
    <nav class="HolyGrail-nav">...</nav>
    <aside class="HolyGrail-ads">...</aside>
  </div>
  <footer>...</footer>
</div>

输入框布局

  .InputAddOn {
    display: flex;
  }
  .InputAddOn-field {
    flex: 1;
  }

<div class="InputAddOn">
  <span class="InputAddOn-item">...</span>
  <input class="InputAddOn-field" />
  <button class="InputAddOn-item">...</button>
</div>

悬挂式布局

   .Media {
     display: flex;
     align-items: flex-start;
   }
   .Media-bod {
     margin-left: 1em;
     flex: 1;
   }

<div class="Media">
   <img class="Media-figure" src="" alt="image" />
   <p class="Media-body">...</p>
 </div>

固定布局

  .fixed {
    display: flex;
    min-height: 100vh;
    flex-direction: column;
  }
  .Site-content {
    flex: 1;
  }
  
<div class="fixed">
  <header>...</header>
  <main class="Site-content">...</main>
  <footer>...</footer>
</div>

文章作者: 时秋
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 时秋 !
  目录