【译】掌握 Flexbox 的终极指南:从烤肉串到鸡尾酒香肠的布局哲学

🔗 原文链接:An Interactive Guide to Flexbox

👨‍💻 原作者:Josh W. Comeau

📅 发布时间:2022年11月22日,最后更新:2025年5月9日
⚠️ 关于本译文

本文基于 Josh W. Comeau 的原文进行忠实翻译,力求准确传达原作者的技术观点和逻辑结构。

🎨 特色亮点:

  • 保持原文的完整性和技术准确性
  • 采用自然流畅的中文表达,避免翻译腔
  • 添加画外音板块,提供译者的补充解读和实践心得
  • 使用生动比喻帮助理解复杂概念

💡 画外音说明: 文中标注为画外音的部分是译者基于实际开发经验添加的拓展解释,旨在帮助读者更好地理解和应用这些概念,不代表原作者观点。

🖼️ 关于交互式示例: 本文中的图片和交互式演示以截图和GIF动图形式呈现。如需体验完整的交互式功能,建议前往原文进行实际操作。

🚀 简介

Flexbox 是一种非常强大的布局模式。当我们真正理解它如何工作时,就能构建出能自动响应、按需重排列的动态布局。

例如,看看这个例子:

这个演示深受 Adam Argyle 那个令人惊艳的 "4 layouts for the price of 1" CodePen 的启发。它没有使用任何媒体查询或容器查询。它并非通过设置任意断点,而是使用流体原则来创建一个能无缝流动的布局。

相关 CSS 代码:

css 复制代码
form {
  display: flex;
  align-items: flex-end;
  flex-wrap: wrap;
  gap: 16px;
}
.name {
  flex-grow: 1;
  flex-basis: 160px;
}
.email {
  flex-grow: 3;
  flex-basis: 200px;
}
button {
  flex-grow: 1;
  flex-basis: 80px;
}

我记得以前看到这种演示时完全懵逼。我知道 Flexbox 的基础,但这玩意儿看起来简直像魔法!✨

在这篇博文里,我想精炼你对 Flexbox 的心智模型。 我们会通过学习每个属性来建立对 Flexbox 算法的直觉。无论你是 CSS 新手,还是用了好几年 Flexbox 的老手,我打赌你都会学到不少东西!

走起!🎉

⚠️ Content warning(内容警告)

在本教程后面我会用到一个与食物相关的比喻。🍖


📚 Flexbox 简介

CSS 由许多不同的布局算法组成,官方称它们为"布局模式(layout modes)"。每种布局模式都是 CSS 中的一个小子语言。默认的布局模式是流式布局(Flow layout),但我们可以通过在父容器上改变 display 属性来启用 Flexbox。

当我们把 display 切换为 flex 时,就创建了一个flex 格式化上下文(flex formatting context)。这意味着默认情况下,所有子元素都会依据 Flexbox 布局算法被摆放。

🔔画外音

这里作者用了一个很形象的比喻,把不同的布局模式比作不同的"子语言",这确实很贴切。每种布局模式都有自己的规则和特性,就像不同的编程语言一样。)

每个布局算法都是为了解决特定问题而设计的。默认的"Flow"布局是为了创建数字文档(digital documents);它本质上就是类似 Microsoft Word 的布局算法。标题和段落垂直堆叠,而像文本、链接和图片之类的内容则在这些块级元素内部静静存在。

那么,Flexbox 解决的是什么问题?Flexbox 专注于在一行或一列中排列一组项目,并给我们大量控制这些项目分布和对齐方式的能力。正如名字所示,Flexbox 是关于"灵活性"的。我们可以控制项目是否增长或收缩、如何分配多余空间,等等。

Is it still relevant?(它仍然适用吗?)

你可能会想:既然 CSS Grid 在现代浏览器中已经得到了很好的支持,Flexbox 是否已过时?

CSS Grid 是一个很棒的布局模式,但它解决的问题与 Flexbox 不同。我们应该都学会这两种布局模式,并在合适的场景使用合适的工具。

