Flexbox 布局完全解析

Flexbox 布局完全解析

最近看到不少,关于布局的讨论,有用百分比自适应的,有用Table layout的,还有用媒体查询的,方法各式各样,每个都可以乐此不疲的讨论个大半天。不过话又说回来,程序员,尤其是搞前端的大多都是喜新厌旧的,这里准备非常非常非常详细的说一下Flexbox布局模式。

Flexbox Layout 模式,旨在实现更方便,更有效的进行布局,很久以前,在我第一次接触到这家伙的时候确实被深深的吸引了。

Flexbox相关名词

Flexbox

( 图片来源:https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Flexible_boxes

感谢MDN,Flexbox的相关名词这里已经标注的足够清楚了,就不一一的去介绍他们了。

Flexbox细节

在进行Flexbox布局之前,我们要明确一点,Flexbox不应该理解成一个简单的属性,他有一个很完整的结构:容器(container)和部件(items)。所有的部件是基于容器来布局的。容器相当于一个大的房子,然后items相当于房子里面的家具,所有的家具都是相对于房子来布局的,并且一般情况下这些家具都是在房子内部的。

Container and items

Container 容器

display

现在我们一起来建一栋房子(Flexbox布局的容器),这一步很简单,只要简单的通过display来进行定义就可以了。

.container{
    display: flex; /*或者 inline-flex */
}

flex-direction

有了房子之后我们就可以在房子里面放置家具了。假设我们的家具必须按顺序排序(先放1号家具,再放2号家具……),那么作为房子的主人,我可以更具自己的喜好,来选择家具放置的方向(横向排、纵向排、正序排、逆序排),这时候就要用到 flex-direction

flex-direction

.container{
    flex-direction: row | row-reverse | column | column-reverse;
}

flex-direction 有下面几个可用的值:

flex-direction:

  • row : 默认方向,横排,从左到右
  • row-reverse 横排,从又到粽
  • column 纵排,从上到下
  • column-reverse 纵排,从下到上

flex-wrap

当我们把所有的家具完整的摆成一排之后,突然发现了这样一个问题,还有2件家具没有地方放怎么办? 这时候 flex-wrap 就派上用场了,它用来指定一排的情况下多余的元素如何处理,他有下面的几个属性:

.container{
    flex-wrap: nowrap | wrap | wrap-reverse;
}

flex-wrap:

  • nowrap : 不换行
  • wrap : 正常换行
  • wrap-reverse : 反转换行

先说 flex-wrap:wrap ,这个很好理解,一排放不下的情况下我可以再换一行来放置我的“家具”。

再说flex-wrap:wrap-reverse ,字面上是反转换行,但是这个反转是什么意思呢?经过实验可以很容易的发现,它反转的仅仅是 cross axismain axis 木有被反转(如果不明白什么是cross axismain axis的话,请仔细再看一下前面的术语介绍的图片),这一点比较出乎我们的意料,需要特别留意。

最后说 flex-wrap:nowrap 如果“家具”刚好一排能放得下,那么会很好理解,但是!如果一排放不下怎么办?如果你沿着墙把所有的部件都放好之后,发现还有3个家具不够放,但是我一定要你放成一排,你会怎么做?杀了我?也许! 但是机器并不会杀了我们,他们会采取妥协的方案,等比缩小所有元素的宽度,以放下全部的部件,是不是听起来很反人类?

flex-wrap

flex-flow

程序员们都是很懒的,因此他们发明了简写,上面介绍了 flex-directionflex-wrap , 如果我同时想指定方向和换行岂不是要写两行?

.container{
    flex-direction: row ;
    flex-wrap: nowrap ;
}

No! No! No! 我们有更加简单的写法

.container{
    flex-flow: row nowrap ;
}

没错!flex-flow就是为了这个场景而诞生的!

.container{
    flex-flow: <‘flex-direction’> || <‘flex-wrap’>
}

justify-content

极端情况我们都解决了,现在考虑一下比较宽松的情况吧,如果我的家具不够排一排,这时候,我又想让他们看起来比较美观的话,我可以通过修改他们的对齐方式来实现:

.container {
  justify-content: flex-start | flex-end | center | space-between | space-around;
}

justify-content:

-flex-start: 常规模式,以 main start 为对齐点 -flex-end: 以 main end 为对齐点 -center: 居中对齐 -space-between: 两边紧贴 main startmain end 中间平均分部 -space-around: 平均分部

justify-content

align-items

在垂直方向我们有 align-items 来处理

.container {
  align-items: flex-start | flex-end | center | baseline | stretch;
}

align-items:

-flex-start: 以 cross-start 为对齐点 -flex-end: 以 cross-end 为对齐点 -center: 居中 -baseline: 文字的基础线 -stretch: 自动伸缩

align-items

Items (部件)

order

默认情况下,flex部件是按照代码的顺序排序的,我们可以使用order在不改变代码的情况下,修改他们的顺序。

.item {
  order: <integer>;
}

order

flex-grow

这个属性比较特殊,grow的意思是生长,也就是说,当我的所有元素排成一排之后,剩下的空间如何去分配。

.item {
  flex-grow: <number>; /* default 0 */
}

这里的grow值可以理解成,占用剩余部分的份数,比如说空余部分是230px,然后我们指定的grow一个是7,一个是3,这样的话会吧空余的部分分成10份(7+3)每份的宽度是23px(230/10),然后第一个grow占用7份也就是161px(7*23),另一个占用69px(3*23)

flex-grow

flex-shrink

损耗比例,和flex-grow相反,如果容器无法放下指定的部件,那么就会平均缩小每个部件的宽度,已到达发下这么多部件的目的。 例如:Contenter的宽度是100px,然后里面有2个宽度为100px的部件,那么如果你指定了不换行的话,浏览器会自动的将这2个部件的宽度同比缩小,即每个的宽度都为50px,这样这2个部件就能放的下了。 但是,有这么一种情况,对于A、B两个部件,A说:我比B牛逼,我不要和B缩小一样的空间,我缩小的空间永远是B的一半! 这时候我们就用到了flex-shrink

.A { flex:1 1 100px;  }
.B { flex:1 2 100px; }
/*flex: 1 1 100px 是 flex-grow: 1, flex-shrink: 1, flex-basis: 20em 的简写*/

这样A,B容器的宽度就分别为67px,33px

flex-basis

指定初始化时候的item的宽度,即main size,后面的flex-grow,flex-shrink都是在这个基础上进行计算的。

.item {
  flex-basis: <length> | auto; /* 默认 auto */
}

flex

前面也说到了,flex是 flex-grow , flex-shrinkflex-basis的简写

.item {
  flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}

align-self

效果类似align-items(上面有介绍),只不过他是针对一个部件来说的,而不是所有的部件。

.item {
  align-self: auto | flex-start | flex-end | center | baseline | stretch;
}

综合应用

好了,让我们看一个简单的Demo,通过flex实现的一个宽度自适应的布局模型。

点击这里查看Demo(如果Demo无法预览,请在评论中告诉我,我会把demo发到你的邮箱中)

order

点击这里查看Demo(如果Demo无法预览,请在评论中告诉我,我会把demo发到你的邮箱中)

参考

Write a response...
Mofei Zhu
publish
挨个儿
2015-02-26 11:33
flex讲解的很清晰、全面、易懂。棒棒哒!
0
 Replay
@挨个儿  
Replay
匿名
2015-02-26 11:33
字母,写的真好
0
 Replay
@  
Replay