Flexbox 布局 与 常见布局需求实现对比

来源:互联网 发布:人工智能电影观后感 编辑:程序博客网 时间:2024/06/08 07:56

Flexbox 布局是 CSS 3 新增的布局模式,在 display 中的值是 display: flex; display: inline-flex;。flex 具有很好的适应性,在电脑浏览器和手机浏览器中都有很好的表现。虽然其标准仍然是“候选(CR)”,但是在各个浏览器已经得到了很广泛的支持。如图1,从图中我们可以看出,flex模块已经得到了几乎所有浏览器的支持,IE11部分支持,我们可以在实际的项目中尝试使用,如果是IE Version<=11的话,要做一定的 polyfill。

flex浏览器支持程度

what for?

flexbox,是’flexible box’ 的缩写,声明为display: flex/inline-box 的元素可以改变子元素的高度和/或宽度,来适应不同大小的浏览器尺寸和显示设备类型,是响应式布局的一种技术。利用块级元素布局基于垂直方向,行内元素基于水平方向,flexbox 则是水平和垂直方向都能很好的适应。关于 Flexbox ,我觉得记住一点就好,声明 display: flex;或者 display: inline-flex;的元素的子 flex 条目会充满父元素的所有空间。

没有 flexbox 时,使用 css 布局时,我们使用 float 、display 和 position,这些技术没有问题,但是实现不是很直观。但是利用这些技术,且对于一些特殊任务实现起来仍然有困难,比如 垂直居中元素。flex 实现这些布局是相当容易的事情,我们可以总结说,Flexbox 就是一种“弹性布局”模型,能很好支持不同视口尺寸和设备。

看完整篇文章后,你会觉得这个和 table 布局十分类似啊!下面说点具体的 【严肃脸】。

内容

说明: 主轴为 flex-direction 指定的方向,侧轴是与主轴方向垂直的轴,借用 MDN 上的一张图说明。main axis 即为主轴,主轴方向开始叫做‘main start’,结束叫做‘main end’;cross axis 为侧轴,开始为 cross start,结束为 cross end。在这里指出这些知识,是因为以下的 flex 的条目对其将会涉及到相应的概念。

MDN轴方向说明图

容器可以设置的属性:

属性 值及其说明 flex-direction 条目放置的方向(主坐标轴),row(默认值),水平放置;column,垂直放置 flex-wrap flex条目溢出父元素时是否应该换行,nowrap(默认值),不换行显示;wrap表示换行,按照父元素的尺寸来布局,如果溢出,那么溢出的将换行显示,最终结果为显示为多行,且无论哪一行,有几个子元素,都会自适应填充满每一行;wrap-reverse,与wrap相同,但是顺序相反 flex-flow flex-direction和flex-wrap的简写,和margin、padding等简写四个方向类似 justify-content 规定flex条目在主轴方向的排布规则。flex-start,条目左对齐,最左边的元素的margin边框将会失效;flex-end,条目右对齐,最右边的元素的margin边框将会失效;center,居中对齐;space-between,沿主轴方向均匀分布,开始和结束margins失效;space-around,沿主轴均匀分布,与space-between不同之处在于开始和结束的margins等于相邻两个flex条目间距的一半 align-item 规定flex条目在侧轴(flex-direction规定的主轴垂直方向)方向的排布规则。flex-start,垂直上对齐;flex-end,垂直下对齐;center,垂直居中对齐;baseline,stretch(默认值),在侧轴方向拉伸flex条目,以期在侧轴方向填满整个容器


条目可以设置的属性:

属性 值及其说明 flex-grow 主轴方向flex条目所占比例,值为Number类型 flex-shrink 主轴方向flex条目缩放比例,值为Number类型 flex-basis 主轴方向flex条目最小尺寸,px或者% flex 是 flex-grow、flex-shrink 和 flex-basis 属性的简写,确立弹性项目的伸缩性 order flex条目在所有flex条目中的次序 align-self 同父元素的align-item,定义了单个弹性项目在侧轴上应当如何对齐,这个定义将覆盖由 align-items 所确立的默认值

看完这些说明,我们来看看如何利用 Flexbox 实现我们常用的布局。

各种常见布局要求的 Flexbox 实现

水平方向多列自适应布局

要求:两列布局,左侧列宽度固定,右侧列自适应,填充整个容器。

  1. 传统做法:浮动定位或绝对定位左侧列,右侧列margin实现与左侧列隔离。
  <section>     <article class="left">       <b>left width-fixed</b>     </article>     <article class="right">       <b>right auto-fill</b>     </article>   </section>

样式:

   html, body{     height: 100%;     margin: 0;     padding: 0;   }   section, article{     height: 100%;   }   .left{     float: left;     width: 300px;     background-color: rgb(255, 0, 0);   }   .right{     margin-left: 300px;     background-color: rgb(0, 255, 0);   }

效果如下:

自适应-窄

自适应-宽

==========附带一提(但是很重要的点)============

外边距(margin)叠加问题,简单的说,就是当两个或更多的垂直外边距相遇时,它们将形成一个外边距,这两个外边距的高度等于两个发生叠加的外边距的高度中的较大者。比如,我在上面的例子中,每一个 article 内的标题都是使用 b 标签,如果我换成 h* 标签,那么就会出现这个问题。如图,我将b 标签换成了 h2,h2 是块级元素,有垂直外边距,在chorme 中,本例的 h2 默认外边距是 19.920 像素,外边距为0的父元素叠加外边距为 19.920 像素的子元素,将会出现 19.920 像素的垂直外边距:

