CSS 布局入门

已发表: 2022-03-10
快速总结 ↬无论您是 CSS 新手,还是堆栈中其他地方的经验丰富的开发人员,想要确保您今天对布局的理解是最新的,本指南涵盖了您今天需要了解的有关 CSS 布局的所有信息。

在过去的几年中,CSS 布局以及我们开发网站前端的方式发生了巨大变化。 对于我们在 CSS 中使用的布局方法来开发我们的网站,我们现在有了一个真正的选择,这意味着我们经常需要选择采用哪种方法。 在本文中,我将通过解释它们的使用方式和用途的基础知识来介绍您可以使用的各种布局方法。

如果您是 CSS 新手并且想知道处理布局的最佳方法是什么,并且如果您是堆栈中其他地方的经验丰富的开发人员,并且希望确保您今天对布局的理解是最新的,那么本指南适合您. 我没有尝试在这里完整记录每种布局方法,因为那样会创建一本书而不是一篇文章。 相反,我将概述您可以使用的内容,并提供大量链接以了解更多信息。

正常流量

如果您使用没有应用 CSS 的 HTML 网页来更改布局,则元素将以正常流显示。 在正常流程中,根据文档的编写模式,一个个显示框。 这意味着,如果您有一个横向书写模式,其中句子从左到右或从右到左运行,正常流程将在页面垂直向下一个接一个地显示块级元素的框。

跳跃后更多! 继续往下看↓

如果您处于垂直写作模式,那么句子会垂直运行,因此正常流程会将块水平放置。

显示 Block Axis 在垂直书写模式下是水平的,在水平书写模式下是垂直的
块和内联方向随书写模式而变化

正常流程是您从任何布局开始的地方:当您创建 CSS 布局时,您正在获取块并导致它们执行与正常流程不同的操作。

构建文档以利用正常流程

您可以通过确保文档以结构良好的方式开始来利用正常流程。 想象一下,如果——而不是这种正常流程的概念——浏览器将你所有的盒子堆叠在一个角落里,直到你创建了一个布局。 这意味着您必须将每一件事都放在页面上。 相反,浏览器以一种立即可读的方式显示我们的内容。

如果您的 CSS 无法加载,用户仍然可以阅读内容,而根本没有获得 CSS 的用户(例如使用屏幕阅读器的用户)将按照文档中的顺序将内容交付给他们。 从可访问性的角度来看,这使得您的 HTML 文档以良好的顺序开始生活很重要。 但是,它也将使您作为 Web 开发人员的生活更轻松。 如果您的内容按照用户期望的顺序阅读,则无需对布局进行大量更改即可将其放置在正确的位置。 使用更新的布局方法,您可能会惊讶于您需要做的事情是如此之少。

因此,在考虑布局之前,请考虑文档结构以及您希望从文档顶部到底部读取内容的顺序。

远离正常流量

一旦我们有了一个结构良好的文档,我们就需要决定如何把它变成我们想要的布局。 对于我们文档的部分内容,这将涉及远离正常流程。 我们有一整套布局方法可供使用。 我们要看的第一个方法是float ,因为 float 很好地展示了如何将元素从正常流中取出。

花车

浮动用于将框向左或向右移动,允许内容围绕它显示。

为了使项目浮动,请使用 CSS 属性float和 left 或 right 值。 浮动的默认值为无。

 .item { float: left; }

值得注意的是,当您浮动一个项目并且文本环绕它时,会发生该内容的行框被缩短。 如果您浮动一个项目并且包含您的文本的以下框应用了背景颜色,您可以看到该背景颜色将在浮动项目下方运行。

一个向左浮动的块,其右侧文本的背景色在该块下方运行
内容上的背景颜色在浮动下运行

当您缩短行框以便在浮动和换行文本之间留出空间时,您必须在浮动项目上设置边距。 文本上的边距只会将文本从容器边缘移入。 对于向左浮动的图像,您将在右侧和底部添加边距,假设您希望图像与容器的顶部和左侧齐平。