当涉及到动态、流体的 UI(在垂直或水平方向排列的列表)时,Flexbox 仍然是王者。在本指南里我们会看到一个例子 ------ 分解的煎饼(deconstructed pancake),这并不容易用 CSS Grid 来完成。

说实话,即便我同时熟悉 Grid 和 Flexbox,我仍然经常选择 Flexbox!


🔄 Flex direction(方向)

如前所述,Flexbox 的重点是控制元素在行或列中的分布。默认情况下,子元素会在一行里并排放置,但我们可以通过 flex-direction 将其改为列:

  • flex-direction: row 时,主轴(primary axis)水平运行,从左到右。
  • flex-direction: column 时,主轴垂直运行,从上到下。

在 Flexbox 中,一切都基于主轴(primary axis)。算法并不关心垂直/水平行/列这些表面概念------所有规则都是围绕主轴和垂直于主轴的交叉轴(cross axis)构建的。

这很酷。当我们掌握了 Flexbox 的规则后,就可以在水平布局和垂直布局之间无缝切换。所有规则会自动适配。这个特性是 Flexbox 所独有的。

子元素默认会按照下面两条规则进行定位:

  • 主轴:子元素会聚拢在容器的起点。
  • 交叉轴:子元素会拉伸以填满整个容器。

在 Flexbox 中,我们决定主轴是水平还是垂直运行。这是所有 Flexbox 计算的基础。


🎯 Alignment(对齐)

我们可以使用 justify-content 来改变子元素沿主轴的分布:

当谈到主轴时,我们通常不会单独考虑对齐一个子元素,而是考虑整组元素的分布。

我们可以把所有项目堆到某个位置(flex-startcenterflex-end),也可以把它们分散(space-betweenspace-aroundspace-evenly)。

对于交叉轴,我们用 align-items

有趣的是......align-itemsjustify-content 有一些相同的选项,但并不完全一致。

为什么不共享相同选项?我们稍后会揭开这个谜团,但在那之前,我需要再分享一个对齐相关的属性:align-self

justify-contentalign-items 不同,align-self 应用于子元素,而不是容器。它允许我们改变某个特定子元素沿交叉轴的对齐方式:

align-self 拥有与 align-items 相同的值。事实上,它们改变的是完全相同的东西。align-items 是语法糖,一个便捷的写法,会自动把对齐设置应用到所有子元素上。

没有 justify-self*。要理解为什么没有,就得深入 Flexbox 算法了。


🍖 Content vs. items(内容组 vs 单个项目)

根据到目前为止学到的内容,Flexbox 可能显得有些任意。为什么是 justify-contentalign-items,而不是 justify-itemsalign-content

更进一步,为什么有 align-self,但没有 justify-self

这些问题指向了 Flexbox 中一个非常重要且常被误解的点。为了解释这一点,我要用一个比喻。

在 Flexbox 中,项目沿主轴分布。默认情况下,它们会并排排列。我可以画一条直线,把所有子元素都"串"起来,就像串烤肉串(kebab)一样:

交叉轴则不同。一条垂直线只会穿过其中一个子元素。它更像是一组鸡尾酒小香肠(cocktail wieners,一口大小的热狗/维也纳香肠):

这里有一个显著的差别。对交叉轴而言,每个项目可以沿着自己的签子独立移动,而不会影响其他项目

但对主轴而言,所有项目被同一根大签子串着,一个项目在主轴上移动会挡到别的项目。试想拖动中间那块往左右移动:

🔔画外音

这个烤肉串和鸡尾酒小香肠的比喻真的很巧妙!它完美地解释了为什么主轴和交叉轴的行为如此不同。主轴上的项目必须作为一个整体来考虑,而交叉轴上的项目可以独立调整。

这是主轴 / 交叉轴之间最根本的区别。当我们在交叉轴上谈论对齐时,每个项目都可以单独移动;而在主轴上,我们只能以组(group)的方式来考虑如何分配空间。

