前言

Flex 诞生在 Float 之后, Grid 之前, 它主要是取代 Float 来实现布局. 而它没有 cover 到的地方则由 Grid 弥补.

所以当前, 我们做布局时, 几乎不用 Float, 大部分都用 Flex, 少许地方用 Grid (通常 Flex 搞不定才会用 Grid).

BTW, Figma 的 Auto Layout 就是用 Flex 实现的.

参考

Youtube – Flexbox is more complicated than you thought

Youtube – Learn Flexbox in 15 Minutes

Youtube – Learn flexbox the easy way

Flex 的能力

抽象的说, Flex 的能力是把几个 element (block 也好, inline 也要) 排成一行或一列, 然后做一些排版, 比如 alignment, spacing, dimension 等等.

然后它还带有一些 RWD 的能力.

Flex 常用地方

参考: Youtube – Flexbox design patterns you can use in your projects (读完本篇后可以看看)

Alignment

本来 2 个 element 是一列的, 通过 flex 变成了一行, 而且 vertical aligh center.

Spacing

不使用 Flex 的话, 一般上我们用 margin-top 来做 spacing, 但 margin-top 的表达不理想, 比如第一个 element 不需要 margin-top. 所有的 margin-top 都是相同的值, 所以用 Flex 会更好表达.

RWD

Flex 还可以用在这类简单的 RWD 上.

Flex 的 HTML 结构

<div class="container">
<div class="item">item1</div>
<div class="item">item2</div>
<div class="item">item3</div>
<div class="item">item4</div>
</div>

Flex 有 2 层, container > item

只有 container 内的 first layer element 才是 flex item.

我们给点 style 看看它的长相

.container {
width: 250px;
border: 1px solid red; > * {
&:nth-child(odd) {
background-color: pink;
}
&:nth-child(even) {
background-color: cyan;
}
}
}

此时还没有加入 flex, 效果:

由于 div 默认是 display block, 所以 item 1,2,3,4 会往下发展形成 1 列.

Flex 的默认值

现在我们加入 display: flex 看看它的效果

display: flex;

虽然只给了一个属性, 但是 Flex 有许多默认值. 所以它其实是这样的

.container {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: flex-start;
align-items: stretch;
align-content: stretch;
gap: 0; > * {
flex-grow: 0;
flex-shrink: 1;
flex-basis: auto;
}
}

效果

和原先的已经完全不一样了.

Flex 属性 (过一轮)

先过一轮每一个属性, 还有它大致上的作用. 有个画面先, 后面才逐一细品.

flex-direction (container)

flex item 的方向, row 表示 horizontal 横向, column 表示 vertical 垂直

当 direction: row 时, item 即使是 display: block 也会被强行排成一行, 看上去就像是变成了 inline.

flex-wrap (container)

flex-wrap 表示当 item 超过 container width 时, 应该如何摆放

wrap 表示把 item 放到下一行

nowrap 则表示让 item 超出 container width

默认是 nowrap, wrap 通常用来做 RWD.

justify-content (container)

justify 是做 alignment 的, align 的 direction 和 flex-direction 一致. 比如上面的例子 flex-direction 是 row, 所以 align 的 direction 就是 horizontal.

align 的前提是要有额外的空间, 比如上面这个例子, container width > items total width 所以有空间可以 align.

align-items (container)

align-items 也是做 align 的, align 的 direction 和 flex-direction 相反. 比如上面的例子 flex-direction 是 row, 那它 align 的 direction 就是 vertical.

有 2 种情况可以 align.

第一, container height > item height 有额外的空间, 像上面这样.

第二, item 的高度不一致时. 总之要 align 得要有空间.

另外, 它有一个特别的属性叫 stretch 拉紧, 意思是 item height fill container

注: container 的 align-items 是可以被 item 的 align-self override 的, 所以也可以理解为, container 设置 align-items 只是一个批量操作, 为了方便而已.

align-content (container)

当设置了 flex-wrap: wrap 那么 container 的 align-items 和 item 的 align-self 都会失效. 取而代之是 container 的 align-content. (注: 无论 item 是否真的超过 container, 只要 set wrap 那么就不看 align-items 了)

