弹性盒子是一种用于 按行 或 按列的一维布局方法.

元素可以膨胀以填充额外的空间, 也可以 收缩 以适应更小的空间.

flex 重点概览

对于 flex 重要的理解点在于:

  • 主轴与交叉轴
  • 换行与缩写
  • 主轴对齐方式
  • 交叉轴对齐方式

基于了解完上面的内容, 我们能用 flex 布局实现如下几种最常见的布局:

  • 内联和块的 上下左右居中布局
  • 不定项居中布局
  • 均分列布局
  • 组合嵌套布局

接着是关于 flex-子项 的重点:

  • flex-grow: 扩展比例
  • flex-shrink 收缩比例
  • flex-basis 及flex缩写
  • order 与 align-self

最后同样是基于子项的属性, 完成一些常用的子项布局:

  • 等高布局
  • 两列与三列布局
  • 粘性页脚布局
  • 溢出项布局

可以发现这个 flex 是真的很强, 相对于上面的内容如果用定位 + 浮动的方式, 搞起来还是超级麻烦的哦

主轴与交叉轴

要形成 flex 布局, 首先需要一个父容器 flex-container, 然后是里面的子项 flex-item.

主轴

主轴 main-axis 默认是水平轴, 交叉轴 cross-axis 则垂直于主轴, 因此子元素默认是水平排列的. 要注意的是主轴和交叉轴, 包括起点, 终点都是可以互换的, 非常灵活.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>flex</title>
<style>
.main {
width: 500px;
height: 500px;
background-color: pink;
/* 这里用的是 display 的内部值属性 */
display: flex;
}
.main div {
width: 100px;
height: 100px;
background-color: skyblue;
}
</style>
</head>
<body>
<div class="main">
<div>1</div>
<div>2</div>
<div>3</div>
</div>
</body>
</html>

特别要注意区分 flex容器 和 flex子项的属性, 千万别写混了.

flex 容器属性 flex 子项属性
flex-direction order
flex-wrap flex-grow
flex-flow flex-shrink
justify-content flex-basis
align-items flex
align-content align-self

交叉轴

flex-direction 其实就是设置主轴是行还是列, 且起始位置是否要逆反而已啦. 要列它一共有 4个属性值:

  • row (默认)
  • row-reverse
  • column
  • column-reverse

默认是水平布局, 当 flex-direction: row-reverse 时候, 子项从右往左排列.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>flex</title>
<style>
.main {
width: 500px;
height: 500px;
background-color: pink;
/* 这里用的是 display 的内部值属性 */
display: flex;
/* 改变主轴起点位置, 水平时, 左->右; reverse: 从右->左 */
flex-direction: row-reverse;
}
.main div {
width: 100px;
height: 100px;
background-color: skyblue;
}
</style>
</head>
<body>
<div class="main">
<div>1</div>
<div>2</div>
<div>3</div>
</div>
</body>
</html>

当我们改变为垂直布局时, flex-direction: column / column-reverse 子项从上到下 或 从下往上排列.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>flex</title>
<style>
.main {
width: 500px;
height: 500px;
background-color: pink;
display: flex;
/* 改变主轴起点位置, 垂直时, 默认上->下; reverse: 下 -> 上 */
/* flex-direction: column; */
flex-direction: column-reverse;
}
.main div {
width: 100px;
height: 100px;
background-color: skyblue;
}
</style>
</head>
<body>
<div class="main">
<div>1</div>
<div>2</div>
<div>3</div>
</div>
</body>
</html>

换行与缩写

flex-wrap 用来设置当子项宽度超出容器时, 是否换行的问题, 主要有 3 个值:

  • nowrap (默认) , 默认不换行, 进行一行的压缩, 宽度不会溢出父容器, 内容往里压缩啦. 但超级多也会溢出.
  • wrap
  • wrap-reverse

当弹性的子元素没有 width 时, 宽度会根据内容撑开; 当不设置 height 时, 会自动撑满容器

当主轴是 row 时:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>flex</title>
<style>
.main {
width: 500px;
height: 500px;
background-color: pink;
display: flex;
/* 元素尺寸超出, 可设置换行, 但是按父容器百分比平分, 2行的话就是 50% 的位置 */
/* 但如果父容器没有高度的话, 那就顺势挨在一起了. */
/* flex-wrap: wrap; */
/* reverse 也可设置从底部开始折行, 但这种用得比较少 */
flex-wrap: wrap-reverse;
}
.main div {
width: 100px;
height: 100px;
background-color: skyblue;
}
</style>
</head>
<body>
<div class="main">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
<div>10</div>
<div>11</div>
</div>
</body>
</html>