请参阅 CodePen 上的 Rachel Andrew (@rachelandrew) 的 Pen Smashing Guide to Layout:float。

请参阅 CodePen 上的 Rachel Andrew (@rachelandrew) 的 Pen Smashing Guide to Layout:float。

清除浮动

浮动元素后,以下所有元素将环绕该浮动元素,直到它们环绕在下方并继续正常流动。 如果你想防止这种情况,你需要清除浮动。

在要在浮动后开始显示的元素上,添加值为 left 的属性clear以指示清除向左浮动的项目,使用 right 以清除向右浮动的项目,或同时清除任何浮动项目。

 .clear { clear: both; }

如果您希望元素在浮动之后开始,则上述方法有效。 如果您发现自己处于一个盒子里有一个浮动项目并且旁边有一些文本的情况,这将无济于事。 如果文本比浮动项短,则框将绘制在内容下方并忽略浮动。 正如我们已经了解到的,浮动缩短了行框,布局的其余部分继续正常流动。

浮动框从容器底部伸出
文本周围的框不清除浮动

为了防止这种情况,我们需要清除盒子里的东西。 我们可以添加一个空元素并将其设置为全部清除。 这涉及将空 div 粘贴到我们的文档中,这并不理想,如果您的页面是由 CMS 生成的,则可能无法实现。 因此,典型的清除浮动方法是所谓的清除修复黑客。 此方法通过添加 CSS 生成的内容并将其设置为清除两者来工作。

请参阅 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout: clearfix。

请参阅 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout: clearfix。

块格式化上下文

清除框内浮动的另一种方法是调用容器上的块格式化上下文 (BFC)。 块格式化上下文包含其中的所有内容,其中包括无法再从盒子底部伸出的浮动项目。 有几种方法可以强制执行 BFC,最常见的清除浮点数的方法是将溢出属性设置为具有默认可见以外的值。

 .container { overflow: auto; }

以这种方式使用溢出通常会起作用,但是,在某些情况下,您最终可能会在项目上出现剪切阴影或不需要的滚动条。 它在你的样式表中也可能看起来有点混乱:你设置溢出是因为你想要滚动条还是只是为了获得这种清除能力?

为了使意图更清晰并防止创建 BFC 导致不必要的副作用,您可以使用flow-root作为display属性的值。 display: flow-root唯一要做的就是创建一个 BFC,从而清除您的浮点数而不会引起其他问题。

 .container { display: flow-root; }

浮点数的传统用法

在新的布局方法出现之前,浮动被用来创建列布局,这种技术通过给一组项目一个宽度并将它们设置为彼此相邻浮动来工作。 仔细管理这些浮动框的百分比大小可能会产生网格效果。

我不建议现在开始新设计并使用这种方法。 但是,它将在未来许多年内保留在现有站点中。 因此,如果您遇到几乎所有东西似乎都是浮动的设计,这就是正在使用的技术。

关于浮动和清除浮动的资源和进一步阅读

  • “Clearfix:强制元素自行清除其子级,” Chris Coyier,CSS-Tricks
  • float ”,CSS:层叠样式表,MDN 网络文档
  • clear ”,CSS:层叠样式表,MDN 网络文档
  • “理解 CSS 布局和块格式化上下文”,Smashing Magazine 的 Rachel Andrew

定位

要从正常流程中移除元素或将其从正常流程中的位置移动,您可以使用 CSS 中的position属性。 在正常流程中,元素的positionstatic 。 这些项目在块维度中一个接一个地显示,如果您滚动页面,它们会随之滚动。

在更改位置值时,您通常还会使用偏移值从特定参考点移动框。 使用的参考点取决于您使用的位置值。

相对定位

如果一个项目有position: relative那么参考点是它通常在正常流程中的位置。 然后,您可以使用属性topleftbottomright的偏移值来将框从通常显示的位置移动。

 .item { position: relative; bottom: 50px; }

请注意,页面上的其他项目不会响应您元素的新位置。 它在正常流程中的位置是保留的,因此您需要自己管理任何重叠。

请参阅 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout:相对定位。

