Flex布局

注意:假如你想设置行内元素为 flexible box,也可以置 display 属性的值为 inline-flex。

flex 模型说明

当元素表现为 flex 框时,它们沿着两个轴来布局:

image.png
  • 主轴(main axis)是沿着 flex 元素放置的方向延伸的轴(比如页面上的横向的行、纵向的列)。该轴的开始和结束被称为** main start** 和** main end**。
  • 交叉轴(cross axis)是垂直于 flex 元素放置方向的轴。该轴的开始和结束被称为 cross start 和** cross end**。
  • 设置了 display: flex 的父元素(在本例中是 <section>)被称之为 flex 容器(flex container)。
  • 在 flex 容器中表现为柔性的盒子的元素被称之为 flex 项flex item)(本例中是 <article> 元素。

列还是行?

弹性盒子提供了 flex-direction 这样一个属性,它可以指定主轴的方向(弹性盒子子类放置的地方)— 它默认值是 row,这使得它们在按你浏览器的默认语言方向排成一排(在英语/中文浏览器中是从左到右)。

尝试将以下声明添加到 section 元素的 css 规则里:

flex-direction: column

换行

当你在布局中使用定宽或者定高的时候,可能会有一个问题出来即处于容器中的 弹性盒子子元素会溢出,破坏了布局。解决此问题的一种方法是将以下声明添加到 section css 规则中:

flex-wrap: wrap

现在我们有了多行 弹性盒子— 任何溢出的元素将被移到下一行。在 article 元素上设置的 flex: 200px 规则,意味着每个元素的宽度至少是200px;我们将在后面更详细地讨论这个属性。你可能还注意到,最后一行上的最后几个项每个都变得更宽,以便把整个行填满。

但是这里我们可以做得更多。首先,改变 flex-direction 属性值为 row-reverse — 你会看到仍然有多行布局,但是每一行元素排列的方向和原来是相反的了。

flex-flow 缩写

到这里,应当注意到存在着 flex-directionflex-wrap — 的缩写 flex-flow。比如,你可以将

flex-direction: row;
flex-wrap: wrap;

替换为

flex-flow: row wrap;


flex 项的动态尺寸

现在让我们回到第一个例子,看看是如何控制 flex 项占用空间的比例的。打开你本地的 弹性盒子0.html,或者拷贝 弹性盒子1.html 作为新的开始(查看线上)。

第一步,将以下规则添加到 CSS 的底部:

article {
  flex: 1;
}

这是一个无单位的比例值,表示每个 flex 项沿主轴的可用空间大小。本例中,我们设置 <article> 元素的 flex 值为 1,这表示每个元素占用空间都是相等的,占用的空间是在设置 padding 和 margin 之后剩余的空间。因为它是一个比例,这意味着将每个 flex 项的设置为 400000 的效果和 1 的时候是完全一样的。

现在在上一个规则下添加:

article:nth-of-type(3) {
  flex: 2;
}

现在当你刷新,你会看到第三个 <article> 元素占用了两倍的可用宽度和剩下的一样 — 现在总共有四个比例单位可用。 前两个 flex 项各有一个,因此它们占用每个可用空间的1/4。 第三个有两个单位,所以它占用2/4或这说是1/2的可用空间。

您还可以指定 flex 的最小值。 尝试修改现有的 article 规则:

article {
  flex: 1 200px;
}

article:nth-of-type(3) {
  flex: 2 200px;
}

这表示“每个flex 项将首先给出200px的可用空间,然后,剩余的可用空间将根据分配的比例共享“。 尝试刷新,你会看到分配空间的差别。

弹性盒子的真正价值可以体现在它的灵活性/响应性,如果你调整浏览器窗口的大小,或者增加一个 <article> 元素,这时的布局仍旧是好的。


flex: 缩写与全写

flex 是一个可以指定最多三个不同值的缩写属性:

  • 第一个就是上面所讨论过的无单位比例。可以单独指定全写 flex-grow 属性的值。
  • 第二个无单位比例 — flex-shrink — 一般用于溢出容器的 flex 项。这指定了从每个 flex 项中取出多少溢出量,以阻止它们溢出它们的容器。 这是一个相当高级的弹性盒子功能,我们不会在本文中进一步说明。
  • 第三个是上面讨论的最小值。可以单独指定全写 flex-basis 属性的值。

我们建议不要使用全写属性,除非你真的需要(比如要去覆盖之前写的)。使用全写会多些很多的代码,它们也可能有点让人困惑。


水平和垂直对齐

还可以使用 弹性盒子的功能让 flex 项沿主轴或交叉轴对齐。让我们一起看一下新例子 — flex-align0.html在线浏览)— 我们将会有一个整洁,灵活的按钮/工具栏。 此时,你看到了一个水平菜单栏,其中一些按钮卡在左上角,就像下面这样:

