一行 CSS 中的十种现代布局

这篇博文重点介绍了几行功能强大的 CSS,可完成一些繁琐的工作,帮助您构建强大的现代布局。

借助现代 CSS 布局,开发者只需敲击几个按键,就可以编写出真正有意义且稳健的样式规则。上面的讨论和后续的博文探讨了 10 行强大的 CSS 代码,这些代码可以完成一些繁重的工作。

若要了解或自行体验这些演示,请查看上方的 Glitch 嵌入代码,或访问 1linelayouts.glitch.me

01. 超级居中:place-items: center

对于第一种“单行”布局,我们来解决 CSS 中最大的一个难题:居中放置。希望您知道,使用 place-items: center 比您想象的要简单。

首先将 grid 指定为 display 方法,然后在同一元素上写入 place-items: centerplace-items 是同时设置 align-itemsjustify-items 的简写形式。将其设置为 center 后,align-itemsjustify-items 均会设为 center

.parent {
  display: grid;
  place-items: center;
}

这样,无论固有大小,内容都能完全在父项内居中。

02. 解构的煎饼:flex: <grow> <shrink> <baseWidth>

接下来我们有了解构的煎饼!这是营销网站的常见布局,例如,网站可能有一行包含 3 件商品,通常包含图片、商品名和一些文字,用于描述产品的某些功能。在移动设备上,我们希望这些标签能很好地叠放,并随着屏幕尺寸的增加而扩展。

通过使用 Flexbox 实现该效果,在屏幕大小调整时,您无需媒体查询来调整这些元素的位置。

flex 的简写形式表示 flex: <flex-grow> <flex-shrink> <flex-basis>

因此,如果您希望框填充到其 <flex-basis> 大小,请缩小较小的尺寸,但不要拉伸以填充任何额外的空间,请写入:flex: 0 1 <flex-basis>。在本例中,您的 <flex-basis>150px,如下所示:

.parent {
  display: flex;
}

.child {
  flex: 0 1 150px;
}

如果您希望框在自动换行到下一行时拉伸并填充空间,请将 <flex-grow> 设置为 1,如下所示:

.parent {
  display: flex;
}

.child {
  flex: 1 1 150px;
}

现在,当您增大或减小屏幕尺寸时,这些具有弹性的项也会缩小和增大。

03. 边栏显示:grid-template-columns: minmax(<min>, <max>) …)

此演示将 minmax 函数用于网格布局。这里我们要做的是将最小边栏大小设置为 150px,但在较大的屏幕上,使其延伸到 25%。边栏将始终占据其父项的 25% 水平空间,直到该 25% 小于 150px 为止。

将其添加为 grid-template-columns 的值,并使用以下值:minmax(150px, 25%) 1fr。第一列(本例中为边栏)中的项在 25% 处的 minmax150px,第二项(此处的 main 部分)以单个 1fr 轨道的形式占据其余空间。

.parent {
  display: grid;
  grid-template-columns: minmax(150px, 25%) 1fr;
}

04. 煎饼堆栈:grid-template-rows: auto 1fr auto

与解构的 Pancake 不同,此示例不会在屏幕尺寸发生变化时封装其子项。此布局通常称为粘性页脚,通常用于网站和应用、移动应用(页脚通常是工具栏)和网站(单页应用通常使用此全局布局)。

向组件添加 display: grid 后,您将得到一个单列网格,但主要区域将仅与其下面有页脚的内容一样高。

如要将页脚固定在底部,请添加:

.parent {
  display: grid;
  grid-template-rows: auto 1fr auto;
}

这会将页眉和页脚内容设置为自动采用其子项的大小,并将剩余空间 (1fr) 应用于主要区域,而大小为 auto 的行将采用其子项的最小内容大小,这样,随着内容的大小变大,该行本身就会变大以进行调整。

05. 经典圣杯布局:grid-template: auto 1fr auto / auto 1fr auto

对于这种经典的圣杯布局,有页眉、页脚、左侧边栏、右侧边栏和主要内容。它与之前的布局类似,但现在增加了边栏!

如需使用一行代码编写整个网格,请使用 grid-template 属性。这样,您就可以同时设置行和列。

“属性与值”对为:grid-template: auto 1fr auto / auto 1fr auto。第一个和第二个以空格分隔的列表之间的斜杠是行和列之间的换行符。

.parent {
  display: grid;
  grid-template: auto 1fr auto / auto 1fr auto;
}

在上一个示例中,页眉和页脚的内容会自动调整大小,此时左侧和右侧边栏会根据其子项的固有大小自动调整大小。不过,这一次,采用的是水平尺寸(宽度),而不是垂直尺寸(高度)。

06. 12 跨距网格:grid-template-columns: repeat(12, 1fr)

接下来,我们来看另一个经典示例:12 跨距网格。您可以使用 repeat() 函数在 CSS 中快速编写网格。对网格模板列使用 repeat(12, 1fr); 可为每个 1fr 提供 12 列。

.parent {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
}

.child-span-12 {
  grid-column: 1 / 13;
}

现在,您已经有一个 12 列的轨道网格,我们可以将子项放置在网格上。一种方法是使用网格线放置它们。例如,grid-column: 1 / 13 跨越第一行到最后一行(第 13 行),跨 12 列。grid-column: 1 / 5; 将跨越前四个。