外边距叠加

需要注意,如果父元素是float 定位,那么该问题不会出现,所以你会看到左侧 article 中的 h2 元素外边距在 article 元素中。

  1. 使用 Flexbox 实现

同样是上面的 HTML 结构,样式如下。

      html, body{        height: 100%;        margin: 0;        padding: 0;      }      section, article{        height: 100%;      }      section{        display: flex;      }      .left{        width: 300px;        background-color: rgb(2,138,201);      }      .right{        flex-grow: 1;        background-color: rgb(78,55,115);      }

效果如下图,这下好了,h* 的外边距都在里边了,没有出现外边距叠加了,可见,article元素已经不是普通的定位了。但是要注意,article 高度必须大于 h2 的盒模型总的高度,否则仍然会溢出。

Flexbox实现

垂直方向多行自适应布局

要求:三行布局,第一行和第三行高度固定,第二行自适应,填充整个容器。

  1. 传统做法,使用 table 布局。
    <section>      <header>        <h2>header</h2>      </header>      <article class="content">        <h2>content</h2>      </article>      <footer>        <h2>footer</h2>      </footer>    </section>

样式:

   html, body{     height: 100%;     margin: 0;     padding: 0;   }   section{     height: 100%;     width: 100%;     display: table;   }   .content{     display: table-row;     background-color: rgb(2,138,201);   }   header, footer{     display: table-row;     background-color: rgb(72,82,94);   }   header{     height: 90px;   }   footer{     height: 80px;   }

效果和使用 Flexbox 实现的效果完全一致,这里就不贴图了,可以看 Flexbox 的实现效果图。

  1. Flexbox 实现
   html, body{     height: 100%;     margin: 0;     padding: 0;   }   section{     height: 100%;     display: flex;     flex-direction: column;   }   .content{     flex-grow: 1;     background-color: rgb(2,138,201);   }   header, footer{     background-color: rgb(72,82,94);   }   header{     height: 90px;   }   footer{     height: 80px;   }

这里写图片描述

这里写图片描述

看完效果是不是感觉很 nice 呢。以后遇到这种布局需求,就是用 Flexbox 吧!结合水平的和垂直的布局,可以做出一些复杂的单页应用布局。

水平居中且垂直居中

使用 Flexbox 做页面居中也很容易,

   <section class="container">     <div class="spacer"></div>     <section class="horizontal">       <div class="spacer"></div>       <article class="content">           居中的内容       </article>       <div class="spacer"></div>     </section>     <div class="spacer"></div>   </section>

样式:

    html, body{      height: 100%;      margin: 0;      padding: 0;    }    .container{      height: 100%;      display: flex;      flex-direction: column;      background-color: rgba(0, 0, 0, 0.8);    }    .spacer{      flex: 1;    }    .horizontal{      display: flex;      flex-direction: row;    }    .content{      height: 200px;      width: 400px;      background-color: rgb(255, 255, 255);      color: rgb(0, 0, 0);      border-radius: 4px;      padding: 10px;    }

HTML 中我们使用了四个名为spacer类的垫片,这里主要利用了 flex 条目会占据所有可用空间的特性,让它们把主要的内容挤到中间的位置 ^_^。我给内同区域添加了圆角效果和内边距,最终效果如下图。看到没,就这么简单就做出了一个弹出层,再加上一点鼠标和键盘事件,这不就是一个我们常用的 bootstrap“模态框”么 【笑】。

页面居中的弹出层

有一个叫做绝对居中的技术,我从其他博客作者看到的,内容较多,这里我们不再介绍,找个机会我们和 Flexbox 实现做一个对比。

大屏和小屏之间的响应性

结合 flex-direction , flex-wrap,order 和 媒体查询,做出的布局会有比较好的跨设备的特性。下面举个例子,咱一起看看它们的威力。

  <section>    <nav>      <button> 测试 </button>      <button> 测试 </button>      <button> 测试</button>    </nav>    <article>      主要内容    </article>  </section>

样式:

   html, body{     height: 100%;     margin: 0;     padding: 0;   }   section{     height: 100%;     display: flex;   }   nav{     width: 200px;     display: flex;     background-color: rgb(2,138,201);   }   button{     height: 30px;     flex: 1;   }   article{     flex: 1;     background-color: rgb(72,82,94);   }   @media screen and (max-width: 640px) {     section{       flex-direction: column;     }     nav{       width: 100%;       flex: 1;       order: 2;       flex-direction: row;     }     article{       flex: 3;     }   }   @media screen and (max-width: 320px) {     nav{       flex-direction: column;     }   }

效果,例子中利用媒体查询,根据浏览器宽度分了三个阶段,当然 640,320都是胡诌的,真实情况下,并不是这个界限,合适的尺寸可以参考 Bootstrap 的分段阈值或者根据实际情况制定。多余的我就不说了,你肯定能看懂。

  • >640px,判断为电脑浏览器;
  • 640px > width >320px,判断为平板浏览器;
  • <320px,判断为手机浏览器。

这里写图片描述

这里写图片描述

这里写图片描述

总结

只要理解了 Flexbox 的设计初衷,并了解其属性和值的含义及用处,那么在实际的需求面前就可以很从容的应用这项技术了。这也是我的学习新东西的思路,首先想为什么有这个东西,为解决什么问题的,有什么 API,然后和其它技术的对比,然后在具体问题面前灵活运用。

1 0
原创粉丝点击