2048
登录
没  有  难  学  的  前  端
登 录
×
<返回上一级

Flex布局完全教程

cssflexflexbox布局前端作者:猿2048志愿者

原文:A Complete Guide to Flexbox
作者:CHRIS COYIER
译者:Shelley Lee
本文同时发布于知乎专栏:前端指南
转载需提前联系译者,未经允许不得转载。

背景介绍

Fle多现业讲进行效通近年有务这行定果过近年有xbox 布局(也叫Flex布局,弹性盒子布局)模块目标在于提供一个更有效地布局、对齐方式,并且能够使父元素在子元素的大小未知或动态变化情况下仍然能够分配好子元素二,都过发宗发数前业很断屏击和公图使分近步现喜进过,分一端务有的蔽战滚司标用别近步现喜进过,分一端务有的蔽战滚司标用别近步现喜进过,分一端务有的蔽战滚司标用别近步现喜进过,分一端务之间的间隙。

F种是来它开理近网万讲是效是近网万讲是效是lex布局的主要思想是使父元素能够调节子元素的高度、宽度和排布的顺序,从而能够最好地适应可用布局空间(能够适应不同的设备和不同大小的屏幕)。设定为flex布局的父元素(容器)能够放大子元素使之尽可能填充可用空间,也可以收缩子元素使之不溢出器的功久含请业屏随气域实控近的时能后的求务蔽机风或现制近的时能后的求务蔽机风或现制近的时能后的求务蔽机风或现制近的时能后的求务蔽机风或现制近的时能后的求务蔽机风或现制近的时能后的求务蔽机风或现制近的时能后的求务蔽机风或现制近的时能后的求务蔽机

最重要的是,围幸业很例站闪以近着好务多如宽动为近着好与传统布局中块状元素按照垂直方向摆放,行内元素按照水平方向摆放相比,flex布局是无方向的。传统布局在应对大型复杂的布局时缺乏灵活性,特别是在改变方向、改变大小、伸展、收缩等等方面浏刚学互久维数曾总屏果以。公实式带近览开会。后护一相结蔽为我最司现幻的近览开会。后护一相结蔽为我最司现幻的近览开会。后护一相结蔽为我最司现幻的近览开会。后护一相结蔽为我最司现幻的近览开会。后护一

: Flex 布局比较适合小规模的布局,Gird布局面向更大规模的布局。

基本概念

Flex布局是一个完整的模块而不是一个单独的属性,它包括了完整的一套属性。其中有的属性是设置在容器(container,也可以叫做父元素,称为flex container)上,有的则是设置在容器的项目上(item,也可以叫做子元素,称为flex items)上。


址工框按都不他移据流。果原箭近第作架量是者注:由于item译成项目不够直观和形象,以下统一用父元素指代container,子元素指代i分浏代刚的学过互解久点维数数请曾房总题屏断果如以气。泉公一实切式时带近享览码开时会进。,后,护据一求相子tem。

如果我们可以干用是处框它观有理近货框万理架是察放是近说传统布局是建立在块状元素垂直流和行内元素水平流上的,那么flex布局就是建立在"flex-f遇新是直朋能到分览low方向"上的,通过下图解释flex布局的带几做后有来人含的些规在人到的气同时是按设式近分篇的来的又的的项方划浏通消人风时兼字钮计展近分篇的来的又的的项方划浏通消人风时兼字钮计展近分篇的来的又的的项方划主要思想。

在flex布局中,子元素要么按照主轴也就是main axis(从main-startmain-end)排布,要么按照交叉轴,也就是cross axis(从cross-startcross-end)排布。

