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

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

flex浏览器支持程度

what for?

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

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

看完整篇文章后,你会以为这个和 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 实现咱们经常使用的布局。flex

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

水平方向多列自适应布局

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

  1. 传统作法:浮动定位或绝对定位左侧列,右侧列margin实现与左侧列隔离。
<section>

     <article class="left">
       <b>left width-fixed</b>
     </article>

     <article class="right">
       <b>right auto-fill</b>
     </article>

   </section>

样式:flexbox

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);
   }

效果以下:spa

自适应-窄

自适应-宽

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

外边距(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,而后和其它技术的对比,而后在具体问题面前灵活运用。

相关文章
相关标签/搜索