这就是为什么没有 justify-self 。如果让中间那块设置 justify-self: flex-start,那意味着什么?前面已经有个别的项目在那儿了!

带着这些背景,我们给下面四个术语下一个准确的定义:

  • justify --- 在主轴上定位某些东西。
  • align --- 在交叉轴上定位某些东西。
  • content --- 可被分配的内容组。
  • items --- 能被单独定位的单个项目。

所以:我们有 justify-content 来控制主轴上这一组内容的分布;我们有 align-items 来控制每个项目在交叉轴上的定位。这是我们用来管理 Flexbox 布局的两个主要属性。

没有 justify-items 的原因与没有 justify-self 的原因相同:在主轴上,我们必须把项目当作内容组来考虑,而不是单个项目。

align-content 呢?实际上,Flexbox 中确实存在 align-content!我们会在讨论 flex-wrap 属性时讲到它。


💡 Hypothetical size(假设尺寸)

让我们谈谈一个让我醍醐灌顶的认识。

假设我写了下面的 CSS:

css 复制代码
.item {
  width: 2000px;
}

一个理性的人可能会说:"好吧,我们会得到一个 2000 像素宽的元素。"但这在任何情况下都成立吗?

我们来测试一下:

有意思吧?

这两个元素有完全相同的 CSS:每个都设置了 width: 2000px。但第一个元素比第二个要宽很多!

区别在于布局模式。第一个元素在流式布局下渲染,在流式布局中,width 是一个硬性约束 。当我们设置 width: 2000px 时,我们就会得到一个 2000 像素宽的元素,即使它得突破视口边界。

而在 Flexbox 中,width 属性被以不同的方式实现。它更像是一个建议,而不是硬性约束

规范为此有一个名称:假设尺寸(hypothetical size) 。它是一个元素在理想世界中会是什么大小的度量------也就是没有任何限制时的尺寸。

可惜现实往往不同。在这个例子里,限制因素是父容器没有足够空间容纳一个 2000px 的子元素。因此,子元素的尺寸会被缩小以适配。

这是 Flexbox 哲学的核心。东西是流动且灵活的,会根据世界的约束做出调整。

🔔画外音

这个概念真的很重要!很多开发者会困惑为什么设置了 width 但元素没有按预期显示。理解"假设尺寸"这个概念,就能明白 Flexbox 的灵活性本质!
Inputs for the algorithms(算法的输入)

我们倾向于把 CSS 看成属性的集合,但我认为这是不准确的心智模型。正如我们看到的,width 属性的行为会根据使用的布局模式不同而不同!

相反,我更喜欢把 CSS 看成一组布局模式。每个布局模式是一个算法,可以实现或重新定义每个 CSS 属性。我们通过写 CSS 声明(键/值)来给算法提供输入(就像给函数传参)。算法会决定如何使用这些输入。

换句话说,我们写的 CSS 是这些算法的输入。若要真正熟悉 CSS,仅仅学属性名称是不够的;我们要学习算法如何使用这些属性。

这也是我在课程《CSS for JavaScript Developers》中采取的核心理念。不是让你记一堆难懂的 CSS 片段,而是把语言的引擎盖掀开,让你了解所有布局模式是如何工作的。


📈 Growing and shrinking(增长与收缩)

到目前为止,我们看到了 Flexbox 算法的某些内置灵活性(比如假设尺寸)。但要真正理解 Flexbox 的流动性,我们需要讨论三个属性:flex-growflex-shrinkflex-basis

下面逐一讲解这些属性。

📐 flex-basis

老实说:很长一段时间我并不太懂 flex-basis 的真正含义。😅

简单来说:在一个 Flex 行(Flex row)中,flex-basis 的作用和 width 一样;在一个 Flex 列(Flex column)中,flex-basis 的作用和 height 一样。

如前所述,Flexbox 中的一切都以主轴/交叉轴为基准。例如,justify-content 会沿主轴分配子元素,它在主轴为水平或垂直时表现一致。

widthheight 并不遵循这个规则:width 总是影响水平尺寸,它不会在 flex-directionrow 切到 column 时自动变成 height