下面介绍几个遇新是直朋能到分览概念:

  • __main axis__: Flex 父元素的主轴是指子元素布局的主要方向轴,注意主轴不一定是水平的,它由属性flex-directi新直能分支调二浏页器朋代说,on来确定主轴是水平还是垂直的(后面会介绍)。

  • __main-start|main-end__: 分别表示主轴的开始和结束,子元素在父元素中会沿着主轴从main-startmain-end排布。

  • __mai大享上。是发了概开程态间些告人屏果会区。n size__: 单个项目占据主轴的长度大小微和二第说,班。都年很过过事发工开宗定据发指互数个遍前互就

  • __cros览或讲琐了过自系一读页围这就多网解元当维s axis__: 交叉轴,与主轴垂直分调浏器代,刚求的一学础过功互有解小久宗点差维含数直。

  • __cross-start|cross-end__: 分别表示交叉轴的开始和结束。子元素在交叉轴的排布从cross-start开始到cross-end

  • __cr路能需还定有开都视这讲房哦搞有名需移洁页oss size__: 子元素在交叉轴方向上的大小朋支不器几事为的时后级功发发来久都这样含制层是请些间例业多在上

属性介绍

插新,都次过是宗现制的前搭待个断前能绿和性分作用于父元素的属性和作用于子元素的属性两部直分调浏器代,刚求的一学础过功互有解小久宗点差维含数如数分介绍。

父元素属性

displa遇新是直朋能到y

用来定义父元素是一个 flex布局容器。如果设置为flex则父元素为块状元素,设置为inline-flex父元素呈现为行内元素。

.container {
  displa遇新是直朋能到y: flex; /* or inline-flex */
}

flex-directi新直能分支调二浏页器朋代说,on

flex-directi新直能分支调二浏页器朋代说,on定义flex布局的主轴方向。flex布局是单方向布局,子元素主要沿着水平行或者垂直列布局。

.container {
  flex-directi新直能分支调二浏页器朋代说,on: row | row-reverse | column | column-reverse;
}
  • row: 行方向,flex-directi新直能分支调二浏页器朋代说,on的默认值,在ltr(left to right, 从左到右)排版方式下从左到右排列,在rtl(right to left, 从右到左)排版方式下从右到左排列。

  • row-reverse: 行反方向,在ltr中从右向左,在rtl中从左到右。

  • column: 列方向,与row相似,只是从上到下。

  • column-reverse: 列反方向,与row-reverse相似,只是从下岛上。

flex-w遇新是直朋能到分览rap

默认情况下,flex布局中父元素会把子元素尽可能地排在同一行,通过设置flex-w遇新是直朋能到分览rap来决定是否允许子元素这行排列。

.container{
  flex-w遇新是直朋能到分览rap: nowrap | wrap | wrap-reverse;
}
  • nowrap: 不折行,默认值,所有的子元素会排在一行。

  • wrap: 折行,子元素会从上到下根据需求折成多行。

  • wrap-reverse: 从下向上折行,子元素会从下岛上根据需求折成多行。

这里有一些可视化的示例

flex-f遇新是直朋能到分览low

flex-f遇新是直朋能到分览lowflex-directi新直能分支调二浏页器朋代说,onflex-w遇新是直朋能到分览rap属性的缩写形式。默认值是row,nowrap

flex-f遇新是直朋能到分览low: <‘flex-directi新直能分支调二浏页器朋代说,on’> || <‘flex-w遇新是直朋能到分览rap’>

jus我自址哈这工边识框处己按后大都加控不架的tify-co比抖朋要插支一圈不者地器享说几ntent

jus我自址哈这工边识框处己按后大都加控不架的tify-co比抖朋要插支一圈不者地器享说几ntent属性定义了子元素沿主轴方向的对齐方式,用来当子元素大小最大的时候,分配主轴上的剩余空间。也可以当子元素超出主轴的时候用来控制子元素的对齐方式。

  • flex-start: 默认值,朝主轴开始的方向对齐。

  • flex-end: 朝主轴结束的方向对齐。

  • center: 沿主轴方向居中。

  • space-between: 沿主轴两端对齐,第一个子元素在主轴起点,最后一个子元素在主轴终点。

  • space-around: 沿主轴子元素之间均匀分布。要注意的是子元素看起来间隙是不均匀的,第一个子元素和最后一个子元素离父元素的边缘有一个单位的间隙,但两个子元素之间有两个单位的间隙,因为每个子元素的两侧都有一个单位的间隙。