gap (container)

item 之前的间距 (gutter)

 gap: 10px

flex-grow (item)

grow 表示当 container 有多余的空间时, 是否自动加大 item, 它的 direction 和 flex-direction 一致, 比如上面的例子 flex-direction 是 row, 那么 flex-grow 的 direction 就是 horizontal.

白色区域就是额外的空间. grow: 0 表示不会加大, 其余号码表示会加大, 并且它是一个比例值, 具体如何按比例分配多余空间下面会讲.

flex-shrink (item)

shrink 和 grow 相反, 它表示当 container 空间不足够时, 是否自动减小 item, 它的 direction 和 flex-direction 一致, 比如上面的例子 flex-direction 是 row, 那么 flex-grow 的 direction 就是 horizontal.

它和 grow 一样, 0 表示不能收缩, 其余号码则是比例, 具体算法下面会讲.

另外它和 wrap 是冲突的, wrap 优先. 所以 shirink 只会配上 nowrap.

flex-basis (item)

它的 direction 和 flex-direction 一致, 比如上面的例子 flex-direction 是 row, 那么 flex-basis 指的是 horizontal 也就是 width.

它的功效就是依据 direction 去替代 width / height 而已. 当 basis = auto 时, 它会直接拿 width / height 的值来用.

小总结

上面过了一轮 flex 的大部分属性和它的基本功用. 有个画面就好. 下面我们来逐一看看它们的细节.

要了解 Flex, 我们脑袋里要时刻有 container 和 item, 和它们的 dimension (width / height) 最后在配上各种 flex 属性.

Flex 属性 (逐个解释)

flex-direction

.flex-container {
display: flex;
flex-direction: row;
width: 200px;
border: 2px solid black;
}

设置 display: flex 以后, 第一步就是选方向.

默认是 row (horizontal 横向)

效果:

虽然里面的 div 是 display block, 但是经过 flex 处理, 它就往横向走了.

flex-direction: column; 就往下走, 即使 item 是 inline 也会被强制变成往下

它还可以 reverse items 哦, row-reverse, column-reverse

flex-wrap

wrap 是设置当 container 装不下 item 的时候如何处理. 默认值是 nowrap.

假设 container width: 100px;

item3 跑出去了, 通过设置 flex-wrap: wrap 效果如下:

item3 没有跑出去, 反而是往下掉了. 这个在做 RWD (Responsive Web Design) 超实用的.

wrap-reverse

wrap 是往下掉, 如果想往上也是可以的. 例如下面这个例子.

flex-flow

flex-flow 是 flex-direction 和 flex-wrap 的 shorthand.

flex-flow: row wrap;

justify-content

justify-content 是用来做 alignment 的. 有点像 Figma 的这个

注: align 的前提是要有空间, 当 container 的 width, height 不是 hug content, 或者 item 的 width, height 宽度/高度不一致的时候就会产生空间, 没有空间自然就谈不上 align 了.

justify-content 调整的方向和 direction 的方向是一致的, 比如 direction 是 horizontal, 那么 justify-content 调整的就是左右.

前面 4 个是比较常用到的. 通常是写 flex-start 而不是 left 或 start, 虽然 chrome 都能接受.

align-items

align-items 的默认值是 stretch 拉紧的意思.

container height 50px, item height auto 的情况下

baseline 通常用于对齐字体, 如果字体一样的话, 它的效果和 flex-start 是一样的.

item 2,4 比较高, 所以产生了空间, align-items: center 的效果如上.

align-content

align-content 和 align-items, justify-content 差不多玩法,

首先它只能用于 flex-wrap:wrap 的情况下, nowrap 情况下, align-content 是无视的.

当 item 超过 container, item 会被 wrap 成多排, 可以把这 2 排想象成 2 个 item, 所以它也能类似 justify-content 那样做 space-between

Gap

Flex 也是可以用 gap 的, 和 Grid 一样.

它就是 Figma 的 Spacing between items,

gap vs gutter (垄沟)

CSS Flex 和 Grid 都是用 gap, gutter 是用在 Figma 的 Grid Layout 虽然它们很相识.