因此,Flexbox 的作者引入了一个通用的"尺寸"属性 flex-basis。它类似于 widthheight,但被钉在主轴方向上(和 Flexbox 的其它属性一致)。它允许我们为元素在主轴方向设定假设尺寸,无论主轴是水平还是垂直。

试试这个效果:每个子元素都设了 flex-basis: 50px,但你可以调整第一个子元素的值来观察差异。

width 一样,flex-basis 更像是建议而不是硬约束。当空间不足以让所有元素按其设定尺寸显示时,算法会让它们妥协以避免溢出。

Not exactly the same(并非完全相同)

在通常情况下,在 Flex 行中 widthflex-basis 可以互换使用,但也有例外。例如,width 会以不同方式影响替换元素(replaced elements 例如图片)与 flex-basis;另外,width 能把元素缩小到低于其最小尺寸,而 flex-basis 则不能。

虽然这些细节超出了本文的讨论范围,但我还是想提一下,因为你可能会遇到这两个属性产生不同效果的边缘情况。

📈 flex-grow

默认情况下,在 Flex 环境下,元素会缩小到它们在主轴方向上的最小舒适大小。这样常常会产生多余空间。

我们可以用 flex-grow 指定这些空间该如何被消耗:

flex-grow 的默认值是 0,这意味着增长是需要显式启用的。如果我们想让某个子元素吞噬容器中的多余空间,就必须明确告诉它。

如果多个子元素同时设置了 flex-grow,那么额外空间将按它们的 flex-grow 值按比例分配。

举例说明会更直观。把每个子元素的 flex-grow 值增减试试:

上图解释如下:第一个子元素想要 3 个单位的额外空间,而第二个子元素想要 2 个单位。这意味着单位总数是 5(3 + 2)。每个子元素都会按比例获得那部分额外空间。

🔔画外音

flex-grow 的比例分配机制真的很巧妙!它让布局变得非常灵活,我们可以精确控制每个元素应该获得多少额外空间。

📉 flex-shrink

在我们到目前为止看到的大多数例子都是容器有额外空间。但如果子元素对容器来说太大怎么办?

来试试缩小容器看看发生什么:

有意思吧?两个元素都被缩小了,但它们是按比例缩小的。第一个元素总是第二个元素宽度的 2 倍。

友情提醒:flex-basis 在 Flex 行中起到的作用与 width 一样。我们这里用 flex-basis,因为这是约定俗成的用法,但如果用 width,结果也是一致的!

flex-basiswidth 设定了元素的假设尺寸。虽然 Flexbox 算法可能会把元素缩小到低于这个建议尺寸,但默认情况下,它们会一起按比例缩放,从而保持它们之间的比例关系。

但如果我们不希望元素按比例缩小怎么办?这就是 flex-shrink 的作用所在。

花几分钟时间戳这个演示。看看你是否能弄清楚这里发生了什么。我们将在下面探索。

好的,让我们来具体分析一下:我们有两个子元素,每个都有 250px 的假设尺寸。容器需要至少 500px 宽才能让这些子元素按假设尺寸显示。

现在假设我们将容器缩小到 400px。显然,我们不能把 500px 的内容硬塞进 400px 的空间里!我们面临着 100px 的赤字。元素们总共需要放弃 100px 才能适配。

flex-shrink 属性让我们决定如何分配这个赤字。

就像 flex-grow 一样,它也是按比例工作的。默认情况下,两个子元素都有 flex-shrink: 1,所以每个子元素承担一半的赤字。它们各自放弃 50px,实际尺寸从 250px 缩小到 200px。

现在,假设我们将第一个子元素的 flex-shrink 调到 3:

我们仍然有 100px 的总赤字。通常情况下,每个子元素会承担一半,但因为我们调整了 flex-shrink,第一个元素最终承担 3/4(75px),第二个元素承担 1/4(25px)。

