阅读 459
flex布局与传统布局对比

flex布局与传统布局对比

flex布局与传统布局对比

布局类型

  1. 盒装模型

布局的传统解决方案,基于盒状模型,依赖 display 属性 + position属性 + float属性。 盒装模型是由margin、border、padding和content几个属性组合形成的。

  1. Flex布局

Flex 是 Flexible Box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性。 任何一个容器都可以指定为 Flex 布局。

盒装模型和flex布局都可以实现各种页面布局。不过盒装模型对于那些特殊布局非常不方便,比如,垂直居中就不容易实现。Flex 布局,可以简便、完整、响应式地实现各种页面布局。下面我们主要通过各种布局方式的实现进行对比,来具体查看这两种布局的区别

flex布局相关语法,点击链接可查看,这里简要的列一下主要内容。

flex布局基本概念

采用 Flex 布局的元素,称为 Flex 容器(flex container),简称"容器"。它的所有子元素自动成为容器成员,称为 Flex 项目(flex item),简称"项目"。 image.png 容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis)。主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end;交叉轴的开始位置叫做cross start,结束位置叫做cross end。 项目默认沿主轴排列。单个项目占据的主轴空间叫做main size,占据的交叉轴空间叫做cross size。

兼容性

image.png

容器的属性

1. flex-direction

属性决定主轴的方向(即项目的排列方向)。

  • row(默认值):主轴为水平方向,起点在左端。
  • row-reverse:主轴为水平方向,起点在右端。
  • column:主轴为垂直方向,起点在上沿。
  • column-reverse:主轴为垂直方向,起点在下沿。

2. flex-wrap

flex-wrap属性定义,如果一条轴线排不下,如何换行。

  • nowrap(默认):不换行。
  • wrap:换行,第一行在上方。
  • wrap-reverse:换行,第一行在下方。

3. flex-flow

flex-flow属性是flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap。

4. justify-content

justify-content属性定义了项目在主轴上的对齐方式。

  • flex-start(默认值):左对齐
  • flex-end:右对齐
  • center: 居中
  • space-between:两端对齐,项目之间的间隔都相等。
  • space-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。

5. align-items

align-items属性定义项目在交叉轴上如何对齐。

  • flex-start:交叉轴的起点对齐。
  • flex-end:交叉轴的终点对齐。
  • center:交叉轴的中点对齐。
  • baseline: 项目的第一行文字的基线对齐。
  • stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。

6. align-content

  • align-content属性定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。
  • flex-start:与交叉轴的起点对齐。
  • flex-end:与交叉轴的终点对齐。
  • center:与交叉轴的中点对齐。
  • space-between:与交叉轴两端对齐,轴线之间的间隔平均分布。
  • space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。
  • stretch(默认值):轴线占满整个交叉轴。

项目的属性

  • order : 属性定义项目的排列顺序。数值越小,排列越靠前,默认为0。
  • flex-grow : 属性定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大。(如果所有项目的flex-grow属性都为1,则它们将等分剩余空间(如果有的话)。如果一个项目的flex-grow属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍。)
  • flex-shrink : 属性定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。(如果所有项目的flex-shrink属性都为1,当空间不足时,都将等比例缩小。如果一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小。负值对该属性无效。)
  • flex-basis : 属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。
  • flex : 属性是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto。后两个属性可选。
  • align-self : 属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。

flex布局与传统布局实例对比

骰子的布局单项目

单项目

demo: lxqnsys.com/code-run/#/…

1、只有左上角1个点的情况

image.png

traditional布局

<div class="tra">
  <div class="tra-child  tra-left"></div>
</div>
复制代码
.tra {
    position: relative;
  }
  .tra-left {
    position: absolute;
    left: 0;
    top: 0;
  }
复制代码

flex布局

<div class="flex flex-left">
  <div></div>
</div>
复制代码
  .flex {
    display: flex; 
  }
  .flex-left {
    justify-content: flex; // 项目在主轴上的对齐方式(默认值)左对齐
  }
复制代码

image.png

traditional布局