column / row-gap

 

gap 表示 row 和 column 一起 set, 也可以分开配置的

gap: 8px 16px;
row-gap: 8px;
column-gap: 16px;

Flex Item

下面的讲解, 会假定 flex-direction 是 row. 如果是 column 请自行换取反方向理解.

Order

顾名思义, 用来修改 element 顺序, 动态排版呢

flex-grow

grow 用于表示 item 是否可以自行放大填满 container. grow: 0 代表不可以放大, 其余号码表示按比例分配 container 额外的空间.

参考: 知乎 – 详解 flex-grow 与 flex-shrink

上面这篇讲解的非常详细了, 而且也有很好的例子.

我讲一下它的 step 就好.

当出现额外空间时 (container width > total item width)

item 有 grow: number (非 zero) 表示可以放大

接着就是看如何分配这些额外的空间.

假设额外的空间有 500px

有 2 个 item 要分配.

grow:1, grow:1 表示平分

grow:2, grow: 1 表示 itemA 分配比例是 2:3, itemB 比例是 1:3

所以 500 x 2 / 3 = 333.33px 就是 itemA 需要扩大的 width.

注1: 当所有 grow 总数 < 1 时 (比如 grow: 0.1), 算法会不同. 最终会导致 container 没有被完全填满. (想了解详情, 看上面的参考)

注2: max-width 会导致 item 无法扩大, 那么其它 item 会继续分配掉, 直到所有 item 都 hit 到 max-width 就会导致 container 没有被完全填满.

flex-shrink

shrink 的分配方式和 grow 是不同的哦.

参考: 知乎 – 详解 flex-grow 与 flex-shrink

同样这篇讲的很详细了. 我讲 step 就好.

当 container 不够大. 它就会去缩小 item. item 默认的 flex-shrink 是 1.

0 表示不允许缩小.

假设需要 500px 空间. 那么就要看如何分配给所有 item

如果所有 item 都是 shrink: 1 那就是按股份分配.

这里和 grow 的平均分配不一样哦.

item A,B,C 分别是 300, 200, 500px

那么持股比例就是 30%, 20%, 50% 大家都是 shrink:1 那么就按这个比例分.

500 x 30% = 150px, 所以 ItemA 要缩小 150px

那么当 shrink 不是 1 的时候呢? 算法是这样的

假设 Item A, B, C shrink 是 1, 2, 3

那么先把比例算出来.

300 x 1 = 300

200 x 2 = 400

500 x 3 = 1500

ItemA 比例是 300: (300 + 400 + 1500) = 2200

所以 ItemA 缩小 = 500 x 300 / 2200 = 68px

注1: 当所有 shrink 总数 < 1 时 (比如 shrink: 0.1), 算法会不同. 最终会导致 item 溢出 container (想了解详情, 看上面的参考)

注2: min-width 会导致 item 无法缩小, 那么其它 item 会继续分配掉, 直到所有 item 都 hit 到 min-width 就会导致 item 溢出 container.

注3: padding, border 是不能被缩小的, 只有 avaiable width 能被缩小, 而且缩小到 item 的 min-content 就不能再小了.

flex-basis

参考:

What are the differences between flex-basis and width?

[译] width 与 flex-basis 的区别

flex-basis和width到底谁听谁的?

basis 就是 item 的 尺寸. 假设 container 是 flex-direction: row.

flex-basis 指的就是 width. 那么对比起设置 width 有什么区别吗?

黄金法则:

flex-basis 你不设置, 它就是 auto, 然后它会去拿 width. 当你设置后, 它就无视 width 了. (建议使用 flex-basis)

flex-basis 是会被 grow 和 shrink 影响的, 也会被 min/max dimension 影响.

flex

它是 flex-grow, flex-shrink, flex-basis 的 shorthand.

flex: 1 代表什么呢? What does flex: 1 mean?

直觉可能会以为是 flex-grow: 1

但它是 flex: 1 1 0

basis 的默认是 auto, 但是 flex: 1 = flex: 1 1 0, 所以 basic 变成了 0

align-self

container 有 align-items 控制所有 item

