沿着
两个轴来布局:沿着
的含义主轴main axis是沿着 flex 元素放置的方向延伸的轴(比如页面上的横向的行、纵向的列)。
交叉轴cross axis是垂直于 flex 元素放置方向的轴。该轴的开始和结束被称为 cross start 和 cross end。
flex 容器flex container设置了 display: flex 的父元素被称之为 flex 容器(flex container)。
flex 项(flex item)在 flex 容器中表现为柔性的盒子的元素被称之为 flex 项(flex item)
Flexible Box 模型,通常被称为 flexbox,是一种一维的布局模型。它给 flexbox 的子元素之间提供了强大的空间分布和对齐能力。本文给出了 flexbox 的主要特性,更多的细节将在别的文档中探索。
我们说 flexbox 是一种一维的布局,是因为一个 flexbox 一次只能处理一个维度上的元素布局,一行或者一列。作为对比的是另外一个二维布局 CSS Grid Layout,可以同时处理行和列上的布局。
flexbox 的两根轴线
当使用 flex 布局时,首先想到的是两根轴线 — 主轴和交叉轴。主轴由 flex-direction 定义,另一根轴垂直于它。我们使用 flexbox 的所有属性都跟这两根轴线有关, 所以有必要在一开始首先理解它。
主轴由 flex-direction 定义,可以取4个值:
如果你选择了 row 或者 row-reverse,你的主轴将沿着 inline 方向延伸。
选择 column 或者 column-reverse 时,你的主轴会沿着上下方向延伸 — 也就是 block 排列的方向。
交叉轴垂直于主轴,所以如果你的flex-direction (主轴) 设成了 row 或者 row-reverse 的话,交叉轴的方向就是沿着列向下的。
如果主轴方向设成了 column 或者 column-reverse,交叉轴就是水平方向。
理解主轴和交叉轴的概念对于对齐 flexbox 里面的元素是很重要的;flexbox 的特性是沿着主轴或者交叉轴对齐之中的元素。
下面的描述是来帮助我们理解为什么不用上下左右来描述 flexbox 元素的方向。
如果 flex-direction 是 row ,并且我是在书写英文,那么主轴的起始线是左边,终止线是右边。
如果我在书写阿拉伯文,那么主轴的起始线是右边,终止线是左边。
在这两种情况下,交叉轴的起始线是flex容器的顶部,终止线是底部,因为两种语言都是水平书写模式。
之后,你会觉得用起始和终止来描述比左右更合适,这会对你理解其他相同模式的布局方法(例如:CSS Grid Layout)起到帮助的作用。
Flex 容器
文档中采用了 flexbox 的区域就叫做 flex 容器。
为了创建 flex 容器, 我们把一个容器的 display 属性值改为 flex
或者 inline-flex
。
flex元素:flex容器中的 直系子元素
就会变为 flex 元素。
所有CSS属性都会有一个 初始值
,所以 flex 容器中的 所有 flex 元素
都会有下列行为:
主维度方向
拉伸,但是 可以缩小
。填充交叉轴
大小。这会让你的元素呈 线形排列
,并且把 自己的大小作为主轴上的大小
。
元素会沿交叉轴
被 拉伸
来填满它的大小。下面s是flex容器可以设置的一些属性
在 flex 容器中添加 flex-direction 属性可以让我们更改 flex 元素的排列方向。设置 flex-direction: row-reverse 可以让元素沿着行的方向显示,但是起始线和终止线位置会交换。
起始线start和终止线end
交换。尝试使用其他的值 row ,column,column-reverse,看看内容会发生什么改变。
用flex-wrap实现多行Flex容器
虽然flexbox是一维模型,但可以使我们的flex项目应用到多行中。
在这样做的时候,您应该 把每一行看作一个新的flex容器
。
任何空间分布都将在该行上发生,而不影响该空间分布的其他行。
为了实现多行效果,请为属性flex-wrap添加一个属性值wrap。
现在,如果您的项目太大而无法全部显示在一行中,则会换行显示。
简写属性 flex-flow
你可以将两个属性 flex-direction 和 flex-wrap 组合为简写属性 flex-flow。
flex-direction
flex-wrap
.在下面的例子中,尝试将第一个值修改为 flex-direction 的允许取值之一,即 row, row-reverse, column 或 column-reverse, 并尝试将第二个指定值修改为 wrap 或 nowrap。
为了更好地控制 flex 元素,有三个属性可以作用于它们:
flex容器中的元素(flex元素)情况(通常不会刚刚好)
- 可能flex元素数量多(或者元素宽度很长)以至于溢出(不便阅读),
- 可能数量很少(或元素宽度很小)而无法占满整个flex容器的宽度(过多留白)
在这里,我们只会大概介绍一下它们的用法,更详细的细节请参阅其它的文档
flex 容器中的可用空间
的行为。假设在 1 个 500px 的容器中,我们有 3 个 100px 宽的元素,那么这 3 个元素需要占 300px 的宽,剩下 200px 的 可用空间
。
在默认情况下, flexbox 的行为会把这 200px 的空间留在最后一个元素的后面。
自动地扩展去填充满剩下的空间
,那么我们需要 去控制可用空间
在 这几个元素间如何分配
flex元素上的 flex 属性
要做的事。Flex 元素属性:flex-basis
flex-basis 定义了 该flex元素
的空间大小(the size of that item in terms of the space),
flex容器里除了元素所占的空间以外的 富余空间
就是可用空间 available space。
auto
此时,浏览器会检测这个元素 是否具有确定的尺寸
。
例如, 所有元素都设定了宽度(width)为100px,所以 flex-basis 的值为100px。
如果没有给元素设定尺寸,flex-basis 的值 采用元素内容
的尺寸(自适应内容的尺寸)。
这就解释了:我们给只要 给Flex元素的
父元素声明 display: flex ,所有子元素就会排成一行,且 自动分配小大
以充分展示元素的 内容
(且刚好展示元素大的内容而不留白)。
以 flex-basis 为基础
,沿主轴方向 增长尺寸
。元素延展
,并占据 此方向轴上
的可用空间(available space)。各自占据可用空间的一部分
。如果我们给上例中的 所有元素设定 flex-grow 值为1
, 容器中的可用空间会被这些元素平分。
它们会延展以填满容器主轴方向上的空间。
Flex 元素属性: flex-shrink
flex-grow属性是处理flex元素在主轴上 增加空间的问题
,相反flex-shrink属性是处理flex元素 收缩的问题
。
如果我们的容器中 没有足够排列flex元素的空间
,那么可以把flex元素 flex-shrink属性设置为正整数来缩小
它所占空间到flex-basis以下。
与flex-grow属性一样,可以 赋予不同的值来控制flex元素收缩的程度
更大的数值
可以比赋予小数值的同级元素 收缩程度更大
。在计算flex元素收缩的大小时,它的最小尺寸也会被考虑进去,就是说实际上flex-shrink属性可能会和flex-grow属性表现的不一致。
因此,我们可以在文章《控制Flex子元素在主轴上的比例》中更详细地看一下这个算法的原理。
在给 flex-grow 和 flex-shrink 赋值时要注意比例。
flex: 10 1 200px
和 flex: 20 1 200px
。1 1 200px
,并且希望其中一个元素可以增加到2倍,我们可以给该元素的flex属性赋值为 2 1 200px
。三个数值按这个顺序
书写 — flex-grow,flex-shrink,flex-basis。Syntax: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
你可以在下面的实例中尝试把flex简写形式中的数值更改为不同数值,但要记得:
让元素增加所占空间
。只有在flex元素总和超出主轴
才会生效。在这个基准值的基础上缩(收缩)与放(拉伸)
的。大多数情况
下可以用 预定义的简写形式
。
你可能经常会看到这种写法,许多情况下你都可以这么使用。
flex: initial
flex: auto
flex: none
flex:
flex: initial
是把flex元素重置为Flexbox的 初始值
,
flex: 0 1 auto
。main axis
):在这里 flex-grow 的值为0
,所以flex元素 不会超过它们 flex-basis 的尺寸
。flex-shrink 的值为1, 所以可以缩小flex元素
来 防止它们溢出
。flex-basis
的值为 auto
.
auto
。flex: auto
等同于 flex: 1 1 auto
;
flex:initial
基本相同,可以拉伸也可以收缩
。flex: none
可以把flex元素设置为 不可伸缩
。
flex: 0 0 auto
是一样的。flex-basis: auto
属性的flexbox进行布局。flex:n
(它相当于 flex: n 1 0
)
flex: 1
或者 flex: 2
等等,它们分别相当于 flex: 1 1 0
,flex:2 1 0
。flex :px
(相当于 flex:1 1 px
)
flex: n px
相当于 flex:n 1 px
align-items 属性可以使元素在 交叉轴
方向 对齐
。
这个属性的初始值为 stretch
,这就是为什么flex元素会默认被拉伸到最高元素的高度。
实际上,它们被拉伸来 填满flex容器
—— 最高的元素定义了容器的高度
。
你也可以设置align-items的值为 flex-start
,使flex元素按flex容器的顶部对齐,
flex-end
使它们按flex容器的下部对齐, 或者center使它们居中对齐.
在实例中尝试——我给出了flex容器的高度,以便你可以看到元素在容器中移动。看看如果更改 align-items的值为下列值会发生什么:
justify-content属性用来使元素在主轴方向上对齐,主轴方向是通过 flex-direction 设置的方向。
初始值是flex-start,元素从容器的起始线排列。
但是你也可以把值设置为flex-end,从终止线开始排列,或者center,在中间排列.
你也可以把值设置为 space-between
,把元素排列好之后的剩余空间拿出来,平均分配到元素之间,所以元素之间间隔相等。
或者使用 space-around
,使每个元素的左右空间相等。
在实例中尝试下列justify-content属性的值:
flex-grow
是否为 wrap等可换行属性值
(或者简写属性 flex-flow
的二个值取可换行值)/* Common Styles */
.content0,
.content1,
.content2 {
color: #fff;
font: 100 24px/100px sans-serif;
/* height: 150px; */
/* width: 90%; */
text-align: center;
}
/* 隐式选择器: */
/* 后代选择器:div */
.content0 div,
.content1 div,
.content2 div {
height: 50%;
width: 150px;
}
body > div {
border: dotted 5px hotpink;
}
/* 颜色类 */
/*通过设置flex元素的flex属性(或者其成分属性flex-grow,
使得红色块所在行始终普铺满整个行
(尽管可在可用空间很充足的时候会有其他色块并到同一行 */
.red {
background: orangered;
/* flex:1; */
flex-grow: 1;
}
.green {
background: yellowgreen;
}
.blue {
background: steelblue;
}
/* 为子块(flex元素)绘制边界 */
.red,
.green,
.blue {
border: 2px solid black;
padding: 3px;
margin: 0.2%;
}
/* Flexbox Styles(层叠样式:flex类) */
.content0 {
display: flex;
flex-wrap: wrap;
}
.content1 {
display: flex;
flex-wrap: nowrap;
}
.content2 {
display: flex;
/* 从下往上,从左往右 */
/* flex-direction: row; */
/* 从下往上,从右往左 */
/* flex-direction: row-reverse; */
flex-wrap: wrap-reverse;
/* display: ; */
}
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<link rel="stylesheet" href="styles/flex-wrap.css">
head>
<body>
<h4>This is an example for flex-wrap:wrap h4>
<div class="content0">
<div class="red">1div>
<div class="green">2div>
<div class="blue">3div>
div>
<h4>This is an example for flex-wrap:nowrap h4>
<div class="content1">
<div class="red">1div>
<div class="green">2div>
<div class="blue">3div>
div>
<h4>This is an example for flex-wrap:wrap-reverse h4>
<div class="content2">
<div class="red">1div>
<div class="green">2div>
<div class="blue">3div>
<div class="red">4div>
<div class="green">5div>
div>
body>
html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<link rel="stylesheet" href="styles/flex-grow.css">
head>
<body>
<h>这展示了 flex 增长h>
<h>A,B,C 和 F 具有 flex-grow:1。D 和 E 具有 flex-grow:2 .h>
<div id="content">
<div class="box" style="background-color:red ;">Adiv>
<div class="box" style="background-color:lightblue;">Bdiv>
<div class="box" style="background-color:yellow;">Cdiv>
<div class="box1" style="background-color:brown;">Ddiv>
<div class="box1" style="background-color:lightgreen;">Ediv>
<div class="box" style="background-color:brown;">Fdiv>
div>
body>
html>
/* 使得html(body)页面占满整个窗口 */
html,
body {
border: dotted 1px;
display: flex;
height: 100%;
width: 100%;
/* align-items: stretch; */
flex-flow: row wrap;
align-items: center;
justify-content: center;
}
#content {
display: flex;
width: 60%;
border: solid 1px;
justify-content: space-around;
flex-flow: row wrap;
/* align-items: stretch; */
align-items: center;
}
h {
border: dotted hotpink;
}
.box {
flex-grow: 1;
border: 3px solid rgba(0, 0, 0, 1);
/* background-color: ; */
}
.box1 {
flex-grow: 2;
border: 3px solid rgba(0, 0, 0, 1);
}
.box,
.box1 {
margin: 0.2%;
}
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
<style>
.box {
width: 100%;
display: flex;
flex-flow: row wrap;
align-items: center;
justify-content: center;
}
div.box>*::after{
border: 1px solid blue;
content: "@flexElementOfBox";
}
.grower {
flex-grow: 1;
}
.box>div {
border: solid 1px hotpink;
margin: 1%;
}
.red,
.green,
.blue {
/* background-color: */
/* opacity: 0.5; */
/* width: 40%;不方便演示换行 */
width: 150px;/*用px方便演示*/
/* background-color: rgba(0, 0, 0, .5); */
/* flex-grow: 1; */
/* 处理可用空间 */
flex: 1 1 auto;
}
.red {
background-color: rgba(255, 0, 0, 0.287);
}
.green {
background-color: rgba(0, 128, 0, 0.452);
}
.blue {
background-color: rgba(0, 0, 255, 0.432);
}
/* .box>div div {
color: rgb(0, 0, 0);
}
*/
style>
head>
<body>
<div class="box">
<div class="red">a
<div class="black">adiv>
div>
<div class="green">bdiv>
<div class="blue">cdiv>
div>
body>
html>
html {
font-family: sans-serif;
}
body {
margin: 0;
}
header {
background: purple;
height: 100px;
}
h1 {
text-align: center;
color: white;
line-height: 100px;
margin: 0;
}
/* 定义基础文章样式(不在次设置article位子flex容器
届时通过伪类选择器选中第三篇article,将其设定为flex容器,允许其内部进行flex布局 */
article {
/* 为主要flex容器元素设定基础宽度(flex-basis)
采用固定值px为单位 */
flex: 200px;
padding: 10px;
margin: 10px;
background: aqua;
/* */
/* flex-flow: wrap-reverse; */
}
/* Add your flexbox CSS below here */
/* 设置主要flex容器 */
section {
display: flex;
/*对三个article对齐进行排版 */
/* flex-flow: ; */
align-items: center;
}
/* article {
flex: 200px;
} */
/* 隐式选中第三篇文章 */
article:nth-of-type(3) {
/* 作为父flex布局的一个flex元素
在flex行充分宽的时候,该元素具有系数3的增长效果*/
/* 需要注意,每一行因为溢出而换行的flex行都要视作一个flex容器来处理 */
flex: 3 200px;
/* 嵌套flex布局:为该元素创建子flex容器 */
display: flex;
/* 将主轴设定为列轴(在排版文章的时候更加方便)
尽管沿着水平轴也可以换行 */
flex-flow: column;
/* flex-flow: row; */
/* flex-wrap: wrap-reverse; */
background-color: pink;
}
/* article */
article:nth-of-type(3)>div:nth-of-type(2){
display: flex;
flex-flow: row wrap;
}
/* 使用`伪类`来选中对象(父容器的第三个article元素)
进一步的,选中article中的第3个buttun子元素 */
article:nth-of-type(3) button:nth-child(3) {
/* flex: 1 100px; */
display: inline-flex;
background-color: greenyellow;
color: red;
flex-flow: row wrap;
align-items: center;
justify-content: space-around;
}
/* 使用`伪类`来选中对象(父容器的第三个article元素)
进一步的,选中article中的第1个div子元素
注意不同:
div:first-child (要求父容器的第一个元素时div的时候,该部分选择器可以选中)
div:nth-of-type(1)(如果父容器中第一个不是div也没关系,该选择器会选中父容器中第一个出现的div标签
*/
article:nth-of-type(3) div:nth-of-type(1) {
flex: 1 100px;
display: inline-flex;
background-color: rgb(196, 47, 255, 0.2);
border: solid blue 1px;
color: red;
flex-flow: row wrap;
align-items: center;
justify-content: space-around;
}
button {
/* flex: 1 auto; */
flex: 1 1 auto;
margin: 5px;
font-size: 18px;
line-height: 1.5;
}
<html>
<head>
<meta charset="utf-8">
<title>Complex flexbox exampletitle>
<link rel="stylesheet" href="styles/complex-flexbox.css">
head>
<body>
<header>
<h1>Complex flexbox exampleh1>
header>
<section>
<article>
<h2>First articleh2>
<p>Tacos actually microdosing, pour-over semiotics banjo chicharrones retro fanny pack portland everyday carry
vinyl typewriter. Tacos PBR&B pork belly, everyday carry ennui pickled sriracha normcore hashtag polaroid
single-origin coffee cold-pressed. PBR&B tattooed trust fund twee, leggings salvia iPhone photo booth health
goth gastropub hammock.p>
article>
<article>
<h2>Second articleh2>
<p>Tacos actually microdosing, pour-over semiotics banjo chicharrones retro fanny pack portland everyday carry
vinyl typewriter. Tacos PBR&B pork belly, everyday carry ennui pickled sriracha normcore hashtag polaroid
single-origin coffee cold-pressed. PBR&B tattooed trust fund twee, leggings salvia iPhone photo booth health
goth gastropub hammock.p>
article>
<article>
<h2>Third articleh2>
<div>
<ul>
<li>1li>
<li>2li>
<li>3li>
ul>
div>
<div>
<button>1Smilebutton>
<button>2Laughbutton>
<button>3Winkbutton>
<button>4Shrugbutton>
<button>5Blushbutton>
div>
<div>
<p>Tacos actually microdosing, pour-over semiotics banjo chicharrones retro fanny pack portland everyday carry
vinyl typewriter. Tacos PBR&B pork belly, everyday carry ennui pickled sriracha normcore hashtag polaroid
single-origin coffee cold-pressed. PBR&B tattooed trust fund twee, leggings salvia iPhone photo booth health
goth gastropub hammock.p>
div>
<div>
<p>Cray food truck brunch, XOXO +1 keffiyeh pickled chambray waistcoat ennui. Organic small batch paleo 8-bit.
Intelligentsia umami wayfarers pickled, asymmetrical kombucha letterpress kitsch leggings cold-pressed squid
chartreuse put a bird on it. Listicle pickled man bun cornhole heirloom art party.p>
div>
article>
section>
body>
html>
html {
font-family: sans-serif;
}
body {
margin: 0;
}
header {
background: purple;
height: 100px;
}
h1 {
text-align: center;
color: white;
line-height: 100px;
margin: 0;
}
/* 定义基础文章样式(不在次设置article位子flex容器
届时通过伪类选择器选中第三篇article,将其设定为flex容器,允许其内部进行flex布局 */
article {
/* 为主要flex容器元素设定基础宽度(flex-basis)
采用固定值px为单位 */
flex: 200px;
padding: 10px;
margin: 10px;
background: aqua;
/* */
/* flex-flow: wrap-reverse; */
}
/* Add your flexbox CSS below here */
/* 设置主要flex容器 */
section {
display: flex;
/*对三个article对齐进行排版 */
/* flex-flow: ; */
/* align-items: center; */
}
/* article {
flex: 200px;
} */
/* 隐式选中第三篇文章 */
article:nth-of-type(3) {
/* 作为父flex布局的一个flex元素
在flex行充分宽的时候,该元素具有系数3的增长效果*/
/* 需要注意,每一行因为溢出而换行的flex行都要视作一个flex容器来处理 */
flex: 4 200px;
/* 嵌套flex布局:为该元素创建子flex容器 */
display: flex;
/* 将主轴设定为列轴(在排版文章的时候更加方便)
尽管沿着水平轴也可以换行 */
flex-flow: column;
/* flex-flow: row; */
/* flex-wrap: wrap-reverse; */
background-color: pink;
}
/* article */
article:nth-of-type(3)>div:nth-of-type(2){
display: flex;
/* 逆向排列 */
flex-flow: row wrap-reverse;
border: 2px dotted;
margin: 2px;
}
/* 使用`伪类`来选中对象(父容器的第三个article元素)
进一步的,选中article中的第3个buttun子元素 */
article:nth-of-type(3) button:nth-child(3) {
/* flex: 1 100px; */
display: inline-flex;
background-color: greenyellow;
color: red;
flex-flow: row wrap;
align-items: center;
justify-content: space-around;
}
/* 使用`伪类`来选中对象(父容器的第三个article元素)
进一步的,选中article中的第1个div子元素
注意不同:
div:first-child (要求父容器的第一个元素时div的时候,该部分选择器可以选中)
div:nth-of-type(1)(如果父容器中第一个不是div也没关系,该选择器会选中父容器中第一个出现的div标签
*/
article:nth-of-type(3) div:nth-of-type(1) {
flex: 1 100px;
display: inline-flex;
background-color: rgb(196, 47, 255, 0.2);
border: solid blue 1px;
color: red;
flex-flow: row wrap;
align-items: center;
justify-content: space-around;
}
button {
/* flex: 1 auto; */
flex: 1 1 auto;
margin: 5px;
font-size: 18px;
line-height: 1.5;
}