<div class="tra">
  <div class="tra-center-child"></div>
</div>
复制代码
.tra {
    position: relative;
  }
 .tra-center-child {
    margin: 0 auto;
  }
复制代码

flex布局

<div class="flex flex-center">
  <div ></div>
</div>
复制代码
  .flex {
    display: flex;
  }
  .flex-center {
    justify-content: center;// 项目在主轴上的对齐方式居中
  }
复制代码

image.png

traditional布局

<div class="tra">
      <div class="tra-end"></div>
    </div>
复制代码
.tra {
    position: relative;
  }
.tra-end {
    position: absolute;
    right:0;
    top: 0;
}
复制代码

flex布局

<div class="flex flex-end">
      <div ></div>
    </div>
复制代码
  .flex {
    display: flex;
  }
  .flex-center {
    justify-content: flex-end;// 项目在主轴上的对齐方式右对齐
  }
复制代码

image.png

traditional布局

<div class="tra">
  <div class="tra-mid-left"></div>
</div>
复制代码
.tra {
    position: relative;
  }
.tra-mid-left {
    position: absolute;
    left:0;
    top:calc(50% - 15px);
  }
复制代码

flex布局

<div class="flex middle-left">
  <div ></div>
</div>
复制代码
  .flex {
    display: flex;
  }
.middle-left {
  align-items: center; // 项目在交叉轴上对齐方式  交叉轴的中点对齐。
}
复制代码

image.png

traditional布局

<div class="tra">
  <div class="tra-mid-center"></div>
</div>
复制代码
.tra {
    position: relative;
  }
.tra-mid-center {
    position: absolute;
    left:50%;
    top:50%;
    transform: translate(-50%, -50%);
  }
复制代码

flex布局

<div class="flex middle-center">
  <div ></div>
</div>
复制代码
  .flex {
    display: flex;
  }
middle-center {
    justify-content: center;  //项目在主轴上的对齐方式 居中
    align-items: center;  // 项目在交叉轴上对齐方式  交叉轴的中点对齐。
}
复制代码

image.png

traditional布局

<div class="tra">
  <div class="end-center"></div>
</div>
复制代码
.tra {
    position: relative;
  }
.end-center {
    position: absolute;
    left:50%;
    bottom:0;
    transform: translate(-50%, 0);
  }
复制代码

flex布局

<div class="flex end-center">
  <div ></div>
</div>
复制代码
  .flex {
    display: flex;
  }
.end-center {
    display: flex;
    justify-content: center; //项目在主轴上的对齐方式 居中
    align-items: flex-end;   // 项目在交叉轴上对齐方式  交叉轴的终点对齐
  }
复制代码

image.png

traditional布局

<div class="tra">
  <div class="end-end"></div>
</div>
复制代码
.tra {
    position: relative;
  }
.end-end {
    position: absolute;
    right:0;
    bottom:0;
  }
复制代码

flex布局

<div class="flex end-end">
  <div ></div>
</div>
复制代码
  .flex {
    display: flex;
  }
.end-end {
    justify-content: flex-end; //项目在主轴上的对齐方式 右对齐
    align-items: flex-end;  // 项目在交叉轴上对齐方式  交叉轴的终点对齐
  }
复制代码

对于简单的只有一个div的布局,两种方式对比,代码量差不多

双项目

demo: lxqnsys.com/code-run/#/…

image.png

traditional布局

<div class="tra">
  <div class="tra-left"></div>
  <div class="tra-right"></div>
</div>
复制代码
.tra {
    position: relative;
  }
  .tra-left {
    position: absolute;
    left: 0;
    top: 0;
  }
  .tra-right {
    position: absolute;
    right: 0;
    top: 0;
  }
复制代码

flex布局

<div class="flex flex-left">
      <div ></div>
      <div ></div>
    </div>
复制代码
  .flex {
    display: flex;
  }
  .flex-left {
    justify-content: space-between;  //项目在主轴上的对齐方式 两端对齐,项目之间的间隔都相等。
  }
复制代码

image.png

traditional布局