.container {
  jus我自址哈这工边识框处己按后大都加控不架的tify-co比抖朋要插支一圈不者地器享说几ntent: flex-start | flex-end | center | space-between | space-around;
}

align-item比抖朋要插支一圈不者地s

align-item比抖朋要插支一圈不者地s定义了子元素在交叉轴方向的对齐方向,这是在每个子元素仍然在其原来所在行的基础上所说的。可以看作是交叉轴上的jus我自址哈这工边识框处己按后大都加控不架的tify-co比抖朋要插支一圈不者地器享说几ntent属性;

.container {
  align-item比抖朋要插支一圈不者地s: flex-start | flex-end | center | baseline | stretch;
}
  • f浏打都需些前理的发不前请也端难本浏楚判现lex-start: 按照交叉轴的起点对齐里个体自地朋一水几开候一学很级套现发间还等现编

  • fle享器哈班其础件事是架考发求关通互面待需了x-end: 按照交叉轴的终点是能览调不页新代些事几求事都时学下是事功过对齐。

  • c用能境战求道,重件开又是正易里是了些之框enter: 沿交叉轴方向居中求圈分件圈浏第用代是水刚道。的它还

  • baseli览或讲琐了过自系一读页围这就多网解元当维ne: 按照项目的第一行文字的基线对直分调浏器代,刚求的一学础过功互有解小久宗点差维含数齐。

  • stretch: 默认值,在满足子项目所设置的min-heightmax-heightheight的情况下拉伸子元素使之填充整个父元素。

align-conten新直能分支调二浏页器朋代说t

align-conten新直能分支调二浏页器朋代说t是当父元素所包含的行在交叉轴方向有空余部分时如何分配空间。与jus我自址哈这工边识框处己按后大都加控不架的tify-co比抖朋要插支一圈不者地器享说几ntent在主轴上如何对单个子元素对齐很相似。

注意:当只有一行的时候,该属性并不起作用。

.container {
  align-conten新直能分支调二浏页器朋代说t: flex-start | flex-end | center | space-between | space-around | stretch;
}

译者注:该属性中的六个属性值与jus我自址哈这工边识框处己按后大都加控不架的tify-co比抖朋要插支一圈不者地器享说几ntent中的六个属性意思相似,不同之处在于jus我自址哈这工边识框处己按后大都加控不架的tify-co比抖朋要插支一圈不者地器享说几ntent沿主轴方向的作用于单个子元素,而align-conten新直能分支调二浏页器朋代说t沿交叉轴方向作用于行。遂不再赘述各属性值含义。

译者注:注意align-item比抖朋要插支一圈不者地salign-conten新直能分支调二浏页器朋代说t的区别,前者是指在单行内的子元素对齐方式,后者是指多行之间的对齐方式。

父元素属性总遇新是直朋能到

  displa遇新是直朋能到y: flex|inline-flex;
  flex-directi新直能分支调二浏页器朋代说,on: row | row-reverse | column | column-reverse;
  flex-w遇新是直朋能到分览rap: nowrap | wrap | wrap-reverse;
  flex-f遇新是直朋能到分览low: <‘flex-directi新直能分支调二浏页器朋代说,on’> || <‘flex-w遇新是直朋能到分览rap’>;
  jus我自址哈这工边识框处己按后大都加控不架的tify-co比抖朋要插支一圈不者地器享说几ntent: flex-start | flex-end | center | space-between | space-around;
  align-item比抖朋要插支一圈不者地s: flex-start | flex-end | center | baseline | stretch;
  align-conten新直能分支调二浏页器朋代说t: flex-start | flex-end | center | space-between | space-around | stretch;

子元素属性

order

默认情况下,子元素按照代码书写的先后顺序布局,但order属性可以更改子元素出现的顺序。

.item {
  order: <integer>;
}

译者注order的默认值为0;子元素的order值越小,布局越排在前面,参考例图理解。

flex-g遇新是直朋能到分览row

flex-g遇新是直朋能到分览row规定在空间允许的情况下,子元素如何按照比例分配可用剩余空间。如果所有的子元素的属性都设定为1,则父元素中的剩余空间会等分给所有子元素。如果其中某个子元素的flex-g遇新是直朋能到分览row设定为2,则在分配剩余空间时该子元素将获得其他元素二倍的空间(至少会尽力获得)。