但是如果有其中一些 item 想要例外, 那么就可以使用 align-self, 达到这样的效果

container align-items: stretch,

item 3 align-self : center

Flex Dimension

假定, flex-direction: row

主要说一下 flex 如何影响 dimension.

width: auto

假设 item 是 display block. width: auto 那么在没有 flex 的情况下它就是 fill container.

一旦添加了 flex, item 就变成了 inline, 这时 width: auto 的效果变成了 hug content.

height: auto

在没有 flex 的情况下, item height auto 表示 hug content.

一旦添加了 flex with align-items stretch, height: auto 变成了 fill container

height: percentage

How can I make Flexbox children 100% height of their parent?

Percentage Heights in Flexbox

% 是无效的, 在 flex direction row 情况下, item height 只能 stretch 填满, 或者 hardcode px 或者 hug content.

不管你 set 1%, 50%, 100%, 它的效果相等于 align-items: flex-start.

Display: inline-flex

display: flex 属于 block, 如果 width: auto 相等于 100% 跟 parent 跑.

如果想让 container hug content width (direction: row) 的话就需要用 inline flex, width: auto

inline flex 也是可以设置 width 的哦, 这个和 display: inline 不同, flex 也没有 display: inline-block-flex 这种东西.

Layout Grid by Flex

参考: Layout Grid by Flex

个人使用体验

最常拿来做 spacing. gap 取代了 margin-top

第二常用的是 align, 尤其是 center

第三常用的 RWD, 配合 wrap

RWD 方面 Flex 并没有很强, 许多时候还是需要用到 media query

比较少会用到的是控制 dimension. 比如 grow, flex-basic 等等. 如果用到的话可能也可以考虑一下 Grid 了.

冷知识 – 当 flex-direction: column 遇上 item margin-inline: auto

.container {
border: 4px solid red;
width: 300px; .box1 {
padding: 1rem;
background-color: lightblue;
width: 100px;
margin-inline: auto;
}
}

在没有 flex 的情况下, item width: 100px, margin-inline: auto 的效果如上 (我们常用的居中方案)

如果 width: auto 则 margin-inline 没有效果, 如下图

但当 container 加上 flex column 以后就不同了, 下图

虽然 item width 是 auto, 但是 margin-inline 却有效果了, 它和设置 align-self: center 是一摸一样的.

注: 通常用了 flex 就不会用 margin-inline 做 alignment 了, 我是不小心发现的.

用例子领悟

有个 container, 左边是 title, 右边是图, 各占 50%

HTML

<div class="container">
<div class="col-left">
<h1>Hello,</h1>
<h1>My name is</h1>
<h1>Arfan</h1>
</div>
<div class="col-right">
<img src="img/img1.jfif" />
</div>
</div>

CSS

.container {
display: flex;
background-color: pink;
}
.container .col-left {
flex-grow: 1;
background-color: blue;
}
.container .col-right {
flex-grow: 1;
background-color: yellow;
}

通过 flex-grow 1:1 分配 width

效果

结果发现并没有平均分配, 原因是 grow 是分配剩余的空间, 把 grow 拿掉会看见 col-left, col-right 是不一样 width.

所以正确的做法是用

flex: 1 也等价于 flex: 1 1 0

最后一个 0 就把 basis 变成 0px 了, 这样 col-left, col-right 的 width 就相同了, 然后通过 grow 增长到填满 container, 就实现了 50%