<div class="tra">
  <div class="tra-left-top"></div>
  <div class="tra-left-bottom"></div>
</div>
复制代码
.tra {
    position: relative;
  }
  .tra-left-top {
     position: absolute;
    left: 0;
    top: 0;
  }
  .tra-left-bottom {
    position: absolute;
    left: 0;
    bottom: 0;
  }
复制代码

flex布局

<div class="flex flex-left-left">
      <div ></div>
      <div ></div>
    </div>
复制代码
  .flex {
    display: flex;
  }
  .flex-left-left {
    flex-direction: column; // 主轴为垂直方向,起点在上沿。
    justify-content: space-between; //项目在主轴上的对齐方式 两端对齐,项目之间的间隔都相等。
  }
复制代码

image.png

traditional布局

<div class="tra">
  <div class="tra-mid-top"></div>
  <div class="tra-mid-bottom"></div>
</div>
复制代码
.tra {
    position: relative;
  }
.tra-mid-top {
    position: absolute;
    left: 50%;
    top: 0;
    transform: translate(-50%, 0);
  }
  .tra-mid-bottom {
    position: absolute;
    left: 50%;
    bottom: 0;
    transform: translate(-50%, 0);
  }
复制代码

flex布局

<div class="flex flex-center">
      <div ></div>
      <div ></div>
    </div>
复制代码
  .flex {
    display: flex;
  }
  .flex-center {
    flex-direction: column; // 主轴为垂直方向,起点在上沿。
    justify-content: space-between; //项目在主轴上的对齐方式 两端对齐,项目之间的间隔都相等。
    align-items: center; // 项目在交叉轴上  交叉轴的中点对齐。
  }
复制代码

image.png

traditional布局

<div class="tra">
  <div class="tra-right-top"></div>
  <div class="tra-right-bottom"></div>
</div>
复制代码
.tra {
    position: relative;
  }
.tra-right-top {
    position: absolute;
    right:0;
    top:0;
  }
  .tra-right-bottom {
    position: absolute;
    right:0;
    bottom:0;
  }
复制代码

flex布局

<div class="flex right-bottom">
      <div ></div>
      <div ></div>
    </div>
复制代码
  .flex {
    display: flex;
  }
   .right-bottom {
    flex-direction: column; // 主轴为垂直方向,起点在上沿。
    justify-content: space-between; //项目在主轴上的对齐方式 两端对齐,项目之间的间隔都相等。
    align-items: flex-end; // 项目在交叉轴上  交叉轴的终点对齐。
  }
复制代码

image.png

traditional布局

 <div class="tra">
      <div class="tra-left-top"></div>
      <div class="tra-mid-center"></div>
    </div>
复制代码
.tra {
    position: relative;
  }
.tra-left-top {
     position: absolute;
    left: 0;
    top: 0;
  }
 .tra-mid-center {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
  }
复制代码

flex布局

 <div class="flex middle-center">
      <div class="flex-child"></div>
      <div class="flex-child"></div>
    </div>
复制代码
  .middle-center {
    display: flex;
  }
  .middle-center .flex-child:nth-child(2) {
    align-self: center; // 属性允许单个项目有与其他项目不一样的对齐方式,居中
  }
复制代码

三项目

demo: lxqnsys.com/code-run/#/…

image.png

traditional布局

 <div class="tra">
    <div class="tra-child tra-mid-top"></div>
  <div class="tra-child tra-mid-middle"></div>
  <div class="tra-child tra-mid-bottom"></div>
</div>
复制代码
.tra {
    position: relative;
  }
.tra-mid-top {
    position: absolute;
    left: 50%;
    top: 0;
    transform: translate(-50%, 0);
  }
  .tra-mid-middle {
      position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
  }
  .tra-mid-bottom {
    position: absolute;
    left: 50%;
    bottom: 0;
    transform: translate(-50%, 0);
  }
复制代码

flex布局

 <div class="flex middle-center">
      <div ></div>
      <div ></div>
      <div ></div>
    </div>