请参阅 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout:相对定位。

绝对定位

在项目上设置position: absolute ,它将完全从正常流程中删除。 留给它的空间将被删除。 然后该项目将相对于它的包含块定位,除非它嵌套在另一个定位元素中,否则它将是视口。

因此,如果您在一个项目上设置position: absolute ,首先会发生的事情是它通常最终会卡在视口的顶部和左侧。 然后,您可以使用属性topleftbottomright的偏移值将框从该位置移动到您想要的位置。

 .item { position: absolute; top: 20px; right: 20px; }

通常你不希望盒子根据视口定位,但参考包含元素,它在里面。 在这种情况下,您需要给该包含元素一个位置值,而不是默认的静态值。

设置position: relative不会从正常流程中删除项目,这是通常的选择。 给父元素您希望从position: relative ,然后从该元素的边界偏移绝对定位的块。

请参阅 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout:绝对定位。

请参阅 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout:绝对定位。

固定定位

在大多数情况下,带有position: fixed的东西会相对于视口定位,并从文档流中移除,这样就不会为其保留空间。 当页面滚动时,固定元素保持相对于视口的位置,因为正常流程中的其余内容照常滚动。

 .item { position: fixed; top: 20px; left: 100px; }

这有助于启用固定在屏幕上的导航面板,例如在内容滚动时。 与其他定位值一样,在执行此操作时可能会导致重叠,因此您应注意所有内容都可以读取,并且不会出现在固定项目后面。

请参阅 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout:Fixed position。

请参阅 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout:Fixed position。

要定位固定项目而不是相对于视口,您需要有一个包含元素,其transformperspectivefilter属性之一设置为默认值none以外的值。 在这种情况下,该元素将成为包含块,并且您的偏移量与该块相关,而不是视口。

粘性定位

设置position: sticky元素会导致元素像在正常流程中一样随着文档滚动,但是,一旦它到达相对于视口的某个点(使用通常的偏移量),它就会“粘住”并开始表现得像position: fixed 。 这是一个较新的值,并且在浏览器中的支持不如其他方法,但是,它回退到仅使用页面滚动 os 是一个很好地用作增强功能的值,如果不支持它不会导致问题。

 .item { position: sticky; top: 0; }

这是如何创建导航栏随内容滚动然后在视口顶部停止以在滚动内容时停留在屏幕上的流行效果的方法。

请参阅 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout:粘性定位。

请参阅 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout:粘性定位。

关于定位的资源和进一步阅读

  • “定位”,MDN 学习区,MDN 网络文档,Mozilla
  • position: sticky; ,” Chris Coyier,CSS 技巧
  • “CSS position:sticky”,浏览器对粘性定位的支持信息,caniuse

弹性布局

弹性盒布局(Flexbox)是一种专为一维布局而设计的布局方式。 一维意味着您希望将内容布置成一行或一列。 要将元素转换为 flex 布局,请使用值为flexdisplay属性。

 .container { display: flex; }

该元素的直接子元素成为弹性项目,它们将排列成一行,与内联方向的起始边缘对齐。

请参阅 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout: flex。

请参阅 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout: flex。

Flexbox 的轴心

在上面的示例中,我将项目描述为在行内方向上与行的起始边缘对齐,而不是将它们描述为与左侧对齐。 我们的项目排成一行,因为flex-direction属性的默认值为row ,这会在行内方向创建一行,即句子运行的方向。 由于我们使用的是英语,一种从左到右的语言,一行的开始在左边,所以我们的项目从那里开始。 因此flex-direction的值定义了 Flexbox 的主轴

因此,交叉轴以直角穿过主轴。 如果您的 flex-direction 是row并且您的项目以 inline 方向显示,则您的交叉轴在 Block 方向上运行。 如果您的flex-directioncolumn ,因此项目在 Block 方向上运行,那么您的横轴沿行。

如果您在使用 Flexbox 时习惯于考虑主轴和交叉轴,它会让很多事情变得更容易。

方向与秩序

