上个周末,在北航新主楼会议厅里举行了首届 CSS 开发者大会,GitCafe 的前端工程师 Jaych Su 在会上作了演讲,与你们分享了一款更优雅的前端布局——Flexbox。如今,咱们就邀请他来为你们讲一下 Flexbox 的相关知识吧~前端
在设计的眼中,排版的操做是一件很简单的事情,靠左、置中、靠右,我只要点一下,全部元素,就会乖乖的到指定的位置。git
但到了前端在排版的实现上,就不是这样了。前端工程师
咱们经常得用一堆其实原本不是这样用的属性来作 hack,好比说用 line-height 来作垂直置中,这样作的确能达到效果,可是在语意上就有点不顺,拿刚刚提到的 line-height 来讲,这原本是用来看成段落中的行距,但却由于这个属性能扩展文字的上下空间,结果也被拿来作垂直置中。那有没有一个方法能用来更好地实现 Web 布局呢?框架
这是 Google 的 Angular。他们几个月前作了一套 UI 来实如今 Angular 上的 Material Design。这套框架用来实现布局的方式,不是以往的 float,而是用了 Flexbox。ide
Flexbox 是什么呢?就 W3C 官方给到的解释是,这是设计来实现更复杂的版面布局。那我本身对他的定义是,Flexbox 从本质上就是一个 Box-model 的延伸,咱们都知道 Box-model 定义了一个元素的盒模型,然而 Flexbox 更进一步的去规范了这些盒模型之间彼此的相对关系。而不须要去用一些很 cheat 的作法,去 hack 一些原本其实不该该用来作版面布局的属性。布局
身为一个喜欢去玩一些新东西的前端,应该说每一个跟互联网有所接触的人,都须要去学新东西。性能
这是我碰到新东西的时候,必定会问本身的三个问题:
1. 这能作什么?也就是他能解决什么问题?
2. 能用在哪裡?在哪些地方能用这个方法?
3. 为何能用?他实现所用到的逻辑是什么?flex
接下来就跟你们分享一下,当初看到 Flexbox 的我问了本身这个三个问题以后,到目前为止我找到的答案。网站
举一个例子,全部前端都会有的痛点,置中,咱们之前是怎么实现的?flexbox
最常看到就是用绝对定位,而后把 top 和 left 偏移 五零%,在用 margin 偏移回去。可是这只适用在已经固定大小的元素。
最近几年常看到的作法是这样,在想置中的元素以前,加上一个元素,不想管太旧的 IE 的话,甚至伪元素也能够。在容器用 text-align,而后把底下的两个元素弄成 inline 的形式,在用 vertical-align。他的好处就是,即便底下的元素会随内容改变大小,但无论怎么改变,就是能够始终维持垂直和水平置中。
固然啦,还有不少置中的方法,就不一一介绍了,咱们来看一下用 flex 的话怎么置中。
用 Flex 来作置中的话,你能够很从容地作到置中,不用一堆即便原本不是这样用的属性。我只要先指定容器为一个 Flex 容器,而后 justify-content 让他水平方向置中,再 align-items 让他垂直方向置中。我能够很简单很优雅的就作到置中。
那也许你会说,欸?既然一个能够的话,那我再多放几个可不能够?其实能够的。
假设咱们如今容器底下有三个元素,喔,这裡就要提到 Flexbox 另一个屌炸天的功能。
假设一个元素是四零%,另外一个是一二%,那在一个 Flex 容器中,只要你有设定 flex-grow 这项属性的话,他的第三个元素就会自适应宽度,填满剩下容器的空白。而在多个元素的状态之下,咱们仍然能很轻易的就置中。
刚刚咱们提到过,flexbox 是用来规范盒模型之间的相对关系,从这裡你就能够看到。如今我将 justify-content 设成 space-around,元素就会变成已分散对齐的方式去分佈在 flex 容器中。
关于元素的分步,咱们再来看几个例子。
这是一个我最近看到的网站。咱们能够看到他底下有一个 Slider,这有个问题,并且也经常是前端在版面上的一个痛点,咱们想让全部的子元素可以等高。在之前咱们很难只用 CSS 去作到这样。
而 flexbox 能够很轻易地只用 CSS 作到这点。只须要在 flex 容器加上 align-items 就好。就能实现容器底下的全部元素,与最高的那个元素等高。
即便我在原本最高的那个元素多加一些内容,其余的元素也必定会维持等高。
Flex 最初被 W3C 于 09 年制定出来,随后就被大量的讨论。拿指定元素为一个 flex 容器来说,第一个版本裡是 display:box,第二个版本是 display: flexbox,第三个版本是 display: flex。实在太复杂,还好如今在开源的世界里已经有大大把这三个版本的 flex 作成一些 mixin,使用的时候,你只要 include 进来就能够。
就跟 IE 的使用体验同样,全部的好东西跟 IE 基本都沾不上边,因此若是你须要考虑 IE 用户,那请慎入。因此有人说 IE 的功能只剩下用来下载 Chrome 和 Firefox。
若是你到网上搜 flex,大多都会著墨在 他的对齐、他的控制 DOM 顺序是如何如何好用。但今天咱们想聊一聊更深一点的东西,flex item 宽度的计算,大多数状况下,咱们只在乎显示的比例,这也是宽度的计算比较少被讨论的缘由,但若是你想要更精确的控制 item 的显示宽度,其实你是须要去了解,在一个 flex 容器当中,item 的宽度是如何被计算出来的。
当咱们把一个容器指定为 flex 容器时,它裡面的 item 实际上是有著这样的设定:flex: 0 1 auto
这三个数字其实分别表明:flex-grow、flex-shrink、flex-basis,这三个属性能够说是 flex 之因此智能的缘由。
咱们先来聊聊 flex-basis 好了,这个属性在 flex 容器为横向的时候,其实就是宽度,当咱们把 item 指定成 flex: 0 0 480px 时,其实就是把它的宽度设定成 480px。可是这样并不能表现出 flex 有什么特别的地方啊?为什麽要重複设定宽度?
这时候就要讲到另外两个属性:flex-grow、flex-shrink
这两个属性实际上是双胞胎,grow 表示在 item 总宽度比容器小的时候,为了让 item 填满容器,每一个 item 增长的宽度。假设有三个 basis 为 100px 的 item。咱们从左到右给予 grow 值分别为 三、二、1,那么当 flex 做用以后,最左边的 item 实际增长的宽度是多少?从图中能够算到增长的宽度是 90px,因而最后最左边 item 的宽度是 190px。
咱们刚才提到 grow 跟 shrink 实际上是双胞胎,其实他们真的很像,shrink 表示在 item 总宽度比容器大的时候,为了让 item 填满容器,每一个 item 减小的宽度。可是计算的公式倒是不同的。为何?由于当你在加的时候无所谓,可是在减的时候,若是只计算赋予的 shrink 值,那么颇有可能最后减小的宽度比 basis 大,因而 item 的宽度就变成负值。那咱们该怎么修正?把 basis 当成参数计算进去,这样就能保证减小的宽度永远小于 basis。因此咱们能够获得修正后的公式,同样以最左边为例子,最后计算出来减小 60px,因而 item 就变成 140px。以上脑子很差使,不要紧,实际上最经常使用的只是 flex: 1。
讲到这里,你刚刚讲的好像这东西很厉害的样子,那你有没有一个最快最简单粗暴的方式去说 Flexbox 真的是个好东西?
嗯⋯⋯有点难,不过我想应该能够。