复制代码
.flex {
   display: flex;
}
  .middle-center {
    flex-direction: column; // 主轴为垂直方向,起点在上沿。
    justify-content: space-between; // 项目在主轴上的对齐方式 两端对齐,项目之间的间隔都相等。
    align-items: center; // 项目在交叉轴上  交叉轴的终点对齐。
  }
复制代码

image.png

traditional布局

 <div class="tra">
    <div class="tra-child tra-right-middle"></div>
      <div class="tra-child tra-left-middle"></div>
      <div class="tra-child tra-mid-center"></div>
</div>
复制代码
.tra {
    position: relative;
  }
.tra-right-middle {
    position: absolute;
    right:0;
    top:50%;
    transform: translate(0, -50%);
  }
  .tra-left-middle {
     position: absolute;
    left: 0;
    top: 50%;
    transform: translate(0, -50%);
  }
  .tra-mid-center {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
  }
复制代码

flex布局

 <div class="flex middle-center">
      <div ></div>
      <div ></div>
      <div ></div>
    </div>
复制代码
.flex {
   display: flex;
}
  .middle-center {
    justify-content: space-between; // 两端对齐,项目之间的间隔都相等。
    align-items: center; // 交叉轴的中点对齐
  }
复制代码

其他

demo: lxqnsys.com/code-run/#/…

image.png

traditional布局

<div class="box">
  <div class="box-column-top">
     <span class="item item-left"></span>
    <span class="item item-right"></span>
  </div>
  <div class="box-column-bottom">
     <span class="item item-left"></span>
    <span class="item item-right"></span>
  </div>
</div>
复制代码
.box {
  position: relative;
  float: left;
  margin-left: 320px;
}
.box-column-top {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
}
.item-left {
  position: absolute;
  left: 0;
  top: 0;
}
.item-right {
  position: absolute;
  right: 0;
  top: 0;
}
.box-column-bottom {
  width: 100%;
  position: absolute;
  left: 0;
  bottom: 20px;
}
复制代码

flex布局

<div class="box">
  <div class="column">
    <span class="item"></span>
    <span class="item"></span>
  </div>
  <div class="column">
    <span class="item"></span>
    <span class="item"></span>
  </div>
</div>
复制代码
.box {
  display: flex;
  flex-wrap: wrap;  // 换行,第一行在上方。
  align-content: space-between; // 与交叉轴两端对齐,轴线之间的间隔平均分布。
}

.column {
  flex-basis: 100%; // 定义了在分配多余空间之前,项目占据的主轴空间100%
  display: flex;
  justify-content: space-between; // 两端对齐,项目之间的间隔都相等。
}
复制代码

image.png

traditional布局

<div class="box">
  <div class="box-column-top">
     <span class="item item-left"></span>
    <span class="item item-right"></span>
  </div>
  <div class="box-column-bottom">
     <span class="item item-left"></span>
    <span class="item item-right"></span>
  </div>
</div>
复制代码
.box {
  position: relative;
  float: left;
  margin-left: 320px;
}
.box-column-top {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
}
.item-left {
  position: absolute;
  left: 0;
  top: 0;
}
.item-right {
  position: absolute;
  right: 0;
  top: 0;
}
.box-column-bottom {
  width: 100%;
  position: absolute;
  left: 0;
  bottom: 20px;
}
复制代码

flex布局

<div class="box">
  <div class="column">
    <span class="item"></span>
    <span class="item"></span>
  </div>
  <div class="column column-center">
    <span class="item"></span>
  </div>
  <div class="column">
    <span class="item"></span>
    <span class="item"></span>
  </div>
</div>
复制代码
.box {
  display: flex;
  flex-wrap: wrap; // 换行,第一行在上方。
  align-content: space-between; // 与交叉轴两端对齐,轴线之间的间隔平均分布。
}

.column {
  flex-basis: 100%; // 定义了在分配多余空间之前,项目占据的主轴空间100%
  display: flex;
  justify-content: space-between; // 两端对齐,项目之间的间隔都相等。
}
.column-center {
  display: flex;
  justify-content: center; // 项目在主轴上的对齐方式 center
}
复制代码

image.png