Flexbox 使您能够通过使用flex-directionrow-reversecolumn-reverse来更改主轴上项目的方向。

请参阅 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout: flex-direction。

请参阅 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout: flex-direction。

您还可以使用order属性更改单个弹性项目的顺序。 但是,这样做时您应该非常小心,因为这可能会给使用键盘而不是鼠标或触摸屏导航的任何用户带来问题,因为文档的 Tab 键顺序将遵循源中内容的顺序。 有关更多详细信息,请参阅下面的视觉和文档顺序部分。

弹性属性

flex 属性是如何控制 flex 项目沿主轴的比率。 这三个属性是:

  • flex-grow
  • flex-shrink
  • flex-basis

这些通常以flex属性的简写形式使用,第一个值是flex-grow ,第二个是flex-shrink ,第三个是flex-basis

 .item { flex: 1 1 200px; }

flex-basis的值给出了项目在任何增长或收缩发生之前将具有的大小。 在上面的例子中,这个大小是 200 像素,所以我们会给每个项目 200 像素的空间。 我们的容器不太可能整齐地除以 200 像素,因此如果每个项目都有 200 像素,那么所有项目都会有剩余空间或没有足够的空间。 flex-growflex-shrink属性允许我们控制项目在空间过多或不足时会发生什么。

如果flex-grow设置为任何正值,则允许项目增长以占用空间。 因此,在我们上面的示例中,在给每个项目 200 像素之后,任何额外的空间都将在项目之间共享。

如果flex-shrink设置为正值,那么如果所有项目都被赋予了flex-basis ,则项目可以在发生溢出的情况下收缩。 如果在我们的示例中容器中没有足够的空间,则每个项目将缩小等量以减少,直到所有项目都可以放入容器中。

flex-growflex-shrink值可以是任何正值。 具有较大flex-grow值的项目将在增长时按比例分配更多可用空间,而具有较大flex-shrink值的项目将在收缩时移除更多空间。

请参阅 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout: flex properties。

请参阅 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout: flex properties。

了解这些 flex 属性的工作方式确实是了解 Flexbox 的关键,下面列出的资源将为您提供所有详细信息。 但是,当您有一堆东西要在一个维度中拉伸和挤压到容器中时,请考虑使用 Flexbox。 如果您发现自己试图按行和列排列,那么您需要一个 Grid,在这种情况下 Flexbox 可能不是这项工作的工具。

Flex 布局的资源和进一步阅读

  • “CSS 灵活框布局”,规范的完整指南,MDN 网络文档,Mozilla
  • “Flexbox 完整指南”,Chris Coyier,CSS-Tricks
  • 《Flexbox Froggy》,一款学习 Flexbox 的游戏
  • “Flexbugs”,一个社区策划的与 Flexbox 相关的浏览器错误列表

网格布局

CSS Grid Layout 被设计为一种二维布局方法。 二维意味着您希望将内容布置在行和列中。 与 Flexbox 一样,网格布局是display的值,因此要开始使用 Grid,您应该从容器上的display: grid开始,然后使用grid-template-columnsgrid-template-rows设置一些列和/或行grid-template-rows属性。

 .container { display: grid; grid-template-columns: 200px 200px 200px; grid-template-rows: 200px 200px; }

上面的 CSS 将创建一个固定大小的网格,具有完全固定的列和行轨道。 这可能不是您在网络上想要的,而 Grid 为您提供了很好的解决方案。 任何轨道的默认值都是auto ,通常可以认为是“足够大的内容”。 如果我们没有创建任何行轨道,那么将为我们创建行以获取添加的任何内容,并且这些行将auto调整大小。 一种常见的模式是指定列轨道,但允许 Grid 根据需要创建行。

虽然您可以使用任何长度单位或百分比设置列和行轨道,但您也可以使用新的fr单位,这是为网格布局创建的单位。 fr单元是一个弹性单元,表示网格容器中可用空间的份额。

