Flexbox 布局是 CSS 3 新增的布局模式,在 display 中的值是 display: flex; display: inline-flex;
。flex 具备很好的适应性,在电脑浏览器和手机浏览器中都有很好的表现。虽然其标准仍然是“候选(CR)”,可是在各个浏览器已经获得了很普遍的支持。如图1,从图中咱们能够看出,flex模块已经获得了几乎全部浏览器的支持,IE11部分支持,咱们能够在实际的项目中尝试使用,若是是IE Version<=11的话,要作必定的 polyfill。css
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 的条目对其将会涉及到相应的概念。布局
容器能够设置的属性:学习
属性 | 值及其说明 |
---|---|
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
<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 元素中。
一样是上面的 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 的盒模型总的高度,不然仍然会溢出。
<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 的实现效果图。
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 的分段阈值或者根据实际状况制定。多余的我就不说了,你确定能看懂。
只要理解了 Flexbox 的设计初衷,并了解其属性和值的含义及用处,那么在实际的需求面前就能够很从容的应用这项技术了。这也是个人学习新东西的思路,首先想为何有这个东西,为解决什么问题的,有什么 API,而后和其它技术的对比,而后在具体问题面前灵活运用。