在CSS网格上创建剪贴簿布局

最近,在学前训练课中,我的儿子被指示要照顾一个泰迪熊一个星期,这表明有必要带一只泰迪熊去冒险,并将他的记忆添加到专辑中。 我真的很喜欢制作这张专辑,并促使我思考如何使用CSS Grid做这样的事情!





复合网


Andy Clarke 在浏览器状态会议上做了精彩的演讲“受CSS网格技术启发”,对于像我这样的设计根基的开发人员来说,这是一个真正的见识。 在他的演讲中,他谈到了印刷设计思想可以在网络上用于创建令人惊叹的布局的方式,以及CSS Grid如何不仅使这成为可能,而且比以往更简单。 这些原理之一是使用复合网格。

我们大多数人可能熟悉使用网格进行Web设计和开发。 我分配给我开发的几乎所有场地布局都被划分为标准的12列(有时是24列)的网格,各列的宽度相等。 到目前为止,一切都是可以预料的。

另一方面,通过将两个或多个网格相互叠加来创建复合网格。 例如,将5列网格叠加在4列网格上的比较会产生有节奏的图案,并为构建比常规网格更动态的布局开辟了可能性。


图2-我们从4列和5列网格开始


图3-网格相互重叠。 结果,我们得到了一个复合网格

从心理学和技术角度来看,这都是适用的-尽管可以使用复合网格,但我们可以创建最常见的布局。 安迪(Andy)写了一篇详细的文章,“ 启发性设计决策:紧要事项 ”,其中更多地讨论了复合网格。 也可以从浏览器状态会议上发表他的演讲

复合网格生成器


fr单元使在CSS Grid中实现复合网格非常容易。 我喜欢在网站设计中使用复合网格的想法,但是我认为计算它们(尤其是更复杂的网格)的过程可能会非常耗时。 我希望能够快速方便地创建复合网格,因此,受安迪报告的启发,我I起袖子,创建了一个小工具来创建和可视化它们。 输入两个网格的列数(每个网格最多10列),生成器将合并它们,并提供可以设置为grid-template-columns属性的最终值。 例如,一个四列网格加上一个五列网格显示4fr 1fr 3fr 2fr 2fr 3fr 1fr 4fr



该工具在Codepen提供 ,因此可以随时使用或适应您的需求。

为相册布局创建网格


复合网格非常适合我想使自己无法预测但又保持节奏感和平衡感的专辑布局。 在使用生成器进行少量实验之后,我选择了一个6/5的复合网格,在我看来,该网格提供了正确数量的列以供进一步操作。 这使我可以使用原始网格:

 .grid { display: grid; grid-template-columns: 5fr 1fr 4fr 2fr 3fr 3fr 2fr 4fr 1fr 5fr; gap: 1rem; } 

定义网格行


定义网格线更加困难,并且需要更多的反复试验。 网格中的每张照片都应相互重叠。 事实证明,在纸上大致绘制一个网格以了解需要多少行很有用。

为了保持垂直节奏感,我决定照片应该以某种方式重叠。 我将此覆盖大小指定给一个变量,以便可以在整个页面中使用它,并在必要时进行更新(图4)。


图4-垂直图像叠加

 .grid { --verticalPadding: 2rem; --overlap: 6rem; } 

每个图像还附带文字。 为此,上方和下方应有足够的空间,以使其与上一张照片不重叠。 这涉及在标题上方和下方添加网格线,这将充当“填充”。 现在,每个图像都应至少覆盖网格的四行-并且在顶部和底部重叠的图像应占据五行。


图5-执行“填充”角色的行,使您可以在文本块的末尾与下一个图像的开始之间保持最小间隔。

但是我们还没有完成网格的设计:我决定为图像设置一个固定的宽高比。 有些照片将是人像,而另一些将是风景。 我希望网格布局能够正常工作,而不管照片的长宽比或文本的长度如何,因此要求网格线必须能够适应。

我们可以使用minmax()函数使这些轨道更灵活,而不是对用作覆盖或填充的字符串使用固定值。 这将提供以下情况:线迹将具有最小大小,但是如果需要,线迹会扩大。

 minmax(var(--padding, auto)); 

元素放置


现在我们有了网格的骨架,是时候处理元素的放置了。 有时很难理解和选择将它们放置在任何结构的网格中的最佳方法。 我们有许多不同的选择:行号,span关键字,命名的行或区域-在某些情况下,其中一些效果更好。 但是,没有正确或错误的选择,而且往往归结为寻找最适合您的方法。

只要一切都能正常进行,就不会有错误的方法

使用网格线放置