traditional布局

<div class="box">
  <div class="box-column-top">
    <span class="item item-left"></span>
    <span class="item item-center-center"></span>
    <span class="item item-right"></span>
  </div>
  <div >
    <span class="item item-left-center"></span>
  </div>
  <div class="box-column-bottom">
    <span class="item item-left"></span>
    <span class="item item-center-center"></span>
    <span class="item item-right"></span>
  </div>
</div>
复制代码
.box-column-top {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
}
.item-left-center {
  position: absolute;
  right:0;
  top:50%;
  transform: translate(0, -50%);
}
.item-left {
  position: absolute;
  left: 0;
  top: 0;
}
.item-right {
  position: absolute;
  right: 0;
  top: 0;
}
.box-column-bottom {
  width: 100%;
  position: absolute;
  left: 0;
  bottom: 20px;
}
.item-center-center {
  position: absolute;
  left:50%;
  top:0;
  transform: translate(-10px, 0);
}
复制代码

flex布局

<div class="box">
  <div class="column">
    <span class="item"></span>
    <span class="item"></span>
    <span class="item"></span>
  </div>
  <div class="column column-right">
    <span class="item"></span>
  </div>
  <div class="column">
    <span class="item"></span>
    <span class="item"></span>
    <span class="item"></span>
  </div>
</div>
复制代码
.box {
  display: flex;
  flex-wrap: wrap; // 换行,第一行在上方。
  align-content: space-between; // 与交叉轴两端对齐,轴线之间的间隔平均分布。
}

.column {
  flex-basis: 100%; // 定义了在分配多余空间之前,项目占据的主轴空间100%
  display: flex;
  justify-content: space-between;// 两端对齐,项目之间的间隔都相等。
}
.column-right {
  display: flex;
  justify-content: flex-end; // 项目在主轴上的对齐方式  右对齐
}
复制代码

明显可以看出,当布局结构变的越来越复杂时,flex的优势就比较明显了。代码量小很多

网格布局

demo:lxqnsys.com/code-run/#/…

flex布局 image.png

<div class="flex">
    <h2>flex布局</h2>
    <div class="box Grid">
      <div class="Grid-cell">1/2</div>
      <div class="Grid-cell">1/2</div>
    </div>
    <div class="box Grid">
      <div class="Grid-cell">1/3</div>
      <div class="Grid-cell">1/3</div>
      <div class="Grid-cell">1/3</div>
    </div>
    <div class="box Grid">
      <div class="Grid-cell">1/4</div>
      <div class="Grid-cell">1/4</div>
      <div class="Grid-cell">1/4</div>
      <div class="Grid-cell">1/4</div>
    </div>
  </div>
复制代码
.flex {
  background: rgb(218, 218, 218);
}
.box .Grid-cell {
  background: rgb(17, 255, 255);
  height: 32px;
  line-height: 32px;
  margin:0.25%;
}
.Grid {
  display: flex;
}
.Grid .Grid-cell {
  margin-top:12px;
  flex: 1; // 将等分主轴的剩余空间
}
复制代码

传统布局

image.png

<div class="tra">
    <h2>传统布局</h2>
    <div class="tra-Grid">
      <div class="Grid-cell-right Grid-item">1/2</div>
      <div class="Grid-cell-left Grid-item">1/2</div>
    </div>
    <div class="tra-Grid">
      <div class="Grid-cell-three Grid-item">1/3</div>
      <div class="Grid-cell-three Grid-item">1/3</div>
      <div class="Grid-cell-three Grid-item">1/3</div>
    </div>
    <div class="tra-Grid">
      <div class="Grid-cell-four Grid-item">1/4</div>
      <div class="Grid-cell-four Grid-item">1/4</div>
      <div class="Grid-cell-four Grid-item">1/4</div>
      <div class="Grid-cell-four Grid-item">1/4</div>
    </div>
  </div>