网格可以为你分配空间; 您无需计算百分比即可确保物品适合容器。 在下面的示例中,我们使用fr单位创建列并允许自动创建轨道。 我们还使用grid-gap来分隔我们的轨道(有关间隙和网格布局的更多详细信息,请参见 Box Alignment 部分)。

请参阅 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout:一个简单的网格。

请参阅 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout:一个简单的网格。

与 Flexbox 和flex-growflex-shrink一样, fr单元处理共享可用空间。 一个轨道的较高fr值意味着它按比例获得更多可用空间。 您还可以混合fr单位和绝对长度。 在计算fr单位之前,将从可用空间中减去长度所需的空间。

请参阅 CodePen 上的 rachelandrew (@rachelandrew) 的 Pen Smashing Guide to Layout:fr 单位和绝对长度。

请参阅 CodePen 上的 rachelandrew (@rachelandrew) 的 Pen Smashing Guide to Layout:fr 单位和绝对长度。

网格术语

Grid 始终有两个轴:Inline Axis 沿文字在页面上的布局方向运行,而 Block Axis 沿块的布局方向运行。

Grid Container 是您设置display: grid on 的元素。 然后,您就有了网格线,由您在使用grid-template-columnsgrid-template-rows时指定的列和行轨道创建。 网格上的最小单位(在四条相交的线之间)称为网格单元,而构成完整矩形的网格单元的集合称为网格区域。

图像显示了突出显示列和行线的网格
网格线在网格的每个轨道之间运行。
图像显示了在网格上突出显示的列轨道
网格轨道位于任意两条线之间
图像显示了一个网格,其中包含多个单格区域和一个跨两行两列的区域。
网格单元是网格上的最小单位,一个网格区域是一个或多个单元共同构成一个矩形区域

网格自动放置

一旦你创建了一个网格,你的网格容器的直接子元素就开始布置自己,在网格的每个单元格中都有一个。 他们根据网格自动放置规则执行此操作。 这些规则确保每个项目都放置在一个空单元格中,避免项目重叠。

根据自动放置规则放置网格容器的任何您未指定位置的直接子项。 在下面的示例中,我已使每第三个项目跨越两行轨道,同时仍根据起始线自动放置。

请参阅 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout: auto-placement。

请参阅 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout: auto-placement。

基本的基于行的定位

在网格上定位项目的最简单方法是使用基于行的定位,给项目规则以告诉它从网格的一条线跨越到另一条线。 例如,如果我有一个包含三个列轨道和两行轨道的网格,我可以将一个项目从第 1 列到第 3 列,从第 1 行到第 3 行。然后它将总共覆盖四个网格单元,跨越两个列轨道和两个列行。

 .item { grid-column-start: 1; grid-column-end: 3; grid-row-start: 1; grid-row-end: 3; }

这些属性可以表示为速记、 grid-columngrid-row ,第一个值是start ,第二个是end

 .item { grid-column: 1 / 3; grid-row: 1 / 3; }

网格项目可以占据相同的单元格,从而可以创建具有重叠内容的设计。 项目以内容在网络上堆叠的通常方式堆叠,降低源的项目出现在其他项目的顶部。 不过,您可以使用z-index来控制它。

请参阅 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout:基于行的放置。

请参阅 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout:基于行的放置。

使用命名区域定位

您还可以使用命名区域在网格上定位项目。 要使用此方法,您需要为每个项目命名,然后将布局描述为grid-template-areas属性的值。

 .item1 { grid-area: a; } .item2 { grid-area: b; } .item3 { grid-area: c; } .container { display: grid; grid-template-columns: 1fr 1fr 1fr 1fr; grid-template-areas: "aabb" "aacc"; }

使用此方法时需要记住一些规则。 如果您希望一个项目跨越多个单元格,那么您应该重复该名称。 区域需要形成一个完整的矩形,不允许 L 形或俄罗斯方块! 网格必须是完整的——必须填充每个单元格。 如果您想留下空白,请用 . 填充该单元格. . 例如,在下面的 CSS 中,我将右下角留空。

 .container { display: grid; grid-template-columns: 1fr 1fr 1fr 1fr; grid-template-areas: "aabb" "aac ."; }