当主轴是 column 时:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>flex</title>
<style>
.main {
width: 500px;
height: 500px;
background-color: pink;
display: flex;
/* 元素尺寸超出, 可设置换列, 但是按父容器百分比平分, 2列的话就是 50% 的位置 */
/* 但如果父容器没有宽的话, 那就顺势挨在一起了. */
flex-direction: column;
/* flex-wrap: wrap; */
/* reverse 也可设置从底部开始折行, 但这种用得比较少 */
flex-wrap: wrap-reverse;
}
.main div {
width: 100px;
height: 100px;
background-color: skyblue;
}
</style>
</head>
<body>
<div class="main">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
<div>10</div>
<div>11</div>
</div>
</body>
</html>

但需注意的是, flex 布局更倾向于一维的布局, 如果是设计行和列的那还是得 grid 比较适合.

通常我用flex最多的就是, 一维横向, 子元素水平垂直居中就可以啦.

flex-flow

这个属性其实就是 flex-direction 和 flex-wrap 的缩写而已啦.

  <style>
.main {
width: 500px;
height: 500px;
background-color: pink;
display: flex; /* flex-direction: column;
flex-wrap: wrap; */
/* 上面两行可简写为一行 */
/* flex-flow: column wrap; */
flex-flow: wrap; }
.main div {
width: 100px;
height: 100px;
background-color: skyblue;
}
</style>

为了降低记忆难度, 我感觉缩写啥, 就直接全写得了, 也不是那么费事.

主轴对齐

justify-content 主轴对齐, 即设置主轴元素的对齐方式, 主要有如下:

  • flex-start (默认)
  • flex-end
  • center
  • space-around
  • space-between
  • space-evenly
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>flex</title>
<style>
.main {
width: 500px;
height: 500px;
background-color: pink;
display: flex; /* 子元素默认对齐方式是 flex-start 紧挨着 */
/* justify-content: flex-start; */ /* 右对齐方式 */
/* justify-content: flex-end; */ /* 居中对齐 */
/* justify-content: center; */ /* 分散对齐, 最左/最右 的空间是一致的, 若不设置父容器宽, 则默认均分浏览器视口 */
/* justify-content: space-around; */ /* 两端对齐, 两侧分别顶到两个断点, 再来进行平分剩余空间 */
/* justify-content: space-between; */ /* 平均分配, 子项之间的距离是相等的 */
justify-content: space-evenly; }
.main div {
width: 100px;
height: 100px;
background-color: skyblue;
}
</style>
</head>
<body>
<div class="main">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
</div>
</body>
</html>

当主轴为 cloumn 时, 也是一样的, 相当于转换一下而已.

  <style>
.main {
width: 500px;
height: 500px;
background-color: pink;
display: flex; flex-direction: column; /* 子元素默认对齐方式是 flex-start 列 */
justify-content: flex-start; /* 下对齐方式 */
/* justify-content: flex-end; */ /* 居中对齐 */
/* justify-content: center; */ /* 分散对齐, 最上/最下 的空间是一致的, 不设高时候, 按内容撑开 */
/* justify-content: space-around; */ /* 两端对齐, 两侧分别顶到两个断点, 再来进行平分剩余空间 */
/* justify-content: space-between; */ /* 平均分配, 子项之间的距离是相等的 */
/* justify-content: space-evenly; */ }
.main div {
width: 100px;
height: 100px;
background-color: skyblue;
}
</style>

交叉轴对齐

交叉轴的对齐方式比主轴要更强大一些, 因为它有两个兄弟呀.

align-content

这个 align-content 和 justify-content 还是很像的, 唯一的特点是它必须要有换行才能生效.

  • strech (默认)
  • flex-start
  • flex-end
  • center
  • space-around
  • space-between
  • space-evenly
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>align-content</title>
<style>
.main {
width: 500px;
height: 500px;
background-color: pink;
display: flex; flex-wrap: wrap;
/* 当不换行的时候, align-content 不生效 */
/* align-content: flex-end; */
/* align-content: stretch; */
/* align-content: space-around; */
/* align-content: space-between; */
align-content: space-evenly; }
.main div {
width: 100px;
height: 100px;
background-color: skyblue;
}
</style>
</head>
<body>
<div class="main">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
</div>
</body>
</html>