我通常从使用开始和结束值放置元素开始-通常是第一行和最后一行的数字,但是如果我知道元素应覆盖的确切轨道数,我将使用span关键字。 有时,我为网格线命名以添加重要的地标(例如wrapper-startwrapper-end ),但是我很少为网格线命名或直接为网格中的每个元素创建网格区域。 一种对我有很大帮助的策略是在要将元素放置到网格末尾的情况下指定负网格线。 我在另一篇文章中写了这个。 我经常在列轴上使用负网格线,因为在大多数情况下(对于我使用的网格),列数是已知的并且是固定的。

通过grid-column属性定位的值为1 / -1的元素将覆盖网格的所有列,从第一列到最后一列:

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

我更倾向于在网格具有大量轨迹的情况下命名网格线。 在所考虑的情况下,我们只有10个列轨道,因此在我看来,按行号放置元素似乎更便于进一步操作。

使用正负网格线和“ span”值的混合,只需将元素沿列的轴放置即可。 在Firefox开发人员面板中打开网格检查器对此很有帮助,因为它使我们能够看到行号。

使用网格区域放置


如果我们看一下网格。 我们可以看到我们有很多行。


图7-开发人员面板中Firefox网格检查器的屏幕截图,显示了网格的列和行

尽管我开始在行轴上按行号放置元素,但很快变得难以控制。 这些元素应该重叠,在我看来,很难追踪一个元素应该结束而另一元素开始的轨迹。 另外,我不想使用负网格线,因为将来有可能我想补充布局。 如果最终向网格中添加了更多的显式行,则负行号将不再有效,可能会导致许多布局错误。

这是我决定在行轴上创建命名网格区域的时候。 网格区域以两种方式创建:

  1. 使用grid-template-areas属性,可让您有效地“绘制”网格布局为ascii图
  2. 使用命名的网格线,使用-start-end作为行名的后缀

grid-template-areas属性不允许我们定义重叠元素的区域,因此对于这种特殊布局并不能真正帮助我们。 但是,使用命名的网格区域无疑会使任务更加容易。

如果我们为行轴和列轴都命名线,则将得到一个网格区域(图8)。


图8-具有-start-end的行名后缀创建一个网格区域

然后,当我们使用grid-area属性放置元素时,可以引用该区域:

 .item { grid-area: image; } 

与使用grid-column和grid-row属性并列出行名称相比,这使我们的代码更加简洁和可读:

 .item { grid-row: image-start / image-end; grid-column: image-start / image-end; } 

但是在这种情况下,我们只需要在行轴上命名一个网格区域。 这是正常现象,因为我们可以使用grid-row属性引用它:

 .item { grid-row: image; } 

由于我们有很多行,所以在我看来,垂直编写grid-template-rows属性要容易得多,以便它反映页面的结构:

 grid-template-rows: /*      */ auto 3rem /*      */ minmax(var(--verticalPadding), auto) minmax(0, auto) minmax(var(--verticalPadding), auto) var(--overlap) minmax(var(--verticalPadding), auto) minmax(0, auto) minmax(var(--verticalPadding), auto) var(--overlap) minmax(var(--verticalPadding), auto) minmax(0, auto) minmax(var(--verticalPadding), auto); 

现在,将行名添加到正确的位置变得更加简单,因为我们可以可视化网格结构:

 grid-template-rows: [header-start] auto [fig1-start] 3rem [header-end] minmax(var(--verticalPadding), auto) [p1-start] minmax(0, auto) [p1-end] minmax(var(--verticalPadding), auto) [fig2-start] var(--overlap) [fig1-end] minmax(var(--verticalPadding), auto) [p2-start] minmax(0, auto) [p2-end] minmax(var(--verticalPadding), auto) [fig3-start] var(--overlap) [fig2-end] minmax(var(--verticalPadding), auto) [p3-start] minmax(0, auto) [p3-end] minmax(var(--verticalPadding), auto) [fig3-end]; 

剩下的只是在放置网格元素时引用行轴上区域的名称:

 .fig--1 { grid-column: span 5 / -1; grid-row: fig1; } .fig--2 { grid-column: 1 / span 7; grid-row: fig2; } .fig--3 { grid-column: span 5 / -2; grid-row: fig3; } 

最终结果(图10)可在Codepen查看


图10


尽管我没有做出任何额外的努力来使此布局响应,但它可以在比平板电脑小的屏幕上使用。 为小屏幕调整布局不是很难。 就个人而言,我会为这种情况选择一个更简单的网格,因为许多视觉功能仍然会丢失。 但是话又说回来,这没有对与错。

Source: https://habr.com/ru/post/zh-CN472496/


All Articles