注意绝对值并不重要,关键在于比例关系。如果两个子元素都设为 flex-shrink: 1,每个子元素会承担总赤字的一半。如果两个子元素都设为 flex-shrink: 1000,每个子元素会承担总赤字的 1000/2000。无论哪种情况,最终结果都是相同的。

收缩和比例

在我们刚才看的示例中,两个 Flex 子元素具有相同的假设尺寸(250px)。在计算如何收缩它们时,我们可以仅凭 flex-shrink 来计算。

不过,正如我们之前看到的,收缩算法也会尽力保持兄弟元素之间的比例。如果第一个子元素是第二个子元素大小的 2 倍,它会收缩得更积极。

因此,完整的计算会同时考虑每个子元素的相对 flex-shrink 值以及它们相对的尺寸。
🔔画外音

这里作者用了一个很形象的比喻------"不能将 500px 的内容塞进 400px 的袋子里",这让我们更容易理解为什么需要 flex-shrink 来分配"赤字"。

我曾对 flex-shrink 有过一个顿悟:我们可以把它看作是 flex-grow 的"反向版本"。它们是同一枚硬币的两面:

  • flex-grow 控制当元素比容器小(有额外空间)时,如何分配剩余空间。
  • flex-shrink 控制当元素比容器大(需要收缩)时,如何移除空间。

这意味着这两个属性在任一时刻只有一个会生效:若有额外空间,flex-shrink 不起作用;若子元素过大以至需要缩小,flex-grow 不起作用。

我喜欢把它想成两个不同的世界 ------ 你不是在"地球",就是在"颠倒世界"。每个世界都有自己的规则。

🛡️ 防止收缩

有时,我们不希望某些 Flex 子元素被缩小。

这种情况我在处理 SVG 图标和形状时经常遇到。看下面的简化示例:

当容器变窄时,我们的两个圆会被压成难看的椭圆。如果我们希望它们保持圆形,该怎么办?

可以把 flex-shrink: 0 设置上去:

当把 flex-shrink 设为 0,就等于从收缩过程中"退出来"。Flexbox 算法会把 flex-basis(或 width)视作一个硬性最小限制。

下面是这个示例的完整代码(以下只是部分截图,感兴趣请直接查看原文):

更简单的方法?

我在课程里教这个概念时,有人会问:为什么我们要用 flex-shrink,而不是用更简单的方法?

css 复制代码
.item.ball {
  min-width: 32px;
}

几年前我会同意这个想法。如果设了最小宽度,元素就不会被缩小到下面去!我们通过添加一个硬限制来替代 width / flex-basis 的软限制。

但我现在觉得在很多情形下,把 flex-shrink: 0 设上去才是更直接、更明了的解决方案。当然,min-width 在 Flexbox 算法中仍然有重要作用!下面我们继续讲它。

⚠️ 最小尺寸陷阱

这里还有一件超级重要的事。可能是本文中最有帮助的一点!

假设我们在做一个流体的电商搜索表单:

当容器收窄到某个点,内容会溢出!

但为什么会这样?默认 flex-shrink1,而我们并没有移除它,所以搜索输入框应该可以按需缩小才对!但它偏偏不肯再缩。

这是因为,除了假设尺寸(hypothetical size),Flexbox 算法还关心另一个尺寸:最小尺寸(minimum size)

Flexbox 算法不会把子元素缩小到它的最小尺寸以下。内容会溢出而不是继续缩小,不管你把 flex-shrink 调得多大!

文本输入在不同浏览器有默认的最小尺寸(大约 170px--200px),这就是上面那个问题的根源。

在其他情况下,限制因素可能是元素内部的内容。例如,尝试调整这个容器的大小:

对于包含文本的元素,最小宽度等于最长不可换行字符串的长度。

好消息是:我们可以用 min-width 改写最小尺寸。

如果直接在 Flex 子元素上设置 min-width: 0px,我们告诉 Flexbox 算法覆盖"内建"的最小宽度。由于我们把它设为 0px,元素就可以按需收缩到任意小。

同样的技巧在 Flex 列中也适用(使用 min-height),不过这个问题在列方向出现得没那么频繁。

