Flexbox,更优雅的布局
在设计的眼中,排版的操作是一件很简单的事情,靠左、置中、靠右,我只要点一下,所有元素,就会乖乖的到指定的位置。
但到了前端在排版的实现上,就不是这样了。
我们常常得用一堆其实本来不是这样用的属性来做 hack,比如说用 line-height 来做垂直置中,这样做的确能达到效果,但是在语意上就有点不顺,拿刚刚提到的 line-height 来说,这本来是用来当作段落中的行距,但却因为这个属性能扩展文字的上下空间,结果也被拿来做垂直置中。那有没有一个方法能用来更好地实现 Web 布局呢?
这是 Google 的 Angular。他们几个月前做了一套 UI 来实现在 Angular 上的 Material Design。这套框架用来实现布局的方式,不是以往的 float,而是用了 Flexbox。
Flexbox 是什么呢?就 W3C 官方给到的解释是,这是设计来实现更复杂的版面布局。那我自己对他的定义是,Flexbox 从本质上就是一个 Box-model 的延伸,我们都知道 Box-model 定义了一个元素的盒模型,然而 Flexbox 更进一步的去规范了这些盒模型之间彼此的相对关系。而不需要去用一些很 cheat 的做法,去 hack 一些本来其实不应该用来做版面布局的属性。
身为一个喜欢去玩一些新东西的前端,应该说每个跟互联网有所接触的人,都需要去学新东西。
这是我碰到新东西的时候,一定会问自己的三个问题:
1. 这能做什么?也就是他能解决什么问题?
2. 能用在哪裡?在哪些地方能用这个方法?
3. 为什么能用?他实现所用到的逻辑是什么?
接下来就跟大家分享一下,当初看到 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 值分别为 3、2、1,那么当 flex 作用之后,最左边的 item 实际增加的宽度是多少?从图中可以算到增加的宽度是 90px,于是最后最左边 item 的宽度是 190px。
我们刚才提到 grow 跟 shrink 其实是双胞胎,其实他们真的很像,shrink 表示在 item 总宽度比容器大的时候,为了让 item 填满容器,每个 item 减少的宽度。但是计算的公式却是不一样的。为什么?因为当你在加的时候无所谓,但是在减的时候,如果只计算赋予的 shrink 值,那么很有可能最后减少的宽度比 basis 大,于是 item 的宽度就变成负值。那我们该怎么修正?把 basis 当成参数计算进去,这样就能保证减少的宽度永远小于 basis。所以我们可以得到修正后的公式,一样以最左边为例子,最后计算出来减少 60px,于是 item 就变成 140px。以上脑子不好使,没关系,实际上最常用的只是 flex: 1。
讲到这里,你刚刚讲的好像这东西很厉害的样子,那你有没有一个最快最简单粗暴的方式去说 Flexbox 真的是个好东西?
嗯⋯⋯有点难,不过我想应该可以。
参考:https://ruby-china.org/topics/23767
Flexbox,更优雅的布局的更多相关文章
- Flexbox弹性布局,更优雅的布局
Flexbox,更优雅的布局 Flex 布局教程:语法篇 Flex 布局教程:实例篇 2009年,W3C提出了一种新的方案----Flex布局,可以简便.完整.响应式地实现各种页面布局.目前,它已经得 ...
- CSS 黑魔法小技巧,让你少写不必要的JS,代码更优雅
首页 登录注册 CSS 黑魔法小技巧,让你少写不必要的JS,代码更优雅 阅读 8113 收藏 927 2017-09-26 原文链接:github.com 腾讯云容器服务CSS,立 ...
- PostCSS一种更优雅、更简单的书写CSS方式
Sass团队创建了Compass大大提升CSSer的工作效率,你无需考虑各种浏览器前缀兼,只需要按官方文档的书写方式去写,会得到加上浏览器前缀的代码,如下: .row { @include displ ...
- 使用 Promises 编写更优雅的 JavaScript 代码
你可能已经无意中听说过 Promises,很多人都在讨论它,使用它,但你不知道为什么它们如此特别.难道你不能使用回调么?有什么了特别的?在本文中,我们一起来看看 Promises 是什么以及如何使用它 ...
- async 更优雅异步体验
上一篇<让 Generator 自启动>介绍了通过起动器让 Generator 跑起来,而本篇采用 async 实现更优雅的异步编程. 从例子开始 借用上一篇例子中的例子说起. funct ...
- [改善Java代码]集合运算时使用更优雅的方式
在初中代数中,我们经常会求两个集合的并集.交集.差集等,在Java中也存在着此 类运算,那如何实现呢? 一提到此类集合操作,大部分的实现者都会说:对两个集合进行遍历,即可求出结果.是的,遍历可以实现并 ...
- Lambda表达式, 可以让我们的代码更优雅.
在C#中, 适当地使用Lambda表达式, 可以让我们的代码更优雅. 通过lambda表达式, 我们可以很方便地创建一个delegate: 下面两个语句是等价的 Code highlighting p ...
- 使用Castle扩展Ibatis.Net,面向接口编程-更优雅的代码
使用Ibatis.Net做项目半年了,甚是喜欢,感觉确实是个简单.轻巧的O/R Mapping框架,特别是将Sql配置在Xml文件中,相当于直接将Dao层抽离了出来. 本文假定读者对Ibatis.Ne ...
- 少年,是时候换种更优雅的方式部署你的php代码了
让我们来回忆下上次你是怎么发布你的代码的: 1. 先把线上的代码用ftp备份下来 2. 上传修改了的文件 3. 测试一下功能是否正常 4. 网站500了,赶紧用备份替换回去 5. 替换错了/替换漏了 ...
随机推荐
- mysql 实现 start with
自己写service----> 传入map(idsql,rssql,prior) idsql 查询id rssql 查询结果集 调用 以下方法 @param ids 要查询的起始 ...
- 第一个python实例--监控cpu
#第一个python实例:监控cpu #/bin/bash/env Python from __future__ import print_function from collections impo ...
- IOS8解决获取位置坐标信息出错(Error Domain=kCLErrorDomain Code=0)(转)
标题:IOS8解决获取位置坐标信息出错(Error Domain=kCLErrorDomain Code=0) 前几天解决了在ios8上无法使用地址位置服务的问题,最近在模拟器上调试发现获取位置坐标信 ...
- css优先级问题
关于CSS specificityCSS 的specificity 特性或称非凡性,它是衡量一个衡量CSS值优先级的一个标准,既然作为标准,就具有一套相关的判定规定及计算方式,specificity用 ...
- linux开发摘要
1.linux内核文档链接点击打开链接 2.配置文件 在out\target\product\project\obj\KERNEL_OBJ\.config中可以看到 # CONFIG_MTD_LPDD ...
- for循环嵌套的优化
public static void main(String[] args) { int x = 0; for (int i = 0; i < 2; i++) { ...
- 渗透测试工具Nmap从初级到高级使用教程
本文由阿德马翻译自国外网站,请尊重劳动成果,转载请注明出处,谢谢 Nmap是一款网络扫描和主机检测的非常有用的工具.Nmap是不局限于仅仅收集信息和枚举,同时可以用来作为一个漏洞探测器或安全扫描器.它 ...
- php 安装yar扩展
git:https://github.com/laruence/yar 先克隆 如果没有 git 需要先安装 yum install git 然后 克隆 git clone https://githu ...
- test homework ~ coverage about method printPrimes
/******************************************************* * Finds and prints n prime integers * Jeff ...
- OpenCV2+入门系列(四):计算图像的直方图,平均灰度,灰度方差
本篇懒得排版,直接在网页html编辑器编辑 在图像处理时,我们常常需要求出图像的直方图.灰度平均值.灰度的方差,这里给出一个opencv2+自带程序,实现这些功能. 直方图 对于直方图,使用cv::c ...