CSS – Flex的更多相关文章

  1. CSS Flex

    关于flex 请看这里  https://css-tricks.com/snippets/css/a-guide-to-flexbox/ 太详细啦!!!  还通俗易懂!!! 没啥好说的 不过上面那篇文 ...

  2. 【css flex】将多个<div>放在同一行

    使用style里的flex属性 默认情况下,一个div独占一行 使用css选择器给外层div加上以下flex属性,则该div的子div可以在同一行中显示, .runs-paginator-flex-c ...

  3. css flex兼容性

    我测试了一下css flex的兼容性 已经可以兼容到IE10了呀 为啥MDN上面的IE兼容性还是兼容到IE11 有点更新不及时的感觉

  4. 87.CSS Flex 弹性盒模型布局教程(共用的css在48篇文章gird)

    CSS Flex 弹性盒模型布局教程 Flex 是 Flexible Box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性. flex布局就是给任何一个容器添加 dis ...

  5. 【转载】CSS flex属性深入理解

    文章转载自 张鑫旭-鑫空间-鑫生活 http://www.zhangxinxu.com/ 原文链接:https://www.zhangxinxu.com/wordpress/2019/12/css-f ...

  6. CSS flex waterfall layout

    CSS flex waterfall layout https://github.com/YoneChen/waterfall-flexbox https://css-tricks.com/snipp ...

  7. CSS Flex布局完全指南 #flight.Archives002

    Title/CSS Flex布局完全指南 #flight.Archives002 序(from Ruanyf) : 网页布局(layout)是 CSS 的一个重点应用. 布局的传统解决方案,基于盒状模 ...

  8. 让CSS flex布局最后一行列表左对齐的N种方法

    原文链接https://mp.weixin.qq.com/s?__biz=MjM5MDA2MTI1MA==&mid=2649091838&idx=1&sn=fa4e1ed1e0 ...

  9. css flex布局

    关于flex布局的一些简单用法 效果(下图) 实现代码: <!--html--> <div class="wrap"> <div class=&quo ...

  10. css flex方法标题左右两边平衡线

    <html> <div class="title"> <div class="line"></div> < ...

随机推荐

  1. Docker 容器数据:持久化

    Docker 容器数据:持久化 每当从镜像创建容器时,它都会创建一个新容器,除了镜像数据之外没有任何数据 意味着如果在提交更改之前删除容器,我们将丢失数据 Docker 应该存在一种将数据的文件系统与 ...

  2. ABC354

    A link 模拟整个过程即可. 点击查看代码 #include<bits/stdc++.h> #define int long long using namespace std; sig ...

  3. mysql 忘记root密码怎么办?

    忘记root可以跳过grant table来登录 1.打开命令行输入以下命令 mysqld -nt --grant-skip-tables 2.在打开一个新命令行,输入以下命令可以登录, mysql ...

  4. windows edge浏览器免费复制网页文字

    复制时,出现上面提示时候 使用edge浏览器打开链接,在http前面加入read: ,然后打开,即可复制 如果用js,可以参考https://www.cnblogs.com/rmticocean/p/ ...

  5. PHP转Go系列 | Carbon 时间处理工具的使用姿势

    大家好,我是码农先森. 在日常的开发过程中经常会遇到对时间的处理,比如将时间戳进行格式化.获取昨天或上周或上个月的时间.基于当前时间进行加减等场景的使用.在 PHP 语言中有一个针对时间处理的原生函数 ...

  6. SemanticKernel/C#:使用Ollama中的对话模型与嵌入模型用于本地离线场景

    前言 上一篇文章介绍了使用SemanticKernel/C#的RAG简易实践,在上篇文章中我使用的是兼容OpenAI格式的在线API,但实际上会有很多本地离线的场景.今天跟大家介绍一下在Semanti ...

  7. 【Layui】07 徽章 Badge

    文档地址: https://www.layui.com/demo/badge.html 圆点徽章: <span class="layui-badge-dot">< ...

  8. 目前AI模型与CAE(计算机辅助工程)结合所能达到的技术水平?

    相关: https://www.anscos.com/odyssee.html ODYSSEE CAE只需进行几次先前的CAE模拟,即可实时预测.优化并可靠地生成准确的结果.ODYSSEE CAE以非 ...

  9. 首次配置成功rllab运行环境,给出anaconda下的配置

    name: rllab channels: - defaults dependencies: - _libgcc_mutex=0.1=main - _openmp_mutex=5.1=1_gnu - ...

  10. JUC高并发编程(一)之请求合并案例

    1.背景 在做活动或者抢购场景,系统查询的请求并发量非常高 如果并发的访问数据库,会给数据库带来很大的压力, 这时候我们可以考虑将多个查询请求合并成一个查询请求返回给客户端, 比如:根据id查询爆款产 ...