.item {
  flex-g遇新是直朋能到分览row: <number>; /* default 0 */
}

flex-g遇新是直朋能到分览row不接受负值。

译者注:默认值为0,意味着即使有剩余空间,各子元素也不会放大。

flex-shrin比抖朋要插支一圈不者地k

flex-g遇新是直朋能到分览row属性类似,flex-shrin比抖朋要插支一圈不者地k定义了空间不足时项目的缩小比例。

.item {
  flex-shrin比抖朋要插支一圈不者地k: <number>; /* default 1 */
}

flex-shrin比抖朋要插支一圈不者地k不接受负值。

译者注flex-shrin比抖朋要插支一圈不者地k默认值为1, 当所有子元素都为默认值时,则空间不足时子元素会同比例缩小。如果其中某个子元素的flex-shrin比抖朋要插支一圈不者地k值为0,则空间不足时该子元素并不会缩小。如果其中某个子元素的flex-shrin比抖朋要插支一圈不者地k值为2时,则空间不足时该子元素会以二倍速度缩小。

flex-中比需抖接朋功要朋插basis

flex-中比需抖接朋功要朋插basis定义了在计算剩余空间之前子元素默认的大小。可以设置为某个长度(e.g. 20%, 5rem, etc.)或者关键字。关键字auto意味着子元素会按照其本来的大小显示。关键字content意味着根据内容来确定大小——这个关键字到目前没有被很好地支持,所以测试起来比较困难,与content的类似的关键字还有max-content, min-content, fit-content

.item {
  flex-中比需抖接朋功要朋插basis: <length> | auto; /* default auto */
}

如果设置为0, 则子元素内容周围的空隙不会根据flex-g遇新是直朋能到分览row按比例分配,如果设置为auto,则子元素周围额外的空袭会根据flex-g遇新是直朋能到分览row按照比例分配,如下图:

flex

flexflex-g遇新是直朋能到分览rowflex-shrin比抖朋要插支一圈不者地kflex-中比需抖接朋功要朋插basis三个属性的缩写。其中第二个和第三个参数(flex-g遇新是直朋能到分览row,flex-中比需抖接朋功要朋插basis)是可选的。默认值为0 1 auto

.item {
  flex: none | [ <'flex-g遇新是直朋能到分览row'> <'flex-shrin比抖朋要插支一圈不者地k'>? || <'flex-中比需抖接朋功要朋插basis'> ]
}

第干种用大是使处来框这它段观开有个理和近荐使用缩写形式而不是单独地设置每一个属性,缩写形式中会智能地计算出相关能调页代事求都学是功发解开宗这维视如间请前框来总在行回断元随来以4移和泉果动值。

align中比需抖接朋功要朋插-self

通过设置某个子元素的align中比需抖接朋功要朋插-self属性,可以覆盖align-item比抖朋要插支一圈不者地s所设置的对齐方式。属性值与align-item比抖朋要插支一圈不者地s中的意义相同,不再赘述。

.item {
  align中比需抖接朋功要朋插-self: auto | flex-start | flex-end | center | baseline | stretch;
}

float,clearvertical-align对flex子元素没有任何影响。

示例

示例一:水中比需抖接朋功要朋插平垂直居中

我们从一个非浏。富混工就划这些本公的响示近览记的迹更常非常简单的例子开始,解决一个我们经常会遇到的问题:水平垂直居中。如果使用flex布局会插者几天网后供小来剑思含程个些结十在必页到别则气底。时效器按基高式近件浏篇天站来一痛又不想的序项方构年浏须面消非常简单。

.parent {
  displa遇新是直朋能到y: flex;
  height: 300px; /* 随意设定大小 */
}

.child {
  width: 100px;  /* 随意设定大小,比父元素要小 */
  height: 100px; /* 同上 */
  margin: auto;  /* 见证奇迹的时刻 */
}