这是一种很好的工作方式,因为任何查看 CSS 的人都可以准确地看到布局将如何工作。

请参阅 CodePen 上 rachelandrew (@rachelandrew) 的 Pen Smashing Guide to Layout: grid-template-areas。

请参阅 CodePen 上 rachelandrew (@rachelandrew) 的 Pen Smashing Guide to Layout: grid-template-areas。

网格布局的资源和进一步阅读

CSS 网格布局比这个快速概述分享的要多得多,下面的资源将帮助您学习规范。 组件和您的整个页面布局都可以是网格,如果您要创建二维布局,请选择网格布局 - 无论大小。

  • “CSS 网格布局”,面向开发人员的 Web 技术,MDN 网络文档,Mozilla
  • “示例网格”,学习 CSS 网格布局所需的一切,Rachel Andrew
  • “Grid Garden”,一款有趣的互动游戏,用于测试和提高您的 CSS 技能
  • “布局土地”,YouTube 的 Jen Simmons

我还在 Smashing Magazine 上写了许多文章,可以帮助您深入了解各种网格概念:

  • “CSS 网格布局的最佳实践”
  • “使用生成的内容和 CSS 网格布局为空单元格设置样式”
  • “使用 CSS 网格:支持没有网格的浏览器”
  • “CSS 网格陷阱和绊脚石”
  • “在 CSS 网格布局中命名事物”

视觉和文件顺序

在本文的开头,我建议您以从上到下的顺序阅读文档,因为这对可访问性和 CSS 布局的工作方式都有帮助。 从我们对 Flexbox 和 CSS Grid 的简短介绍中,您可以看到可以将事物从该顺序中大大改变。 这有可能导致问题。

浏览器将遵循文档源以对文档进行任何非可视化使用。 因此,屏幕阅读器将读出文档顺序,任何使用键盘导航的人都将按照文档在源中的顺序而不是显示顺序来浏览文档。 许多屏幕阅读器用户并非完全失明,因此可能在使用屏幕阅读器的同时能够看到他们在文档中的位置。 对于这两种情况,与源相比混乱的显示确实会导致非常混乱的情况。

当您从源中的顺序移动元素时要非常注意。 如果你发现自己在 CSS 中重新排列项目的顺序,你真的应该回去重新组织你的文档吗? 测试您是否仍然可以在文档周围使用标签,并且视觉顺序是否有意义。

视觉和文档顺序的资源和进一步阅读

  • “CSS 网格布局和可访问性”,面向开发人员的 Web 技术,MDN 网络文档,Mozilla
  • “HTML 源顺序与 CSS 显示顺序”,Adrian Roselli
  • “Flexbox 和键盘导航断开连接”,Code Things,Tink
  • “键盘焦点的响应顺序冲突,”阿拉斯泰尔坎贝尔

盒子生成

您在网页上放置的所有内容都会创建一个盒子,本文中的所有内容都描述了如何在设计中使用 CSS 来布局这些盒子,但是,在某些情况下,您可能根本不想创建一个盒子。 display属性有两个值用于处理不需要框的情况。