align-items

它是针对容器中, 针对每一行的对齐方式, 而 align-content 是针对整体. 在实际应用中, 针对每一行的方式则用的更多些. 毕竟用 flex 是用来解决一维布局的, 换行就搞起来有点麻烦, 不如用 grid 操作.

  • stretch (默认)
  • flex-start
  • flex-end
  • center
  • baseline -- 用得少
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>align-items</title>
<style>
.main {
width: 500px;
height: 500px;
background-color: pink;
display: flex; flex-wrap: wrap;
/* align-items: 每一行的对齐 */
/* align-items: flex-start; */
align-items: center; }
.main div {
width: 100px;
height: 100px;
background-color: skyblue;
}
</style>
</head>
<body>
<div class="main">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
</div>
</body>
</html>

从我的应用实践中, 就水平垂直居中用的比较多一些, 其他的换行都不咋用的.

. flex-container {
dispaly: flex;
justify-content: center;
align-items: center;
}

水平垂直居中布局

即容器内元素的水平和居中对齐, 根据内容.

内联元素: 文本垂直水平居中

  • 水平居中: justify-content: center;
  • 垂直居中: align-items: center
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>文字水平垂直居中</title>
<style>
.box {
width: 300px;
height: 200px;
background-color: pink;
/* 水平垂直居中 */
display: flex;
justify-content: center;
align-items: center;
}
</style>
</head>
<body>
<div class="box">哈哈哈哈哈</div>
</body>
</html>

这样就轻松搞定了. 但如果我们不用 flex 的话, 如果只是垂直居中, 就可以用 行高 = 盒子高 .

  <style>
.box {
width: 300px;
height: 200px;
background-color: pink;
/* f水平垂直居中 */
text-align: center;
line-height: 200px;
}
</style>

但这种一旦涉及多行文字, 这种设置行高的方式就会对每行文字撑大一个空间, 就乱了. 但 flex 没有问题.

块级元素: 垂直水平居中

  • 水平居中: justify-content: center;
  • 垂直居中: align-items: center
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>块元素-水平垂直居中</title>
<style>
.box {
width: 300px;
height: 200px;
background-color: pink; /* 块元素 水平垂直居中 */
display: flex;
justify-content: center;
align-items: center;
}
.box div {
width: 100px;
height: 100px;
background-color: skyblue;
}
</style>
</head>
<body>
<div class="box">
<div>item</div>
</div>
</body>
</html>

如果不用 flex 的话, 我们可以通过定位来实现哈, 即 子绝父相.

  <style>
.box {
width: 300px;
height: 200px;
background-color: pink; /* 块元素 水平垂直居中, 子绝父相 */
position: relative; }
.box div {
width: 100px;
height: 100px;
background-color: skyblue; /* 子: 绝对定位, 参考父元素(设置了 relative) */
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%); }
</style>

或者也可用 margin: auto 来做, 设置绝对定位, 然后 top / right / bottom / left 都设置为 0 即可.

  <style>
.box {
width: 300px;
height: 200px;
background-color: pink;
position: relative;
}
.box div {
width: 100px;
height: 100px;
background-color: skyblue; position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0; margin: auto;
}
</style>

对比发现, 还是这个 flex 布局比较好用呀.

不定项居中对齐

就中间元素多少不清楚, 但需要进行居中对齐, 最常用的比如轮播图里面, 下面的切换小点点,

还有就是像页面分页器在底部的居中对齐等.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>不定项居中对齐</title>
<style>
.box {
width: 300px;
height: 150px;
background-color: pink; display: flex;
justify-content: center;
align-items: flex-end;
} .box div {
width: 30px;
height: 30px;
background-color: skyblue;
border-radius: 50%;
margin: 10px;
}
</style>
</head>
<body>
<div class="box">
<div></div>
<div></div>
<div></div>
<!-- 多项也能进行居中 -->
<div></div>
<div></div>
</div>
</body>
</html>

同样如果不用 flex , 则我们可以利用 position 来做:

