- 原文地址:11 things I learned reading the flexbox spec
- 原文做者:David Gilbertson
- 译文出自:掘金翻译计划
- 译者:XatMassacrE
- 校对者:zaraguo,reid3290
在经历了多年的浮动布局和清除浮动的折磨以后,flexbox 就像新鲜空气通常,使用起来是如此的简单方便。javascript
然而最近我发现了一些问题。当我认为它不该该是弹性的时候它倒是弹性的。修复了以后,别的地方又出问题了。再次修复以后,一些元素又被推到了屏幕的最右边。这究竟是什么状况?css
固然了,最后我把它们都解决了,可是黄花菜都凉了并且个人处理方式也基本上没什么规范,就好像那个砸地鼠的游戏,当你砸一个地鼠的时候,另外一个地鼠又冒出来,很烦。前端
无论怎么说,我发现要成为一个成熟的开发者而且真正地学会 flexbox 是须要花时间的。可是不是再去翻阅另外的 10 篇博客,而是决定直接去追寻它的源头,那就是阅读 The CSS Flexible Box Layout Module Level 1 Spec。java
下面这些就是个人收获。react
我过去经常想,若是你想要一个 logo 和 title 在左边,sign in 按钮在右边的 header ...android
点线为了更清晰ios
... 那么你应该给 title 的 flex 属性设置为 1 就能够把其余的条目推到两头了。git
.header {
display: flex;
}
.header .logo {
/* nothing needed! */
}
.header .title {
flex: 1;
}
.header .sign-in {
/* nothing needed! */
}复制代码
这就是为何说 flexbox 是个好东西了。看看代码,多简单啊。github
可是,从某种角度讲,你并不想仅仅为了把一个元素推到右边就拉伸其余的元素。它有多是一个有下划线的盒子,一张图片或者是由于其余的什么元素须要这样作。数据库
好消息!你能够不用说“把这么条目推到右边去”而是更直接地给那个条目定义 margin-left: auto
,就像 float: right
。
举个例子,若是左边的条目是一张图片:
我不须要给图片使用任何的 flex,也不须要给 flex 容器设置 space-between
,只须要给 'Sign in' 按钮设置 margin-left: auto
就能够了。
.header {
display: flex;
}
.header .logo {
/* nothing needed! */
}
.header .sign-in {
margin-left: auto;
}复制代码
你或许会想这有一点钻空子,可是并非,在 概述 里面这个方法就是用来将一个 flex 条目推到 flexbox 的末端的。它甚至还有本身单独的章节,使用 auto margins 对齐。
哦对了,我应该在这里添加一个说明,在这篇博客中我会假设全部的地方都设置了 flex-direction: row
。可是对于 row-reverse
,column
和 column-reverse
也都是适用的。
你或许会想必定有一个直截了当的方法确保在一个容器中全部的 flex 条目都适应地收缩。固然了,若是你给全部的条目设置 flex-shrink: 1
,这不就是它的做用吗?
仍是举例说吧。
假设你有不少的 DOM 元素来显示出售的书籍而且有个按钮来购买它。
(剧透:蝴蝶最后死了)
你已经用 flexbox 安排地很好了。
.book {
display: flex;
}
.book .description {
font-size: 30px;
}
.book .buy {
margin-left: auto;
width: 80px;
text-align: center;
align-self: center;
}复制代码
(你想让 'Buy now' 按钮在右边,即便是很短的标题的时候,那么你就要给他设置 margin-left: auto
。)
这个标题太长了,因此他占用了尽量多的空间,而后换到了下一行。你很开心,生活真美好。你洋洋得意地将代码发布到生产环境而且自信地认为没有任何问题。
而后你就会获得一个惊喜,但不是好的那种。
一些自命不凡的做者在标题中用了一个很长的单词。
那就完了!
若是那个红色的边框表明手机的宽度,而且你隐藏了溢出,那么你就失去你的 'Buy now' 按钮。你的转换率,可怜的做者的自我感受都会遭殃。
(注:幸运的是我工做的地方有一个很棒的 QA 团队,他们维护了一个拥有各类相似于这样的使人不爽的文本的数据库。也正是这个问题特别的促使我去阅读这些细则。)
就像图片展现的那样,这样的表现是由于描述条目的 min-width
初始被设置为 auto
,在这种状况下就至关于 Electroencephalographically 这个单词的宽度。这个 flex 条目就如它的字面意思同样不容许被任何的压缩。
那么解决办法是什么呢?重写这个有问题的属性,将 min-width: auto
改成 min-width: 0
,给 flexbox 指明了对于这个条目能够比它里面的内容更窄。
这样就能够在条目里面处理文本了。我建议包裹单词。那么你的 CSS 代码就会是下面这个样子:
.book {
display: flex;
}
.book .description {
font-size: 30px;
min-width: 0;
word-wrap: break-word;
}
.book .buy {
margin-left: auto;
width: 80px;
text-align: center;
align-self: center;
}复制代码
这样的结果就是这个样子:
重申一下,min-width: 0
不是什么为了特定结果取巧的技术,它是细则中建议的行为 。
下个章节我会处理尽管我明确写明了可是 ‘Buy now’ 按钮仍然不老是 80px 宽的问题。
就像你知道的,flex
属性实际上是 flex-grow
,flex-shrink
和 flex-basis
的简写。
我必须认可为了达到我想要的效果,我在不停地尝试和验证这三个属性上面花费了不少时间。
可是直到如今我才明白,我其实只是须要这三者的一个组合。
flex: 0 1 auto
flex: 1 1 auto
flex: 0 0 auto
我但愿你还不是很惊奇,由于还有让你更惊奇的。
你看,Flexbox Crew (我一般认为 flexbox 团队的皮衣是男女都能穿的尺寸)。对,Flexbox Crew 知道我用得最多的就是这三个属性的组合,因此他们给予了这些组合 对应的关键字。
第一个场景是 initial
的值,因此并不须要关键字。flex: auto
适用于第二种场景,flex: none
是条目不伸缩的最简单的解决办法。
早就该想到它了。
它就好像用 box-shadow: garish
来默认表示 2px 2px 4px hotpink
,由于它被认为是一个 ‘有用的默认值’。
让咱们再回到以前那个丑陋的图书的例子。让咱们的 'Buy now' 按钮更胖一点...
... 我只要设置 flex: none
:
.book {
display: flex;
}
.book .description {
font-size: 30px;
min-width: 0;
word-wrap: break-word;
}
.book .buy {
margin-left: auto;
flex: none;
width: 80px;
text-align: center;
align-self: center;
}复制代码
(是的,我能够设置 flex: 0 0 80px;
来节省一行 CSS。可是设置为 flex: none
能够更清楚地表示代码的语义。这对于那些忘记这些代码是如何工做的人来讲就友好多了。 )
坦白讲,几个月前我才知道 display: inline-flex
这个属性。它会代替块容器建立一个内联的 flex 容器。
可是我估计有 28% 的人还不知道这件事,因此如今你就不是那 28% 了。
或者这件事我并非彻底的懂,可是从某种意义上我能够肯定,当使用 vertical-align: middle
来尝试对齐的时候,它并不会起做用。
如今我知道了,细则里面直接写了,vertical-align 在 flex 条目上不起做用” (注意:就好像 float
同样)。
这并不只仅是一个最佳实践,它相似于外婆说的话,去遵照就行了,不要问为何。
"开发者们在 flex 条目上使用 paddings 和 margins 时,应该避免使用百分比" — 爱你的,flexbox 细则。
下面是我在细则里面看到的最喜欢的一段话。
注解:这个变化糟透了,可是它精准地抓住了世界的当前状态(实现无定法,CSS 无定则)
小心,糖衣炮弹进行中。
你或许知道有时候会出现相邻条目的边缘塌陷。你或许也知道其余的时候不会出现边缘塌陷。
如今咱们都知道相邻的 flex 条目是不会发生边缘塌陷的。
我不肯定我是否真的在意这一点。可是我想到或许有一天,它就会真地有用。就好像我冰箱里有一瓶柠檬汁。
某一天我家来了其余人,而后他会问:"嗨,你这里有柠檬汁吗?",我这时就会告诉他:"有的,就在冰箱里",他会接着说:"谢谢,大兄弟。那么若是我想给一个 flex 条目设置 z-index,我须要指定 position 吗?",我会说:"兄弟,不须要,flex 条目不须要这样。"
一旦 initial
,auto
和 none
都不能知足你的需求时,事情就有点复杂了,可是咱们有 flex-basis
,有趣的是,你知道的,我不知道怎么结束这句话。若是大家有好的建议的话,欢迎留言。
若是你有 3 个 flex 条目,它们的 flex 值分别为 3,3 和 4。那么当 flex-basis
为 0
的话它们就会忽略他们的内容,占据可用空间的 30%,30%,40%。
然而,若是你想要 flex 更友好可是有点不太可预测的话,使用 flex-basis: auto
。这个会将你的 flex 的值设置得更合理,同时也会考虑到一些其余因素,而后为你给出相对合理的宽度。
看看这个很棒的示意图。
我十分肯定我读到的关于 flex 的博客中至少有一篇提到了这一点,可是我也不知道为何,直到我看到上面这张图才想起来。
若是我想让个人 flex 条目垂直对齐,我老是使用 align-items: center
。可是就像 vertical-align
同样,这样当你的条目有不一样的字体大小而且你但愿它们基于 baselines 对齐的时,你须要设置 baseline
才能对齐的更完美。
align-self: baseline
也能够,或许更直观。
下面这段话不论我读几遍,都没法理解它的含义...
在主轴上内容大小是最小内容大小的尺寸,而且是加紧的,若是它有一个宽高比,那么任何定义的 min 和 max 的大小属性都会经过宽高比转换,而且若是主轴的 max 尺寸是肯定的话会进一步加紧。
这些单词经过个人眼睛被转化成电信号穿过个人视神经,刚刚抵达的时候就看到个人大脑打开后门一溜烟跑了。
就像米老鼠和疯狂麦克斯 7 年前生了个孩子,如今和薄荷酒喝醉了,使用他从爸爸妈妈吵架时学到的语言肆意的辱骂周围的人。
女士们,先生们,我已经放弃了体面开始胡言乱语了,这意味着你能够关闭这篇文章了(若是你看这个是为了学习的话你能够在这里中止了)。
读这篇细则我学到的最有趣的事情是,尽管我看过大量的博文,以及 flexbox 也算是相对简单的知识点,可是我对其的了解曾是那么的不完全。事实证实 '经验' 不老是起做用的。
我能够很开心的说花时间来阅读这些细则已经获得了回报。我已经优化的个人代码,设置了 auto margins,flex 的值也设置成了 auto 或者 none,并在须要的地方定义了 min-width 为 0。
如今这些代码看起来好多了,由于我知道这样作是正确的。
个人另一个收获就是,尽管这些细则在某些方面正如我所想的基于编者视角并有些庞杂,可是仍然有有不少友好的说明和例子。甚至还高亮了那些初级开发者容易忽略的部分。
然而,这个是多余的,由于我已经告诉了你全部有用知识点,你就不用再本身去阅读了。
如今,若是大家要求,那么我会再去阅读全部其余的 CSS 细则。
PS:我强烈建议读读这个,一个浏览器 flexbox bugs 的清单:github.com/philipwalto….
掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 Android、iOS、React、前端、后端、产品、设计 等领域,想要查看更多优质译文请持续关注 掘金翻译计划。