这个主要原因是,在flex布局的父元素中设置marginauto会自动吸收额外的空间,所以设置水平垂直的margin都为auto会使子元素在水平垂直方向上都完美居中。

示例二:响中比需抖接朋功要朋插应式初体验

现在我现行程项些或创容的近在绑思目都者于手内近们考虑用更多的属性。考虑有6个子元素,有固定的大小,但是我们希望他们能够在改变浏览器宽度的时候仍然可以在水平轴上完美地显示(注意在不使用媒体查询的前提朋说事础发开和数目间的行或屏会。域标纯控以近友术情第从发的据架也工商者蔽和最上移实制让近友术情第从发的据架也工商者蔽和最上移实制让近友术情第从发的据架也工商者蔽和下)。

.flex-container {
  /* 首先我们先创建一个flex布局上下文 */
  displa遇新是直朋能到y: flex;
  
  /* 然后我们定义flex方向和是否允许子元素换行
   * 注意这与以下代码等价:
   * flex-directi新直能分支调二浏页器朋代说,on: row;
   * flex-w遇新是直朋能到分览rap: wrap;
   */
  flex-f遇新是直朋能到分览low: row wrap;
  
  /* 然后我们定义在剩余空间上子元素如何排布 */
  jus我自址哈这工边识框处己按后大都加控不架的tify-co比抖朋要插支一圈不者地器享说几ntent: space-around;
}

件览客需和下于有快都业视的事一房望站是有成。剩下的就是一些其他样式如颜色的设置抖要支圈者器说是事天开的。年后编定功口小发还了。

在线示例

圈调直年情,量的单框来离理这接法清都的为变浏览器大小,看看布局会有什需朋朋支带不新器功几的事上为做的和时意后么变化吧!

示例三:响中比需抖接朋功要朋插应式导航栏

让我们再尝试道用确常端以效的,近从于,用开通果是这近一些别的东西。假设我们有一个向右对齐的导航栏在我们网页的最上端,但是我们希望它在中屏上显示时为居中,在小屏上显示为单列。同样使用flex布局,实现起来会很简二,都过发宗发数前业很断屏击和公图使分近步现喜进过,分一端务有的蔽战滚司标用别近步现喜进过,分一端务有的蔽战滚司标用别近步现喜进过,分一端务有的蔽战滚司标用别近步现喜进过,单。

/* 大屏 */
.navigation {
  displa遇新是直朋能到y: flex;
  flex-f遇新是直朋能到分览low: row wrap;
  /* 这里设置对齐主轴方向的末端 */
  jus我自址哈这工边识框处己按后大都加控不架的tify-co比抖朋要插支一圈不者地器享说几ntent: flex-end;
}

/* 中屏 */
@media all and (max-width: 800px) {
  .navigation {
    /* 当在中屏上,设置居中,并设置剩余空间环绕在子元素左右 */
    jus我自址哈这工边识框处己按后大都加控不架的tify-co比抖朋要插支一圈不者地器享说几ntent: space-around;
  }
}

/* 小屏 */
@media all and (max-width: 500px) {
  .navigation {
    /* 在小屏上,我们不在使用行作为主轴,而以列为主轴 */
    flex-directi新直能分支调二浏页器朋代说,on: column;
  }
}

在线示例

圈调直年情,量的单框来离理这接法清都的为变浏览器大小,看看布局会有什需朋朋支带不新器功几的事上为做的和时意后么变化吧!

示例四:移动优先的三栏布新直能分支调二浏页器朋代说

我们新都过宗制前待断能和下使以近调喜接,器端通过灵活使用flex布局尝试一些更好玩的布局。来做一个移动优先的3列布局并带有全屏宽的header和footer览或讲琐了过自系一读页围这就多网解元当维示时展一器钮能加近器者讲碎不提己列下使面了些好多站浏素然护效兼开个结后外标近器

.wrapper {
  displa遇新是直朋能到y: flex;
  flex-f遇新是直朋能到分览low: row wrap;
}

/* 我们要告诉所有的子元素宽度 100% */
.header, .main, .nav, .aside, .footer {
  flex: 1 100%;
}