<!DOCTYPE html>
<html lang="en"> <head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>定位实现: 不定项居中对齐</title>
<style>
.box {
width: 300px;
height: 150px;
background-color: pink;
/* 子绝父相 */
position: relative; } .box section {
/* text-align 对内联样式起作用, 块则无效 */
text-align: center;
width: 100%;
position: absolute;
bottom: 0;
font-size: 0;
} .box div {
width: 30px;
height: 30px;
background-color: skyblue;
border-radius: 50%;
margin: 10px; /* inline-block: 对外是行内样式, 对内是块样式 */
display: inline-block;
}
</style>
</head> <body>
<div class="box">
<section>
<div></div>
<div></div>
<div></div>
<!-- 多项也能进行居中 -->
<!-- <div></div>
<div></div> -->
</section>
</div>
</body> </html>

这个搞起来就有点麻烦, 但是也能, 不过要这样对比才能发现这个 flex 是真的香呀, 而且还是自适应的.

均分列布局

最常用的就是小程序底部的菜单栏, 将底部进行一个均分排列, 即便新增也是均分开显示哦.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>均分列布局</title>
<style>
.main {
/* 块盒子不写 width 就是默认浏览器 */
height: 200px;
background-color: pink; display: flex;
/* 设置子元素均分列, 自适应 */
/* justify-content: space-around; */
/* justify-content: space-evenly; */
justify-content: space-between; /* 可以移到底部 */
align-items: flex-end;
/* 左右留一点间距出来 */
padding: 10px 20px;
/* 保证父容器不被撑开, 设置为怪异盒模型 */
box-sizing: border-box;
} .main div {
width: 30px;
height: 30px;
border-radius: 50%;
background-color: skyblue;
}
</style>
</head>
<body>
<div class="main">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</body>
</html>

同样如果不用 flex 的话, 用 float 来实现就有一点麻烦啦.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>只能固定尺寸: 均分列布局</title>
<style>
.main {
height: 200px;
background-color: pink;
/* 要用宽度, float 分散 */
width: 500px;
/* 溢出则要隐藏 */
overflow: hidden;
box-sizing: border-box;
/* 左右边距 */
padding: 0 10px;
/* 子绝父相 */
position: relative;
} .main section {
width: 800px;
position: absolute;
bottom: 10px;
} .main div {
width: 30px;
height: 30px;
border-radius: 50%;
background-color: skyblue; float: left;
margin-right: 120px;
}
</style>
</head>
<body>
<div class="main">
<section>
<div></div>
<div></div>
<div></div>
<div></div>
</section>
</div>
</body>
</html>

可以看到这个用浮动 + 定位来实现就要计算宽度, 有点麻烦, 而且还不能自适应, 果断废弃用 flex 呀.

子项分组布局

其实就是嵌套 flex. 比如有3个块要横向排列, 一个在左边, 另外两个靠右边, 中间空出来这种效果.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>子项分组布局</title>
<style>
.main {
height: 200px;
background-color: pink; display: flex;
justify-content: space-between;
align-items: center;
} /* 右边, 即 main 下的第二个兄弟, 也进行 flex 布局 */
.main div:nth-of-type(2) {
display: flex;
/* 留一点间隙 */
margin-left: 10px;
} .main .box {
width: 50px;
height: 100px;
background-color: skyblue;
}
</style>
</head>
<body>
<!-- 外层容器用 flex -->
<div class="main">
<div class="box">1</div>
<!-- 子项也进行 flex -->
<div>
<div class="box">2</div>
<div class="box">3</div>
</div>
</div>
</body>
</html>

这个核心在于在 html 的部分进行嵌套和包裹, 再用 flex , 能够实现效果, 但是有点麻烦. 其实有个更为简单的办法, 是通过 margin-right: auto;

Tips: 当父容器布局为 flex 时, 子项用 margin-right: auto 会将右边的元素直接挤压到右侧, 贼好用

关于 flex 父容器的相关设置和常用的布局就基本到这啦.