复制代码
.tra {
  background: rgb(218, 218, 218);
}
.tra-Grid {  
  width:100%;
  clear: both;
}
.Grid-item {
  background: rgb(17, 255, 255);
  height: 32px;
  line-height: 32px;
  margin:0.25%;
}
.Grid-cell-right {
  float: right; 
  width:49.5%;
}
.Grid-cell-left {
  float: left; 
  width:49.5%;
}
.Grid-cell-three {
  width:32.83%;
  float: left;
}
.Grid-cell-four {
   width:24.5%;
  float: left;
}
复制代码

百分比布局

demo:lxqnsys.com/code-run/#/…

传统布局

image.png

<div class="tra">
    <h2>传统布局</h2>
    <div class="tra-Grid">
      <div class="Grid-cell-right Grid-item">1/2</div>
      <div class="Grid-cell-auto Grid-item">auto</div>
      <div class="Grid-cell-auto Grid-item">auto</div>
    </div>
    <div class="tra-Grid">
      <div class="Grid-item Grid-item-auto3">auto</div>
      <div class="Grid-cell-three Grid-item">1/3</div>
     
    </div>
    <div class="tra-Grid">
      <div class="Grid-cell-four Grid-item">1/4</div>
      <div class="Grid-cell-auto4 Grid-item">auto</div>
      <div class="Grid-cell-auto5 Grid-item">auto</div>
     
    </div>
  </div>
复制代码
.tra {
  background: rgb(218, 218, 218);
}
.tra-Grid {  
  width:100%;
  clear: both;
}
.Grid-item {
  background: rgb(17, 255, 255);
  height: 32px;
  line-height: 32px;
  margin:0.25%;
}
.Grid-cell-right {
  width:49.25%;
  float: left;
}
.Grid-cell-auto {
   width:24.625%;
  float: left;
}
.Grid-item-auto3 {
  width:66%;
  float: left;
}
.Grid-cell-left {
  float: left; 
  width:49.5%;
}
.Grid-cell-three {
  width:32.83%;
  float: left;
}
.Grid-cell-four {
   width:24.5%;
  float: left;
}
.Grid-cell-auto4 {
    width:41.5%;
  float: left;
}
.Grid-cell-auto5 {
    width:32.5%;
  float: left;
}
复制代码

flex布局 image.png

<div class="flex">
    <h2>flex布局</h2>
    <div class="box Grid">
      <div class="Grid-cell u-lof1">1/2</div>
      <div class="Grid-cell">auto</div>
      <div class="Grid-cell">auto</div>
    </div>
    <div class="box Grid">
      <div class="Grid-cell">auto</div>
      <div class="Grid-cell u-lof2">1/3</div>
    </div>
    <div class="box Grid">
      <div class="Grid-cell u-lof3">1/4</div>
      <div class="Grid-cell">auto</div>
      <div class="Grid-cell u-lof2">auto</div>
    </div>
  </div>
复制代码
.flex {
  background: rgb(218, 218, 218);
}
.box .Grid-cell {
  background: rgb(17, 255, 255);
  height: 32px;
  line-height: 32px;
  margin:0.25%;
}
.Grid {
 display: flex;
 }
.Grid .Grid-cell {
 flex: 1;  // 将等分主轴的剩余空间
 }
.Grid .u-lof1 {
 flex: 0 0 50%; // 不放大,不缩小,将等分主轴的剩余空间 50%
 }
.Grid .u-lof2 {
 flex: 0 0 33.33% // 不放大,不缩小,将等分主轴的剩余空间 33.3%
 }
.Grid .u-lof3 {
 flex: 0 0 25% // 不放大,不缩小,将等分主轴的剩余空间 25%
 }
复制代码

传统布局不能自动平均分配,需要计算所占百分比,固定宽度分配,flex布局只需指定需要设置的元素的宽度占比,其他会自动分配占比,相对于传统布局,更加灵活,写法也更加简单

圣杯布局

demo: lxqnsys.com/code-run/#/…

传统布局

<div class="HolyGrailTra">
    <div class="headerTra">header</div>
    <div class="HolyGrail-body-tra">
      <div class="left">left</div>
      <div class="center">center</div>
      <div class="right">right</div>
    </div>
    <div class="footerTra">footer</div>
  </div>