谨慎使用

值得注意的是,内建的最小尺寸是有用的------它作为一种护栏,防止发生更糟糕的事情。

比如说:当我们对包含文本的 Flex 子元素直接应用 min-width: 0px 时,事情可能会变得更糟

能力越大,责任越大,min-width 在 Flexbox 中是一个特别强大的属性。它不止一次让我摆脱困境,但我总是小心确保我没有让事情变得更糟。 总结一句话:min-width 是一把锋利的刀,用对了能救急,滥用就会把页面肢解。用它时要小心!
画外音

这个"最小尺寸陷阱"真的是很多开发者都会遇到的坑!特别是当使用 flex-shrink 但元素仍然不收缩时,往往就是因为最小尺寸的限制。理解这个概念能解决很多布局问题。


📏 间距

近年来对 Flexbox 最大的体验改进之一就是 gap 属性的加入:

gap 允许我们在每个 Flex 子元素之间创建间距。这对像导航头部这样的场景特别适用:

gap 是 Flexbox 语言中相对较新的补充,但自 2021 年初以来已在现代浏览器中得到广泛实现


🎯 自动边距

还有一个与间距相关的技巧想要分享。它从 Flexbox 早期就存在,但相对冷门,当我第一次发现时简直震惊。

margin 通常用于在特定元素周围添加空间。在某些布局模式(如流式布局和定位布局)中,它甚至可以用来居中元素(margin: auto)。

在 Flexbox 中,自动外边距更有意思:

我们之前看到 flex-grow 能吞噬多余空间,把它分配给子元素。

自动外边距会吞噬多余空间,但把它应用到元素的外边距上。它让我们能精确控制多余空间该分配到哪里。

常见的头部布局是:左侧是 logo,右侧是一些导航链接。下面是利用自动外边距实现该布局的方式(请到原文查看完整实现):

把公司 Logo 放在列表的第一个项,通过给它 margin-right: auto,把所有额外空间收集到第一个和第二个项之间,从而把导航推到右侧。

我们可以在浏览器开发工具中看到发生了什么:

当然还有很多其他方法可以解决这个问题:把导航链接分组到自己的 Flex 容器,或者用 flex-grow 让第一个列表项增长。但我个人很喜欢自动外边距的方案。它把多余空间当成资源,让我们决定把资源放到哪儿。

画外音

自动边距真的是一个很巧妙的技巧!它让我们可以精确控制额外空间的分布,这在很多布局场景中都非常有用。


🔄 换行

呼!到现在为止我们已经覆盖了很多内容。最后还有一个重要的收获要分享。

到目前为止,所有项目都在单行/单列里并排。flex-wrap 属性允许我们改变这一点。

看下面的例子:

大多数时候,当我们需要二维布局时,我们会去用 CSS Grid。但 Flexbox 加上 flex-wrap 仍然有它的用途!这个例子展示了"分解的煎饼(deconstructed pancake)"布局:在中等尺寸屏幕上,3 个项目会堆成一个倒三角形。

当我们设置 flex-wrap: wrap 时,项目不会被缩小到低于它们的假设尺寸 ------ 起码当换行到下一行/列是可行选项时不会被缩小。

但等等!我们的烤肉串 / 鸡尾酒香肠比喻呢?

flex-wrap: wrap 时,我们不再有那根可以串住每个项目的单一主轴线。实际上,每行(或每列)都变成了它自己的小型 Flex 容器。不是一根大串,而是每一行各有一根小串:

我们学过的规则在这个缩小的范围内依旧适用。比如 justify-content 会在每行内分配项目。

但是......那 align-items 在有多行时会怎样?交叉轴可能会穿过多行项!

想一想会发生什么。当你有答案(或至少有了猜想)后,再去验证看看:

每一行现在都是自己的迷你 Flexbox 环境。align-items 会让每个项目在包围该行的隐形盒子内上下移动。

但如果我们想要对行本身进行对齐怎么办?那时就用 align-content