另一种编写方法是使用 span 关键字。借助 span,您可以设置起点,然后设置从该起点跨越多少列。在本例中,grid-column: 1 / span 12 相当于 grid-column: 1 / 13grid-column: 2 / span 6 相当于 grid-column: 2 / 8

.child-span-12 {
  grid-column: 1 / span 12;
}

07. RAM(重复、自动、MinMax):grid-template-columns(auto-fit, minmax(<base>, 1fr))

对于第 7 个示例,请结合您已经学到的一些概念,使用自动放置的灵活子项创建自适应布局。这挺好看的。这里要记住的关键术语是 repeatauto-(fit|fill)minmax()',您记住它们的首字母缩写词为 RAM。

总的来说,如下所示:

.parent {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}

您再次使用了重复,但这次使用的是 auto-fit 关键字,而不是显式数值。这样就可以自动放置这些子元素。这些子项的基本最小值为 150px,最大值为 1fr,这意味着在较小的屏幕上,它们会占据完整的 1fr 宽度,当每个子项的宽度达到 150px 时,它们将开始流向同一行。

使用 auto-fit 时,框会在水平大小超过 150 像素时拉伸以填充整个剩余空间。不过,如果您将此值更改为 auto-fill,那么当其在 minmax 函数中的基数超出时,它们不会进行拉伸:

.parent {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
}

08. 频道组:justify-content: space-between

对于下一个布局,这里要演示的重点是 justify-content: space-between,它会将第一个和最后一个子元素置于其边界框的边缘,剩余空间均匀分布在元素之间。对于这类卡片,它们会置于 Flexbox 显示模式下,并使用 flex-direction: column 将方向设置为列。

这会将标题、说明和图片块放置在父卡片内的一个垂直列中。然后,应用 justify-content: space-between 会将第一个(标题)和最后一个(图片块)元素锚定到 Flexbox 的边缘,在这些元素之间的描述性文本将按等间距放置到每个端点。

.parent {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

09. 固定我的样式:clamp(<min>, <actual>, <max>)

下面我们将探讨一些技术支持较少的浏览器,但其对布局和响应式界面设计也有一些非常令人兴奋的影响。在本演示中,您将使用 clamp 设置宽度,如下所示:width: clamp(<min>, <actual>, <max>)

这会设置一个绝对的最小和最大尺寸以及一个实际尺寸。添加值后,结果可能如下所示:

.parent {
  width: clamp(23ch, 60%, 46ch);
}

此处的大小下限为 23ch 或 23 个字符,上限为 46ch,上限为 46 个字符。字符宽度单位基于元素的字体大小(特别是 0 字形的宽度)。“实际”尺寸为 50%,表示此元素父级宽度的 50%。

clamp() 函数在此处执行的操作是,让此元素保持 50% 的宽度,直到 50% 大于 46ch(在较宽的视口上)或小于 23ch(在较小的视口上)。您可以看到,当我拉伸和缩小父级尺寸时,此卡片的宽度会增大至其固定值的最大点,并减小到限制值的最小值。由于我们对其应用了其他属性,使其居中,因此它始终位于父元素中。这样布局将更加清晰易读,因为文字既不会太宽(超过 46ch),也不会太挤压和窄(小于 23ch)。

这也是实现响应式排版的好方法。例如,您可以编写:font-size: clamp(1.5rem, 20vw, 3rem)。在这种情况下,标题的字体大小将始终介于 1.5rem3rem 之间,但会根据 20vw 实际值进行缩放,以适应视口的宽度。

这种方法有助于确保使用最小和最大尺寸值都清晰可辨,但请注意,并非所有现代浏览器都支持此功能,因此请确保您有后备版本并进行测试。

10. 尊重切面:aspect-ratio: <width> / <height>

最后,最后的这个布局工具是众多工具中最具实验性的工具。它最近在 Chromium 84 中被引入到 Chrome Canary 版中,Firefox 也在努力实现此功能,但目前它尚未在任何稳定的浏览器版本中提供。

不过,我确实要提到这一点,因为这是一个经常会遇到的问题。这只是保持图片的宽高比即可。

使用 aspect-ratio 属性时,当我调整卡片大小时,绿色视觉块会保持 16 x 9 的宽高比。使用 aspect-ratio: 16 / 9 遵循宽高比要求。

.video {
  aspect-ratio: 16 / 9;
}

要在不添加此属性的情况下保持 16 x 9 的宽高比,您需要使用 padding-top 技巧并为其设置 56.25% 的内边距,以设置上宽比。为避免黑客入侵和计算百分比,我们很快就会提供相应的属性。您可以制作宽高比为 1 / 1 的方形、宽高比为 2 / 1 的 2:1 的方形,实际上就是让此图片按照设定的尺寸比例进行缩放所需的任何内容。

.square {
  aspect-ratio: 1 / 1;
}

虽然这一功能尚处于开发阶段,但它是一个很好的了解,因为它解决了我自己多次遇到的许多开发者冲突,尤其是在视频和 iframe 方面。

总结

感谢您通过 10 行功能强大的 CSS 跟随这个历程。要了解详情,请观看完整视频,并自行尝试演示