复制代码
.HolyGrailTra {
  position: relative;
}
.HolyGrailTra div {
  border: 1px solid #ddd;
  line-height: 32px;
}
.headerTra {
 
}
.HolyGrail-body-tra {
   min-height: 100px;
   div {
      width:33.22%;
      float: left;
      min-height: 100px;
   }
}
复制代码

image.png

flex布局

<div class="HolyGrail">
    <div class="header">header</div>
    <div class="HolyGrail-body">
      <div class="left">left</div>
      <div class="center">center</div>
      <div class="right">right</div>
    </div>
    <div class="footer">footer</div>
  </div>
复制代码
.HolyGrail {
  display: flex;
  flex-direction: column; // 主轴为垂直方向,起点在上沿。
}
.HolyGrail div {
  border: 1px solid #ddd;
  line-height: 32px;
}
.HolyGrail .header,
.HolyGrail .footer {
  flex: 0 0 100%; // 不放大,不缩小,将等分主轴的剩余空间 100%
}
.HolyGrail-body {
  display: flex;
  flex: 1; // flex-grow属性1,如果所有项目的flex-grow属性都为1,则它们将等分剩余空间
  min-height: 100px;
}
.HolyGrail-body .left,
.HolyGrail-body .center,
.HolyGrail-body .right {
  flex: 1; // flex-grow属性1,如果所有项目的flex-grow属性都为1,则它们将等分剩余空间
}
复制代码

中间部分元素,子元素需要占比1/3,对于传统布局,只能近似1/3,没办法像flex布局那样,平均分配

悬挂式布局

demo:lxqnsys.com/code-run/#/…

image.png

传统布局

<div class="MediaTra">
    <img src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=4132631755,1579869755&fm=26&gp=0.jpg" alt="这里是图片" />
    <p class="Media-body-tra">
      这里是很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长的文字
    </p>
  </div>
复制代码
.MediaTra {
  img {
    width:100px;
    height:100px; 
    float: left;
  } 
  .Media-body-tra {
    margin:0 0 0 8px;
    float: left;
  }
}
复制代码

flex布局

<div class="Media">
    <img src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=4132631755,1579869755&fm=26&gp=0.jpg" alt="这里是图片" />
    <p class="Media-body">
      这里是很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长的文字
    </p>
  </div>
复制代码
.Media {
  display: flex;
  align-items: flex-start; // 交叉轴的起点对齐
  img {
    width:100px;
    height:100px; 
  } 
}
.Media-body {
  flex: 1;
  margin: 0 0 0 8px;
  padding: 0;
}
复制代码

当界面缩小到一定宽度时,传统布局文字会另外出现在一行,flex布局正常,flex布局很适合移动端布局,可适配多界面。

固定的底栏

demo: lxqnsys.com/code-run/#/…

image.png

传统布局

<div class="SiteTra">
    <div>header</div>
    <div class="Site-content-tra">main content</div>
    <div class="footerTra">footer</div>
  </div>
复制代码
.SiteTra {
   min-height: 200px;
}
.SiteTra div {
  border: 1px solid #ddd;
}
.Site-content-tra {
  min-height:100px;
}
.footerTra {
  position: fixed;
  bottom:0;
  width:100%;
}
复制代码

flex布局

<div class="Site">
    <div>header</div>
    <div class="Site-content">main content</div>
    <div>footer</div>
  </div>
复制代码
.Site {
  display: flex;
  min-height: 200px;
  flex-direction: column; // 主轴为垂直方向,起点在上沿。
}
.Site div {
  border: 1px solid #ddd;
}
.Site-content {
  flex: 1; // flex-grow属性1,如果所有项目的flex-grow属性都为1,则它们将等分剩余空间
}
复制代码

传统布局固定底栏,采取position: fixed;的方法,是相对于当前视窗来定位,固定在底部,flex则是相对于父元素来固定在底部。如果只是视窗中一小部分中的元素,需要相对于固定底栏,传统布局就比较麻烦,flex布局的灵活性优势就突显了。