Flex布局-容器项的更多相关文章

  1. Flex布局-容器的属性

    本文部分内容参考阮一峰大神博客,原文地址:http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html Flex布局即弹性布局,使用起来十分方便灵活 ...

  2. flex布局使用

    什么是flex布局 flex是flexible Box的缩写,意味"弹性盒子",用来为盒子状模型提供最大的灵活性 任何一个盒子都可以指定为flex布局 .box{ display: ...

  3. flex布局(弹性布局)

    1. 传统布局与 flex 布局比较 传统布局 兼容性好 布局繁琐 局限性,不能在移动端很好的布局 flex 弹性布局 操作方便,布局极为简单,移动端应用很广泛 PC端浏览器支持较差 IE 11 或 ...

  4. 移动 WEB 开发布局方式 ---- flex 布局

    一.flex布局体验 1.1 传统布局 flex 布局 1. 2 初体验 1. 搭建 HTML 结构 <div> <span>1</span> <span&g ...

  5. flex布局实现elment容器布局

    一.flex布局是什么 flex布局,意为"弹性布局",是一种响应式的布局方法 采用 Flex 布局的元素,称为 Flex 容器,它的所有子元素自动成为容器成员. 先放上一个ele ...

  6. CSS3 Flex布局整理(二)-容器属性

    一.Flex容器属性介绍 1.flex-flow :水平或垂直方向上的流动方式,包裹处理,其中包括了flex-direction属性和flex-wrap属性. 2.justify-content:定义 ...

  7. CSS3 Flex布局(容器)

    一.flex-direction属性 row(默认值):主轴为水平方向,起点在左端. row-reverse:主轴为水平方向,起点在右端. column:主轴为垂直方向,起点在上沿. column-r ...

  8. flex布局中父容器属性部分演示效果

    如图可见flex的属性分为父容器和子容器的属性共12个.关于这些属性具体代表什么意思,网上有很多教程的文章,自觉不能写得比别人更好,所以这里主要写了一些例子关于父容器属性效果的演示,希望可以帮助大家理 ...

  9. Flex 布局教程:语法篇

    作者: 阮一峰 网页布局(layout)是CSS的一个重点应用. 布局的传统解决方案,基于盒状模型,依赖 display属性 + position属性 + float属性.它对于那些特殊布局非常不方便 ...

  10. 【转】Flex 布局语法教程

    网页布局(layout)是CSS的一个重点应用. 布局的传统解决方案,基于盒状模型,依赖 display属性 + position属性 + float属性.它对于那些特殊布局非常不方便,比如,垂直居中 ...

随机推荐

  1. ABB机器人IO板DSQC651维修检查方法

    ABB机器人作为工业自动化的重要设备,其稳定性和可靠性对于生产线的持续运行至关重要.然而,在实际使用中,由于各种原因,可能会出现ABB机器人IO板DSQC651故障,影响机器人的正常运行. 一.ABB ...

  2. 【软件开发】Doxygen使用笔记

    [软件开发]Doxygen 使用笔记 Doxygen 是通过代码注释生成文档的事实标准,借用该工具可以将文档内容与代码写在一起方便维护. https://github.com/doxygen/doxy ...

  3. Typecho 引入JS简单的实现点击文字即可复制

    在文章中插入大量无意义内容一不美观,二不便复制,不如使用 js 创建隐藏内容的复制按钮吧. 引入 JS 本主题:依次进入 控制台 - 外观 - 设置外观 - 主题自定义扩展,将以下代码加入到 自定义 ...

  4. Git pull(拉取),push(上传)命令整理(详细)

    转自:https://www.cnblogs.com/wbl001/p/11495110.html (文档较长,请大家耐心阅读,很有帮助) git比较本地仓库和远程仓库的差异 更新本地的远程分支 gi ...

  5. 【抓包】Fidder Script自动修改包

    Fiddler Script的本质是用JScript.NET编写的一个脚本文件CustomRules.js 但是它的语法很像C#但又有些不一样,比如不能使用@符号 通过修改CustomRules.js ...

  6. C++判断文本编码

    #include <iostream> #include <fstream> #include <string> #include <sstream> ...

  7. 实现领域驱动设计 - 使用ABP框架 - 聚合

    这是本指南的关键部分.我们将通过实例介绍和解释一些明确的规则.在实现领域驱动设计时,您可以遵循这些规则并将其应用到您的解决方案中 领域案例 这些例子将使用GitHub中使用的一些概念,比如Issue, ...

  8. BUUCTF---bbbbbras

    题目 p = 177077389675257695042507998165006460849 n = 3742182950988779627489716224936732940098864714561 ...

  9. CoreOS 手动升级篇

    说到升级...通常肯定会以下2个步骤: 检查是否有新版本. 下载和安装新版本. 在 CoreOS 中也一样,我们先来看下在 CoreOS 中对应的命令: # 检查是否有新版本 update_engin ...

  10. 关于TFDMemtable的使用场景【3】处理数据

    原因很多: 1.通过TFDMemtable处理数据时,避免影响数据感知 2.处理速度很快. ------------------------------ 从Tdataset读取数据: Procedur ...