不生成框或内容( display: none

如果您希望不生成该元素和该元素的所有内容,包括任何子项,您可以使用display: none 。 该元素现在将不会显示,并且不会为它本来的位置保留空间。

 .item { display: none; }

不生成此元素,但生成任何子元素( display: contents

display 的更新值是display display: contents 。 将display: contents应用于元素,不会生成该元素的框,但将正常生成任何子元素。 如果您希望间接子元素成为弹性或网格布局的一部分,这会很有帮助。

在下面的示例中,第一个 flex 项包含两个嵌套的子项,但它设置为display: contents ,它的盒子没有被租用,子项显示为好像它们是直接子项并成为 flex 项。 从该元素中删除display: contents以查看布局如何更改。

请参阅 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout: display: contents。

请参阅 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout: display: contents。

盒子生成的资源和进一步阅读

  • “带display: contents ”,雷切尔·安德鲁
  • 如何display: contents; 作品,”Ire Aderinokun,
  • CSS display: contents ,”浏览器支持信息, caniuse

结盟

直到最近,对齐一直是网络上的一个棘手主题,正确对齐框内项目的方法非常有限。 盒子对齐模块正在改变这一点,目前您将在控制 Grid 和 Flex 容器中的对齐时使用该模块。 未来,其他布局方法也将实现这些对齐属性。 Box Alignment 规范中详述的对齐属性列表如下:

  • justify-content
  • align-content
  • place-content
  • justify-items
  • align-items
  • place-items
  • justify-self
  • align-self
  • place-self
  • row-gap
  • column-gap
  • gap

由于布局模型具有不同的功能,对齐的工作方式会根据使用的布局模型略有不同。 让我们看看对齐如何与一些简单的 Grid 和 Flex 布局一起工作。

align-itemsjustify-items属性将align-selfjustify-self属性设置为一个组。 这些属性在它们的网格区域内对齐项目。

请参阅 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout:align-items、justify-items、align-self、justify-self。

请参阅 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout:align-items、justify-items、align-self、justify-self。

align-contentjustify-content属性对齐网格轨道,其中网格容器中的空间比显示轨道所需的空间多。

请参阅 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout:align-content, justify-content。

请参阅 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout:align-content, justify-content。

在 Flexbox 中, align-itemsalign-self处理 Cross Axis 上的对齐,而justify-content处理主轴上的空间分布。

请参阅 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout: Flex justify-content, align-items, align-self。

请参阅 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout: Flex justify-content, align-items, align-self。

在横轴上,您可以使用align-content来包裹 flex 线和 flex 容器中的额外空间。

请参阅 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout: flex align-content。

请参阅 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout: flex align-content。

See the resources for some links that discuss Box Alignment in detail across layout methods. It really is worth spending some time understanding how alignment works, as it will make working with Flexbox, Grid and future layout methods far easier.

Row And Column Gaps

A multiple-column layout has the column-gap property, and the Grid Layout spec had — until recently — the properties grid-column-gap , grid-row-gap , and grid-gap . These have now been removed from the Grid specification and added to Box Alignment. At the same time, the grid- prefixed properties were renamed to column-gap , row-gap , and gap . Browsers will alias the prefixed properties to the new renamed ones so you do not need to worry if you are using the better supported old names in your code right now.

The renaming means that these properties can be also applied to other layout methods, the obvious candidate being Flexbox. While no browser supports gaps in Flexbox at the moment, in future we should be able to use column-gap and row-gap to create space between flex items.

Resources And Further Reading For Alignment

  • “CSS Box Alignment,” CSS: Cascading Style Sheets, MDN web docs, Mozilla
  • “Box Alignment in Flexbox,” CSS Flexible Box Layout, MDN web docs, Mozilla
  • “Box Alignment in CSS Grid Layout,” CSS Grid Layout, MDN web docs, Mozilla
  • “The New Layout Standard For The Web: CSS Grid, Flexbox And Box Alignment,” Rachel Andrew, Smashing Magazine
  • “Box Alignment Cheatsheet,” Rachel Andrew

多列布局

A multiple-column layout is a layout type that enables the creation of columns, such as you might find in a newspaper. A block is split into columns, and you read down a column in the block direction then return to the top of the next column. While reading content in this way is not always useful in a web context as people don't want to have to scroll up and down to read, it can be a helpful way to display small amounts of content or to collapse down sets of checkboxes or other small UI elements.

A multiple-column layout can also be used to display sets of cards or products which have differing heights.

Setting A Column Width

To set an optimal column width, and instruct the browser to display as many columns as possible at that width use the following CSS:

 .container { column-width: 300px; }

This will create as many as 300 pixel columns as possible, any leftover space is shared between the columns. Therefore, unless your space divides into 300 pixels with no remainder, it is likely that your columns will be slightly wider than 300 pixels.

Setting A Number Of Columns

Instead of setting the width, you could set a number of columns using column-count . In this case, the browser will share the space between the number of columns you have asked for.

 .container { column-count: 3; }

If you add both column-width and column-count , then the column-count property acts as a maximum. In the below code, columns will be added until there are three columns, at which point any extra space will be shared between those three columns even if there was enough space for an additional column.

 .container { column-width: 300px; column-count: 3; }

Gaps And Column Rules

You cannot add margins or padding to individual column boxes, to space out columns use the column-gap property. If you do not specify a column-gap , it will default to 1em to prevent columns bumping up against each other. This is a different behavior to the way column-gap is specified for other layout methods, where it defaults to 0. You can use any length unit for your gap, including 0 if you want no gap at all.

The column-rule property gives you the ability to add a rule between two columns. It is a shorthand for column-rule-width , column-rule-color , and column-rule-style , and acts in the same way as border . Note that a rule does not take up any space of its own. It lays on top of the gap so to increase or decrease space between the rule and the content you need to increase or decrease the column-gap .

See the Pen Smashing Guide to Layout: multicol by Rachel Andrew (@rachelandrew) on CodePen.

See the Pen Smashing Guide to Layout: multicol by Rachel Andrew (@rachelandrew) on CodePen.

Allowing Elements To Span Columns

You can span an element inside the multicol container across all of the columns using the column-span property on that element.

 h3 { column-span: all; }

When a column-span happens, the multicol container essentially stops above the spanning element, therefore, the content forms into columns above the element and then remaining content forms a new set of column boxes below the spanning element.

See the Pen Smashing Guide to Layout: multicol span by Rachel Andrew (@rachelandrew) on CodePen.

See the Pen Smashing Guide to Layout: multicol span by Rachel Andrew (@rachelandrew) on CodePen.

You can only use column-span: all or column-span: none ; it isn't possible to span some of the columns. At the time of writing, Firefox does not support the column-span property.

Resources And Further Reading For Multiple-Column Layout

  • “Using Multi-Column Layouts,” CSS Multi-column Layout, MDN web docs, Mozilla

碎片化

Multiple-Column Layout is an example of fragmentation . In this case, the content is broken into columns. It is, however, very similar to the way that content is broken into pages when printing. This process is dealt with by the Fragmentation specification, and this specification contains properties to help control the breaking of content.

For example, if you have laid out a set of cards using multicol and you want to make sure that a card never breaks in half, becoming split between two columns you can use the property break-inside with a value of avoid . Due to browser compatibility reasons, you will also want to use the legacy page-break-inside property as well.

 .card { page-break-inside: avoid; break-inside: avoid; }

If you want to avoid a break directly after a heading, you can use the break-after property.

 .container h2 { page-break-after: avoid; break-after: avoid; }

These properties can be used when preparing a print stylesheet and also in multicol. In the example below, I have three paragraphs in a multicol container that fragments into three columns. I have given break-inside: avoid to the p element meaning that the paragraphs end up one in each column (even if this makes the columns uneven).

See the Pen Smashing Guide to Layout: multicol fragmentation by Rachel Andrew (@rachelandrew) on CodePen.

请参阅 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout: multicol fragmentation。

碎片化的资源和进一步阅读

  • “2018 年打印样式表状态指南”,Smashing Magazine 的 Rachel Andrew
  • “分栏”,QuirksMode.org

选择布局类型:如何选择?

大多数网页将混合使用这些布局类型,并且每个规范都准确定义了它们之间的交互方式。 例如,您可能有一个网格布局,其中一些网格项目也是 Flex 容器。 其中一些弹性容器可能是定位项目的包含块或内部浮动图像。 编写规范时期望我们将根据最适合我们布局的内容混合布局模型。 在本指南中,我试图概述每种布局类型的基本行为方式,以帮助您了解可能是实现特定效果的最佳方式。

但是,不要害怕尝试不同的方式来创建您想要的设计。 您应该担心您的选择会导致任何实际问题的地方比您想象的要少。 从良好的文档结构开始,并注意不要将视觉显示与该订单断开连接。 其余大部分只是测试在目标浏览器中是否按预期工作的情况。