流式布局

demo: lxqnsys.com/code-run/#/…

image.png

传统布局

 <div class="parentTra">
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
  </div>
复制代码
.parentTra {
   width: 200px;
  height: 150px;
  background-color: rgb(0, 255, 179);
  .item {
    background: rgb(255, 6, 6);
    width:24%;
    float: left;
    height: 50px;
    border: 1px solid rgb(153, 153, 153);
  }
}
复制代码

flex布局

 <div class="parent">
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
  </div>
复制代码
.parent {
  width: 200px;
  height: 150px;
  background-color: rgb(0, 255, 179);
  display: inline-flex;
  flex-flow: row wrap;
  align-content: flex-start;
   .item {
    box-sizing: border-box;
    background: rgb(255, 6, 6);
    flex: 0 0 25%;
    height: 50px;
    border: 1px solid rgb(153, 153, 153);
  }
}
复制代码

流式布局中,传统布局,宽度百分比计算时,需要考虑边框的宽度,这时就不是很好给一个精确的平均分配,flex布局可以精确设置25%,是四个子元素平均分配,精确度更高

综合来看:

传统布局 (1)兼容性好 (2)布局繁琐,当遇到需要平均分配宽高时,计算麻烦 (3)在移动端适配时,百分比计算需要考虑边框,不能在移动端有很好的布局

flex布局特点 1、任何元素都可采用flex布局,灵活度更高 2、在需要平均分配空间时,减去繁琐的计算,代码简洁 2、能更好的适配移动端布局

上述是根据flex布局属性实现的不同布局与传统布局的对比,这样就能更直观的看出flex的布局一些优势。 在使用flex语法实现上述布局时,有一些地方不是很明白,为何这样设置会有这样的效果,下面就加了些补充说明:

flex:1 到底代表什么?

在上述圣杯布局和固底布局中,都用到了flex:1这个属性,文档中说明 :flex属性是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto。后两个属性可选。

flex-grow 是属性定义项目的放大比例

flex-shrink 属性定义了项目的缩小比例

flex-basis 给上面两个属性分配多余空间之前, 计算项目是否有多余空间, 默认值为 auto, 即项目本身的大小

那flex:1,如果还原成完整写法,到底是什么呢?下面我们就进行测试

demo: lxqnsys.com/code-run/#/…

image.png

<h2>flex: 1;</h2>
    <div class="container flex">
      <div class="div">我是一个div</div>
      <div class="div">我是一个很多字div</div>
      <div class="div">我是一个更多字而且第三个div</div>
    </div>
     <h2>flex: 1 1 auto;</h2>
    <div class="containerOne flex">
      <div class="div">我是一个div</div>
      <div class="div">我是一个很多字div</div>
      <div class="div">我是一个更多字而且第三个div</div>
    </div>
    <h2>flex: 1 1 0;</h2>
    <div class="containerTwo flex">
      <div class="div">我是一个div</div>
      <div class="div">我是一个很多字div</div>
      <div class="div">我是一个更多字而且第三个div</div>
    </div>
复制代码
.flex{
  display: flex;
}
.container .div{
  border: 1px solid rgb(255, 115, 0);
  flex: 1;
}
.containerOne .div {
  border: 1px solid rgb(255, 175, 3);
  flex: 1 1 auto;
}
.containerTwo .div {
  border: 1px solid rgb(255, 175, 3);
  flex: 1 1 0;
}
复制代码

可以看出,flex为 1 1 auto时,auto 为表示项目本身的大小, 如果设置为 auto, 那么这三个盒子就会按照自己内容的多少来等比例的放大和缩小

flex为 1 1 0时,实际上是 1 1 0px

image.png

那我们如果随便设置一个其他带有长度单位的数字呢, 那么他就不会按项目本身来计算, 所以它不关心内容, 只是把空间等比收缩和放大

所以 flex: 1 === flex: 1 1 任意数字+任意长度单位

参考资料:

www.ruanyifeng.com/blog/2015/0…

zhuanlan.zhihu.com/p/136223806

文章分类
前端
文章标签