image

首先,拷贝一份到本地。

然后,将下面的 CSS 添加到例子的底部:

div {
  display: flex;
  align-items: center;
  justify-content: space-around;
}

刷新一下页面,你就会看到这些按钮很好的垂直水平居中了。我们是通过下面所说的两个新的属性做到的。

align-items 控制 flex 项在交叉轴上的位置。

  • 默认的值是 stretch,其会使所有 flex 项沿着交叉轴的方向拉伸以填充父容器。如果父容器在交叉轴方向上没有固定宽度(即高度),则所有 flex 项将变得与最长的 flex 项一样长(即高度保持一致)。我们的第一个例子在默认情况下得到相等的高度的列的原因。
  • 在上面规则中我们使用的 center 值会使这些项保持其原有的高度,但是会在交叉轴居中。这就是那些按钮垂直居中的原因。
  • 你也可以设置诸如 flex-startflex-end 这样使 flex 项在交叉轴的开始或结束处对齐所有的值。查看 align-items 了解更多。

你可以用 align-self 属性覆盖 align-items 的行为。比如,你可以这样:

button:first-child {
  align-self: flex-end;
}

去看看它产生的效果,然后删除它。

justify-content 控制 flex 项在主轴上的位置。

  • 默认值是 flex-start,这会使所有 flex 项都位于主轴的开始处。
  • 你也可以用 flex-end 来让 flex 项到结尾处。
  • centerjustify-content 里也是可用的,可以让 flex 项在主轴居中。
  • 而我们上面用到的值 space-around 是很有用的——它会使所有 flex 项沿着主轴均匀地分布,在任意一端都会留有一点空间。
  • 还有一个值是 space-between,它和 space-around 非常相似,只是它不会在两端留下任何空间。

在继续下面之前,多多使用提到过的属性吧,看看它们的效果。


flex 项排序

弹性盒子也有可以改变 flex 项的布局位置的功能,而不会影响到源顺序(即 dom 树里元素的顺序)。这也是传统布局方式很难做到的一点。

代码也很简单,将下面的 CSS 添加到示例代码下面。

button:first-child {
  order: 1;
}

刷新下,然后你会看到 "Smile" 按钮移动到了主轴的末尾。下面我们谈下它实现的一些细节:

  • 所有 flex 项默认的 order 值是 0。
  • order 值大的 flex 项比 order 值小的在显示顺序中更靠后。
  • 相同 order 值的 flex 项按源顺序显示。所以假如你有四个元素,其 order 值分别是2,1,1和0,那么它们的显示顺序就分别是第四,第二,第三,和第一。
  • 第三个元素显示在第二个后面是因为它们的 order 值一样,且第三个元素在源顺序中排在第二个后面。

你也可以给 order 设置负值使它们比值为 0 的元素排得更前面。比如,你可以设置 "Blush" 按钮排在主轴的最前面:

button:last-child {
  order: -1;
}

flex 嵌套