总结如下:

  • flex-wrap: wrap 让我们有两行项目。
  • 在每行内部,align-items 让每个单独的子元素上下移动。
  • 放大视角看,我们有多行处于同一个 Flex 上下文中!交叉轴现在会穿过多行。因此我们不能单独移动某一行,我们要以组(content)的形式分配它们的位置。
  • 使用我们前面定义的术语:这时我们处理的是 content(内容),而不是 items(项目)。而又因为这是在交叉轴上,所以使用 align-content

画外音

这里又回到了我们之前学到的内容组 vs 单个项目的概念!当有多行时,我们需要用 align-content 来对齐行组,而不是单个项目。这完美地展示了 Flexbox 概念的一致性。


🎉 恭喜完成!

我想承认一些事情:这是一个密集的教程。 我们已经深入兔子洞,除非你已经是 Flexbox 专家,否则我预计你的头会有点晕。😅

就像 CSS 中的很多东西一样,Flexbox 在你刚开始时可能看起来很简单,但当你超越基础时,复杂性会迅速上升。

结果,我们中的许多人在 CSS 方面遇到了早期的高原期。我们知道足够的知识来完成工作,但这是一个持续的挣扎。这种语言感觉摇摇欲坠和不可预测,就像一座古老的绳桥,随时可能断裂。当它断裂时,我们向问题投掷随机的 StackOverflow 片段,希望有什么能帮助。

这确实很糟糕,因为 CSS 是大多数前端开发工作中很重要的一部分!

事实是,CSS 实际上是一种深度健壮和一致的语言。 问题是我们大多数人的心智模型是不完整和不准确的。当我们花时间建立对语言的正确直觉时,一切都会豁然开朗,CSS 变成了绝对令人愉快使用的语言。✨

我为了解决这个问题,做了一个综合课程,叫《CSS for JavaScript Developers》

如果你觉得这篇博文有帮助,你会喜欢那门课。课程采用类似的方法,但覆盖整个 CSS 语言,并配有练习和项目,确保你能真正掌握新技能。课程专门为使用 JS 框架(如 React/Angular/Vue)的人设计。80% 的内容聚焦 CSS 基础,另外还展示了如何把这些基础整合到现代 JS 应用中、如何组织 CSS、以及其它实务内容。

如果你在 CSS 上挣扎,建议去看看。掌握 CSS 会极大提升你的开发效率,特别是当你同时熟悉 HTML 和 JS 时。三者合一,会让你更容易进入开发状态,真正享受构建应用的过程。💖


🎁 彩蛋:解析演示

在本教程开始时,我们看到了那个 4 layouts for the price of 1 的演示。

现在我们已经学了 Flexbox 算法的很多细节,你能弄懂它是怎么工作的吗?欢迎在代码中试验:

让我们逐步解析它是如何实现的(以下是一个将近 5min 的视频,无法在掘金展示,请大家进原文查看):

以上的代码示例和讲解视频请大家点进原文查看!

感谢你的阅读!这篇博文花了我很多功夫,我非常高兴它终于发布了!希望你觉得有用。💖

相关推荐
绝无仅有3 小时前
大厂Redis高级面试题与答案
后端·面试·github
绝无仅有3 小时前
面试问题之导致 SQL 查询慢的原因及优化建议
后端·面试·github
在未来等你4 小时前
Kafka面试精讲 Day 18:磁盘IO与网络优化
大数据·分布式·面试·kafka·消息队列
那一抹阳光多灿烂4 小时前
CSS 编码规范
前端·css
程序员清风4 小时前
滴滴三面:ZGC垃圾收集器了解吗?
java·后端·面试
degree5204 小时前
CSS :has() 选择器详解:为什么它是“父选择器”?如何实现真正的容器查询?
前端·css·css3
૮・ﻌ・4 小时前
CSS高级技巧---精灵图、字体图标、布局技巧
前端·css
昔人'5 小时前
纯`css`固定标题并在滚动时为其添加动画
前端·css
三角叶蕨5 小时前
javaweb CSS
css·web