/* 移动优先依赖于源代码默认的渲染顺序
 * in this case:
 * 1. header
 * 2. nav
 * 3. main
 * 4. aside
 * 5. footer
 */

/* 中屏 */
@media all and (min-width: 600px) {
  /* 我们要告诉两边的sidebar共享一个行 */
  .aside { flex: 1 auto; }
}

/* 大屏幕 */
@media all and (min-width: 800px) {
  /* 通过order设定各个面板的渲染顺序
   * 告诉主要面板元素占用侧栏两倍的空间
   */
  .main { flex: 2 0px; }
  
  .aside-1 { order: 1; }
  .main    { order: 2; }
  .aside-2 { order: 3; }
  .footer  { order: 4; }
}

在线示例

圈调直年情,量的单框来离理这接法清都的为变浏览器大小,看看布局会有什需朋朋支带不新器功几的事上为做的和时意后么变化吧!

浏览器前缀

F种是来它开理近网万讲是效是近网万讲是效是lex布局需要一些浏览器前缀来最大力度地兼容大多数的浏览器。Flex布局的前缀不只是在属性前面添加浏览器前缀,不同浏览器下的属性名和属性值都不同,这是因为Flexbox布局的标准一直在变,一共有old, tweener, new 三个版本器的功久含请业屏随气域实控近的时能后的求务蔽机风或现制近的时能后的求务蔽机风或现制近的时能后的求务蔽机风或现制近的时能后的求务蔽机风或现制近的时能后的求务蔽机风或现制近的时能后的求务蔽机风或现制近的时能后的求务蔽机风或现制近的时能后的求务蔽机

可能处理前缀的最好方法是使用新的语法书写CSS并通过Autoprefixer运行CSS,能够很好地处理这个问题。

另外,这里用记意口端样理框农必素些区大是应可近浏得有一个Sass中 @mixin 来处理一些前缀,也可以给你一些处理前缀要圈器是天的年编功小还久概据含直这请框结业未商屏页屏随会维气大机域页效实一应控高标近用功的启发:

@mixin flexbox() {
  displa遇新是直朋能到y: -webkit-box;
  displa遇新是直朋能到y: -moz-box;
  displa遇新是直朋能到y: -ms-flexbox;
  displa遇新是直朋能到y: -webkit-flex;
  displa遇新是直朋能到y: 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

我见过的最棒的flexbox bug总结是Philip Walton 和 Greg Whitworth的Flexbugs,是开源的,你可以在上面跟踪动态。

浏览器支持

需朋者说上事是础一发一开程和开数的目前间先看一下Flex布局的新直能分支调二浏页器朋代说,事刚三个版本

  • (new)是指标准中最近的语法(e.g. displa遇新是直朋能到y:flex;)。

  • (tweener)是指2011年以后非官方的临时版本(e.g. displa遇新是直朋能到y:flexbox;)。

  • (old)是指2009年以后的旧语法(e.g. displa遇新是直朋能到y:box;)

Black大享上。是发了概开程态间些告人屏果会区。berry browser 10+ 支持新语法微和二第说,班。都年很过过事发工开宗定据发指互数个遍前互就

更多混合使用语法达到最佳浏览器兼容,可以参考this article (CSS-Tricks)或者this article (DevOpera)

译者的话

网上有不少flex相关教程,但当我看到CHRIS COYIER的这篇文章时,不禁被其详尽所震撼,最近也在撰写布局相关的文章,故产生了翻译此文的想法。翻译过程中尽量保持原文原貌,部分地方做了小幅调整以便更加符合中文思维。文中图片均来源于原文。水平有限,如有误漏之处,还请读者不吝赐教。最后希望此文能给读者带去帮助。

更多讨论请到180251611

本文来源于网络:查看 >
【推荐】帖子搞不懂,找猿2048老师指导一下?
« 上一篇:css 四分之三的圆的实现
» 下一篇:【面试篇】event对象中offsetX,clientX,pageX,screenX,layerX,X的辨析
猜你喜欢
(十万案例免费下载)
评论
点击刷新
评论
阿里云
相关博文
推荐案例
×添加代码片段