一篇完整的FlexBox布局指南

一篇完整的FlexBox布局指南

转载请标注本文连接并附带如下信息: 译:Cydiacen 做者:CHRIS COYIER 原文:A Complete Guide to Flexbox 原文更新于 2016-11-19css

译者的话

出于提高自身英语水平和巩固FlexBox的知识,因而打算翻译一篇比较知名的FlexBox布局的文章,固然这篇文章以前网上已有大漠的译文,这次翻译也有部分参考大漠译文的内容,因而在此贴上大漠译文的地址,以此致敬大佬。《一个完整的Flexbox指南html

为了避免浪费你们时间,先说明下flexBox如今的兼容状况:css3

  • (new)意味着已成为规范的新语法(好比:display:flex;
  • (tweener)意味着是来自2011年一种临时的非官方的语法(display:flexbox;
  • (old)意味着来自2009年的老语法(display:box;
Chorme Safari Firefox Opera IE Android IOS
20- (old) 3.1+ (old) 2-21 (old) 12.1+ (new) 10 (tweener) 2.1+ (old) 3.2+ (old)
21+ (new) 6.1+ (new) 22+ (new) 11+ (new) 4.4+ (new) 7.1+ (new)

黑莓浏览器 10+ 支持新语法。git

关于怎么样混合语法能够获得更好的浏览器支持的信息,能够跳转到《CSS-Tricks》或者《DevOpera》。github

写做背景

Flexbox(弹性盒子)布局模式(目前是个W3C规范草案)旨在为布局,对齐和分布容器内的子项提供一种更加高效的方式,即便这些玩意儿的大小是未知的或者动态变化的。(正如他的名字所示——Flex,弹性的意思)web

Flex布局背后的主要思想是——给指定的容器提供修改其子项的宽、高乃至顺序的能力,而且足够完美的去填充可用的空间(主要是为了适应各类各样的显示设备和屏幕大小)。浏览器

一个使用了Flex布局的容器,将会扩展其子项以致于填充起可用的空间,或者缩小他们以防止溢出容器。app

有一个至关重要的一点,FlexBox布局的方向不像常规布局(块就是垂直从上到下,行就是水平从左到右),它是不可预知方向的。而那些常规的适合页面布局,但对于做用在大型或者复杂的应用程序(特别是当他涉及到方向改变、大小变化、拉伸和收缩等)就缺少灵活性。ide

注意: FlexBox布局最适用于应用程序的组件和小规模布局,而网格布局更适用于大规模的布局。布局

基本要素

由于FlexBox是一整个模块并非一个单独的属性,它涉及到不少东西包括它的全部设置属性。一些属性是须要被设置在容器(父级元素,称为『弹性容器』),而一些其余的属性须要被设置在子元素(称为『弹性项』)中。

若是常规布局是基于块布局与内联布局的方向流的,那么弹性布局就是基于“flex-flow流”。请看一下来自W3C规范的这张图,它解释了弹性布局的主要思想。

基本上,弹性项(flex item)会沿着主轴方向(main-startmain-end)或侧轴方向(cross-startcross-end)排列。

  • 主轴(main axis) - 弹性项主要是沿着弹性容器的主轴进行排列的。要注意一点,他不必定是水平的;这主要仍是看flex-direction属性(见下文)。
  • main-start | main-end - 弹性项将由main-startmain-end方向放置在容器内。
  • main size - 弹性项在主轴方向的宽度或高度就是主轴的尺寸。弹性项主要的大小属性能够是宽度,也能够是高度属性,由哪个对着主轴方向决定。
  • cross axis - 与主轴垂直相交的轴线就是侧轴。它的方向由主轴决定。
  • cross-start | cross-end - 弹性行是由弹性项填充起来的,它的配置是从容器的cross-start开始,往cross-end结束。
  • cross size - 弹性项在侧轴方向的宽度或高度就是cross sizecross size根据侧轴的方向来取决是宽度仍是高度。

父级(弹性容器)属性

display

这个属性是定义在弹性容器上的;根据其值决定是内联仍是块布局。这时它的直属下级将会变成flex文档流。

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

须要注意CSS的columns在flex容器里没有效果。

flex-direction

这个是创建在主轴上的,从而定义了弹性项放置在容器的方向。FlexBox是单方向的布局概念。能够将弹性项视为主要布置在水平行或垂直列中。

.container {
  flex-direction: row | row-reverse | column | column-reverse;
}
  • row(默认):在ltr排版方式下从左向右排列;在rtl排版方式下从右向左排列。
  • row-reverse:与row排列方向相反,在ltr排版方式下从右向左排列;在rtl排版方式下从左向右排列。
  • column:相似于row可是是顶部到底部
  • column-reverse:相似于row-reverse可是是底部到顶部

flex-wrap

弹性项默认会所有集中在一行。你可使用这个属性来改变这种状况,让他们根据你的须要进行自动换行。文档方向在这里也起做用,决定了新的一行被堆叠的方向。

.container{
  flex-wrap: nowrap | wrap | wrap-reverse;
}
  • nowrap(默认):单行显示。在ltr排版下,项目自左向右;在rtl下,自右向左
  • wrap:多行显示。在ltr排版下,项目自左向右;在rtl下,自右向左
  • wrap-reverse:多行显示。与wrap相反

flex-flow(定义在弹性容器中)

这个是flex-directionflex-wrap属性的缩写版,它同时定义了弹性容器的主轴和侧轴。默认是row nowrap

flex-flow: <‘flex-direction’> || <‘flex-wrap’>

justify-content

这属性是用来定义主轴上的对齐方式的。当全部的弹性项在一行而且没法弹性伸展,或者可伸展可是达到了最大尺寸,它能帮助分配剩下的多余空间。而且当他们行内溢出时,这个属性也能够对项目对齐施加一些控制。

.container {
  justify-content: flex-start | flex-end | center | space-between | space-around;
}
  • flex-start(默认):子项会从一行的起始处开始放置
  • flex-end:子项会从一行的结尾处开始放置
  • center:子项会集中在一行的中央
  • space-between:子项会被均匀的分布在行内;首项放置在一行的开始,尾项放置在一行的结束
  • space-around:子项会均匀的按照同等距离分布在一行。须要注意的是,在视觉上会以为并不等距,由于全部子项在两侧都须要加上同等的空间。首项会与容器开始边缘有一个单位空间的距离,可是与下一项会有两个单位空间的距离,由于下一项也有它本身的适配空间。

align-items

这用来定义弹性项目在弹性容器的当前侧轴上的默认行为。能够认为是侧轴版的justity-content

.container {
  align-items: flex-start | flex-end | center | baseline | stretch;
}
  • flex-start:弹性项在侧轴起点边的外边距紧靠住该行在侧轴起始的边。
  • flex-end:弹性项在侧轴起点边的外边距紧靠改行在侧轴结尾的边。
  • center:弹性项会被放置在侧轴的中央。
  • baseline:弹性项会根据他们的基线对齐。
  • stretch(默认):在侧轴方向上拉伸弹性项以至填充满弹性容器。(任听从min-width/max-width

align-content

这个属性会根据在侧轴上的额外空间来排列容器的行,相似于justify-content在主轴在对齐单个弹性项的方式。

注意,这个属性对于只有单行的弹性项来讲是没有效果的。

.container {
  align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}
  • flex-start:行会紧靠容器的起始位
  • flex-end:行紧靠容器的结束位
  • center:行紧靠容器的中间位
  • space-between:每行会均匀分布;首行在容器起始处而最后行在容器结束处
  • space-around:每行根据相同的距离均匀的分布
  • stretch(默认):每行将会伸展以占用剩余的空间。

子项(弹性项)的属性

order

通常来讲,弹性项会按照文档流的顺序进行布局。然而,order属性能够控制他们出如今弹性容器中的顺序。

.item {
  order: <integer>;
}

flex-grow

这个属性给予弹性项在须要的时候能够伸展的能力。它接收一个不带单位的值做为比例。它规定了在容器内的弹性项能够占用多少的可用空间。

若是全部的子项都设置了flex-grow为1,那么容器内的剩余空间会被均匀的分配给全部自项。若是其中一项的值为2,那么这项的占用空间会是其余项的两倍。

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

设置负数是无效的。

flex-shrink

这定义了弹性项在须要的时候具备伸展的能力。

.item {
  flex-shrink: <number>; /* default 1 */
}

负数是无效的。

flex-basis

这定义了,当一个元素在被分配到剩余空间以前的默认大小。它能够是一个长度(如:20%,5rem等)或者一个关键字。auto关键字的意思就是『按照个人宽度和高度属性调整尺寸』(他会暂时根据main-size来布局大小直到被弃用)。若是使用关键字content,意思就是『基于内容调整大小』——不过这个关键字并必定能很好的工做,所以很难去测试或者知晓它的兄弟们max-contentmin-contentfit-content作了什么。

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

若是设置为0,额外空间内容不会被分解开来。若是设置成auto,额外空间会基于它的flex-grow的值进行分布。

flex

这是flex-growflex-shrinkflex-basis组合缩写版。第二个和第三个参数(flex-shrinkflex-basis)是可选的。默认是0 1 auto

推荐你使用的这种缩写属性,这比设置单独属性更好。能够智能的经过缩写形式设置值。

align-self

用来在单独的伸缩项目上覆写默认的对齐方式。

请看下align-items的解释,帮助你了解可用值。

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

注意,floatclearvertical-align在弹性项中会失效。

例子

让咱们从一个很是很是简单的例子开始,解决一个很是平常的问题:完美居中。若是你使用flexBox布局,这将会变得很是简单。

.parent {
  display: flex;
  height: 300px; /* Or whatever */
}

.child {
  width: 100px;  /* Or whatever */
  height: 100px; /* Or whatever */
  margin: auto;  /* Magic! */
}

这个依赖于设置margin值为auto值,会自动获取弹性容器的额外空间。所以设置垂直方向marginauto可让弹性项完美的居中在两个轴。

如今让咱们使用下一些其余属性。

考虑使用一个包含六个项的列表,而且为了视觉审美给他设置了一个固定大小尺寸,但他们也有可能能够自动获取尺寸大小。咱们想要他们能够均匀的,而且完美分布在水平轴上,而且当我改变浏览器的大小,他们仍是能够很好的展现(不须要引用媒体查询!)。

.flex-container {
  /* 咱们先建立一个弹性布局环境*/
  display: flex;
  
  /* 而后若是咱们容许子项换行能够定义flow-direction
   * 记住这相等于:
   * flex-direction: row;
   * flex-wrap: wrap;
   */
  flex-flow: row wrap;
  
  /* 而后咱们再定义怎么样分布剩余的空间 */
  justify-content: space-around;
}

完工。其余的一切不过是美化样式。下面提供一些html,css代码,能够在codePen调试而且改变下浏览器的大小看看会发生什么。
codePen

<ul class="flex-container">
  <li class="flex-item">1</li>
  <li class="flex-item">2</li>
  <li class="flex-item">3</li>
  <li class="flex-item">4</li>
  <li class="flex-item">5</li>
  <li class="flex-item">6</li>
</ul>

SASS:

@import "compass/css3";

.flex-container {
  padding: 0;
  margin: 0;
  list-style: none;
  
  display: -webkit-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
  
  -webkit-flex-flow: row wrap;
  justify-content: space-around;
}

.flex-item {
  background: tomato;
  padding: 5px;
  width: 200px;
  height: 150px;
  margin-top: 10px;
  
  line-height: 150px;
  color: white;
  font-weight: bold;
  font-size: 3em;
  text-align: center;
}

让咱们再尝试下其余东西。想象下,咱们的网站全部页面头部都有个右对齐布局的导航,可是咱们想让他在中等大小的屏幕中居中显示而且在小屏幕设备中单行显示。很是简单。

/* Large */
.navigation {
  display: flex;
  flex-flow: row wrap;
  /* This aligns items to the end line on main-axis */
  justify-content: flex-end;
}

/* Medium screens */
@media all and (max-width: 800px) {
  .navigation {
    /* When on medium sized screens, we center it by evenly distributing empty space around items */
    justify-content: space-around;
  }
}

/* Small screens */
@media all and (max-width: 500px) {
  .navigation {
    /* On small screens, we are no longer using row direction but column */
    flex-direction: column;
  }
}

codePen调试连接

让咱们再来试试一些更加灵活性的弹性项!关于移动先行,3列布局与页眉页脚全屏。和独立的文档顺序。

.wrapper {
  display: flex;
  flex-flow: row wrap;
}

/* We tell all items to be 100% width */
.header, .main, .nav, .aside, .footer {
  flex: 1 100%;
}

/* We rely on source order for mobile-first approach
 * in this case:
 * 1. header
 * 2. nav
 * 3. main
 * 4. aside
 * 5. footer
 */

/* Medium screens */
@media all and (min-width: 600px) {
  /* We tell both sidebars to share a row */
  .aside { flex: 1 auto; }
}

/* Large screens */
@media all and (min-width: 800px) {
  /* We invert order of first sidebar and main
   * And tell the main element to take twice as much width as the other two sidebars 
   */
  .main { flex: 2 0px; }
  
  .aside-1 { order: 1; }
  .main    { order: 2; }
  .aside-2 { order: 3; }
  .footer  { order: 4; }
}

codePen

Flexbox前缀

Flexbox接受一些运营商前缀以支持能够在更多的浏览器上使用。它不只只包括在属性前添加前缀,它也有彻底不一样的属性名字和值名字。这是由于Flexbox规范随着时间一直在变化,所以有了oldtweenernew版本。

固然最好的方式是使用最新的语法,而且经过Autoprefixer运行你的css。

这有一段Sass @mixin可供选择,他也能够给你提供一些须要怎样处理的想法,帮助你处理一些前缀问题。

@mixin flexbox() {
  display: -webkit-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
}

@mixin flex($values) {
  -webkit-box-flex: $values;
  -moz-box-flex:  $values;
  -webkit-flex:  $values;
  -ms-flex:  $values;
  flex:  $values;
}

@mixin order($val) {
  -webkit-box-ordinal-group: $val;  
  -moz-box-ordinal-group: $val;     
  -ms-flex-order: $val;     
  -webkit-order: $val;  
  order: $val;
}

.wrapper {
  @include flexbox();
}

.item {
  @include flex(1 200px);
  @include order(2);
}

相关属性

Bugs

Flex固然不是没有bug,我见过的关于这些bug收集最好的是Philip WaltonGreg WhitworthFlexBugs

相关文章
相关标签/搜索