弹性盒子也能创建一些颇为复杂的布局。设置一个元素为flex项目,那么他同样成为一个 flex 容器,它的孩子(直接子节点)也表现为 flexible box 。看一下 complex-弹性盒子.html在线浏览)。

image

这个例子的 HTML 是相当简单的。我们用一个 <section> 元素包含了三个 <article>元素。第三个 <article> 元素包含了三个 <div>

section - article
          article
          article - div - button   
                    div   button
                    div   button
                          button
                          button

现在让我们看一下布局用到的代码。

首先,我们设置 <section> 的子节点布局为 flexible box。

section {
  display: flex;
}

下面我们给 <article> 元素设置 flex 值。特别注意这里的第二条CSS规则—我们设置第三个 <article> 元素的子节点的布局同样为 flex ,但是属性值为列布局。

article {
  flex: 1 200px;
}

article:nth-of-type(3) {
  flex: 3 200px;
  display: flex;
  flex-flow: column;
}

接下来,我们选择了第一个 <div>。首先使用 flex: 1 100px; 简单的给它一个最小的高度 100px,然后设置它的子节点(<button> 元素)为 flex 项。在这里我们将它们放在一个包装行(wrap raw)中,使它们居中对齐,就像我们在前面看到的单个按钮示例中做的那样。

article:nth-of-type(3) div:first-child {
  flex: 1 100px;
  display: flex;
  flex-flow: row wrap;
  align-items: center;
  justify-content: space-around;
}

最后,我们给按钮设置大小,有意思的是我们给它一个值为1的 flex 属性。如果你调整浏览器窗口宽度,你会看到这是一个非常有趣的效果。按钮将尽可能占用最多的空间,尽可能多的堆在同一条线上,但是当它们不再适合在同一条线上,他们中的一些会到下一行去。

button {
  flex: 1;
  margin: 5px;
  font-size: 18px;
  line-height: 1.5;
}

跨浏览器兼容性

大多数浏览器都支持 弹性盒子,诸如 Firefox, Chrome, Opera, Microsoft Edge 和 IE 11,较新版本的 Android/iOS 等等。但是你应该要意识到仍旧有被人使用的老浏览器不支持 弹性盒子(或者支持,但是只是支持非常非常老版本的 弹性盒子)。

虽然你只是在学习和实验,这不太要紧; 然而,如果您正在考虑在真实网站中使用弹性盒子,则需要进行测试,并确保在尽可能多的浏览器中您的用户体验仍然可以接受。

弹性盒子相较其他一些 CSS 特性可能更为棘手。 例如,如果浏览器缺少 CSS 阴影,则该网站可能仍然可用。 但是假如不支持 弹性盒子功能就会完全打破布局,使其不可用。

我们将在未来的模块中讨论克服棘手的跨浏览器支持问题的策略。

Link to section总结

到这里,介绍弹性盒子的基础知识就结束了。 我们希望你体会到乐趣,并且玩的开心,能随着你的学习与你一起向前。 接下来,我们将看到CSS布局的另一个重要方面—网格系统。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容

  • 前言、Flex布局 Flex布局可谓是移动端H5上最重要的布局,基本没有之一。一些常用的功能和基本功能在此只做罗列...
    破晓霜林阅读 1,165评论 0 4
  • 几个问题 一个弹性布局可以由哪几方面决定? flex布局在web端与react-native端表现一样吗? rea...
    nimw阅读 1,861评论 0 4
  • 最近这两天一直在学习关于移动端页面,而移动端页面一般很多用flex(弹性)布局,方便简洁,而且没有什么兼容性的问题...
    YM雨蒙阅读 462评论 0 4
  • 1.Flex布局是什么? Flex是Flexible Box的缩写,就是灵活的弹性页面布局。 作用是为盒子模型提供...
    LiLi原上草阅读 652评论 0 7
  • 前言 本文引自阮一峰的网络日志:Flex 布局教程:语法篇 阮一峰老师的文章确实很棒,在他的博客学到了很多的知识,...
    destiny0904阅读 666评论 0 2