代码作为文档:CSS网格的新策略
Supercool,一家快速发展的网页设计公司,为艺术客户创建定制网站,并使用现成的Craft CMS系统;它具有高规格的图形设计,以及相对苛刻的排版和艺术指导。在过去的几个月里,我们一直在转向CSS Grid。我们正在缓慢过渡,允许自己发现新的范例和设计方法,而不是简单地将旧习惯移植到新的语法中。
到目前为止,我们已经开发出了一些非常有用的策略来跟踪布局。我已经编写了一些非常巧妙的mixin,使用了命名区域和模板,并且我们已经找到了一些基本约定来创建高度可读的代码。我认为,逐步讲解使用grid的单个主要组件的完整生产实现,深入探讨它提出的一些设计问题,并引导您避免我们遇到的陷阱,将非常有价值。CSS Grid是一个大型规范,有很多可能的方法和很多正确的方法,但在某个时刻,您必须确定您的方法并使其上线。
我期望您对CSS、Sass、BEM有一定的了解,并且对在紧迫的时间表(例如一周)内,使用Sketch或Photoshop类型的文档,原型化完全实现的、可访问的、自定义框架(包含50多个组件)的任务感兴趣。
首先,让我们识别并分离出设计中的不同编码任务,并规划我们将如何处理它们:
- 字体: 设计师已经定义了一个字体系统。
- 颜色: 首先,我们构建一个主题模型,然后将其包含在部分中。
- 内容: 此块中包含哪些元素?它的变体是什么?这就是我们的BEM mixin发挥作用的地方。
- 布局: 这就是内容在此块中的放置方式。您可能希望直接跳到此步骤。
- 约定: 这正是我们选择编写上述所有内容的方式。CSS中有很多正确答案,因此重要的是我们都同意一个约定,即规则。这确实应该排在第一位,但为了本文的缘故,我们将在最后总结。
字体系统
我们使用实用程序类(例如h-text--h1、h-text--badge)来设置字体样式。一个项目中可能有一百种字体样式。我们使用Typex将这些样式从Sketch直接导出到我们的Patternlab中。这本身就是另一篇文章的内容,所以让我们假设字体已经处理完毕。我们不会将字体引入我们的组件部分。
颜色使用
主题化只需添加几个微小的mixin,因此理想情况下,我们不会在部分中看到大量的颜色规则。我们将它们全部存储在“Mixin和模型”库中的_themer.scss
部分中,这样我们可以确保遵循网站的设计系统。这样,当有人稍后返回构建时,他们就有一个关键的参考部分来描述设计和品牌规则。当在大致相同的市场中构建和维护许多网站时——但每个网站都有不同的品牌规格——您必须确保不会将一个品牌与另一个品牌混淆!因此,与字体一样,我们将颜色规则从部分中抽象出来。从本质上讲,在我们的_header.scss
文件中,我们实际上只关注布局(尽可能多)。
鉴于我们同意始终使用我们的mixin进行主题化,这就是如何在元素上包含它的方式:
<code>@include var($property, $value);</code>
然后,我们将设置一个主题模型,说明颜色在此特定网站上的工作方式,并将其应用于组件:
<code>@include theme;</code>
这是我们将与此页面标题一起使用的示例主题模型。它非常简单。
我们将颜色与黑色或白色配对。我们依赖于对比度规则,并为强调它们进行翻转,可能是在事件(如悬停)或突出显示的号召性用语上。这就是我们实现这一目标所需做的全部工作,现在我们有了关于颜色在此网站上实际工作方式的文档。如果我们需要调试或扩展UI,我们可以访问并检查它。
我们还希望准备继承以帮助我们,因此让我们确定一些有用的约定:
- 在您的管道中将SVG图标的填充设置为currentColor(顺便说一句,在CSS中默认大小为
width: 1em; height: 1em; font-size: inherit;
)。 - 在基础处设置
<a></a>
为currentColor。 - 编写简写,继承边框(例如
1px solid
或1px solid currentColor
)。
使用此主题模型,我们可以生成任意数量的主题,也许将它们存储为实用程序类,或者在组件内循环遍历修饰符列表,或者只允许用户直接在CMS中的块上设置变量。当IE 11在我们统计数据中的占比低于1%时,我们可以使用变量做更多的事情,但这对于我们目前的用途来说已经足够了。
让我们不要偏离主题。Grid怎么样?!
内容组件
Grid让我们能够以一种新的方式精确地描述每个部分中我们拥有的内容。对于为每个项目构建新UI的设计机构来说,这确实是一个改变游戏规则的东西,并且在我们探索的过程中,我们正在发现它的新(且有趣)的应用。
为了提供上下文:我们使用Craft CMS为我们的客户定制每个界面,并创建自定义字段以满足他们的特定需求和他们的内容模型。我们拥有内部工具,可以从票务API中提取事件并从中创建条目,然后可以在CMS中编辑和扩展这些条目(或完全创建)。客户可以在永久页面区域中填写或编辑命名字段,并且还可以将整个设计好的、品牌的块添加到每个页面的布局中,因为他们正在构建它们。
有很多UI。客户对内容有很大的控制权,而我们对HTML有很大的控制权,因此我们可以确保页面上具有高质量的可访问的语义代码。我们在发现过程中共同开发内容模型,然后让他们自由创建内容。他们添加他们想要的内容,我们确保它有效并且始终看起来正确。比正确更好!超级。(对不起!:P)
因此,作为一名开发人员,我必须权衡相互竞争的优先事项:
- 可访问性、可用性
- 品牌和图形设计
- 性能
- 维护和代码库健康
让我们逐一查看它们:
可访问性
可访问的、逻辑的HTML是我的最爱。至少,我的项目需要在Lighthouse评分中获得绿色可访问性评分。(我在开玩笑,我想要那个美味的100!)核心路径和页面使用一些屏幕阅读器(键盘选项卡、键盘导航)、低视力模拟器、Dasher、语音访问和二进制开关进行测试。(我还为Robots and Cake工作,所以这是我开发工作的重要组成部分。)我一遍又一遍地将巨大的可点击电话号码和电子邮件地址添加到页面中。我只是想让人们到达他们想去的地方。
我一直担心内容可以通过grid(以及flexbox)重新排序的方式。现在我已经完成了几个构建,我实际上认为grid可以帮助我们解决这个问题。使用CSS Grid,没有理由为了布局而移动HTML。我们可以回到将整个文档视为逻辑的线性序列作为我们首要关注点。
品牌与性能与维护
艺术场所需要高规格的图形设计,在印刷品和网络上统一,并且需要不断更改的材料(例如节目、手册、门票、海报、微型网站等)来向他们的观众分发,包括必须满足的合同营销义务。正如您所能想象的,我们有很多高质量的大图像需要优先处理,并且通常带有强大的以印刷为主导的品牌。这意味着我们可能需要向页面提供大约十五种自定义字体(包括粗细变化、显示字体等)以及复杂的CSS。我们必须让自己尽可能精简。我们目前正在发送大约20 KB nano Gzipped的CSS,但我正在努力进一步减少它。
但是,我们确实通过在PostCSS任务中将reduce标识符设置为false来保持grid区域名称的完整长度。在DevTools中拥有可用的布局图比节省那些少量字节更有用。为了维护、自文档化以及您未来在Sowerby Bridge的一列延误的火车上没有repo访问权限的情况下调试此网站的未来的自己的缘故:保留地图。
代码健康
平衡所有这些相互竞争需求的方法是阐明并达成约定,以便在测试中需要修复的内容更少,并且已解决的问题保持解决。我们检查我们构建的所有组件,并确保它们始终以标题开头,链接指向位置,按钮触发操作,可计数的对象作为列表交付并在前面加上地标标题,导航是<nav></nav>
,时间是<time></time>
,div汤是早餐——基础知识。
使用CSS Grid,没有理由为了布局而移动 HTML。您的内容始终可以逻辑地流动,而布局更改则发生在CSS中。并且,由于不需要边距或填充来创建间距,您可以简单地声明:
<code>.o-grid .o-grid { width:100%; }</code>
……以确保任意数量的嵌套组在视觉上都占据相同的页面网格。HTML可以更清晰地指导事物真正是什么:更接近文档。
在标题和操作之间有很多内容需要管理,我的挑战是跟踪所有这些组件中的所有这些字段,同时确保我忠实地执行设计规范,使其可遍历、可扫描、可线性化并易于以某种逻辑的、可理解的方式读取。
让我们引入我的第一个、令人惊讶的有用的grid mixin。
<code>@mixin template($elements...) { @each $element in $elements { &__#{$element} { grid-area: $element; } } }</code>
在任何地方使用此mixin意味着:
- 每个组件部分现在都以其所有可能的元素列表开头,这是一个非常方便的文档,尤其是在Twigging实际前端组件时。
- mixin负责分配grid区域。
- 元素和组件名称在Sketch、CSS和HTML中保持一致,任何不一致之处都将非常明显,因为布局将失败。我态度坚定,但公平。
- BEM命名会自动强制执行,但不会在部分中弄乱事情。
现在,在部分中,我们将只声明grid-template-areas,使用普通的英语单词,为我们提供一系列布局地图,这些地图也与数据库字段匹配。超级易读!
以下是如何使用此mixin的示例:
我们决定坚持使用命名区域进行内部网格,因为我在这个网站上读到一篇很棒的文章,解释了如果您坚持使用列出的受支持属性,Autoprefixer 如何处理IE 11的grid——并且它在大多数情况下确实如此。如果您在浏览器测试中使用应用了Autoprefixer的超级有用的调试模式查看此测试用例,您将看到它正在工作。
但是有陷阱!您必须将内联元素设置为块以确保它们始终在IE 11中作为grid单元操作。注释掉示例中的标记行以查看否则会发生什么:
哎哟!小心那些块。您可能会发现某些版本的IE 11甚至不会拾取此修复程序,在这种情况下,您可能会尝试只使用普通的<div>标签……叹息。
<p>我没有在此mixin中包含<code>display: grid
,因为在某些情况下,实际的grid是在内部容器上设置的,例如,但我们仍然希望grid-areas与正确的BEM类匹配。
所以:
<code>.c-header{ @include template(title, pretitle, posttitle, producer, venue, credit, quote, nav, infobar, search); }</code>
让我们来布局这些东西。
布局
让我们确定一些额外的规则,以确保此组件可以轻松滑入页面布局。在撰写本文时,没有可用的子网格(但会有!),因此此组件不知道它所在的父网格。这恰好与BEM组件方法很好地匹配——因为每个组件都是扁平的、孤立的,以限制继承。我在这里不是提倡BEM(或者我们显然使用的BEM-ish)——我只是说,如果您已经在使用它,这是一个额外的好处。
在此示例中,设计师设置了一个页面布局,该布局具有12列网格和20px(1.25rem)间距,全站范围内,没有偏移部分。我们的组件是一个页面区域,将占据所有12个网格列。在这个过渡时期,我们仍在使用这种类型的设置网格,因为我们有很多仍然基于这个想法的系统需要与之集成。因此,这是此条件下的约定:对于全宽区域,删除网格间隙并将网格模板列写为12的分数单位(fr)。
这样做意味着:
- 此内部网格的视线大致遵循其所在的网格;
- 轻松查看代码中的底层设计规则;以及
- 如果需要,可以轻松地将事物精确地对齐。
关于“对齐”的快速说明
等等……我的意思是“精确对齐”是什么意思?它难道不是已经精确对齐了吗?
嗯,不是。分数单位方法完美地划分空间,因此您最终会进入间距。两列均匀的列会让您位于间距的中间。其中一列为2/3而另一列为1/3的两列将在该间距的1/3处分割,依此类推。
修复对齐并不难,因为我们知道页面网格间距的宽度。例如,在均匀分割上,我们可以包含网格间隙。
但是,我们不能对任何其他分割这样做。我们可以做的是将该间隙添加为边距——无论您设置了什么盒大小,边距都会在内部添加。在此示例中,我们有三列(两个命名区域和一个空空间),将我们的间距分成三份:
这就是计算这些边距的方法:确保fr单位的总和结果为12。将网格间隙除以父网格中的列数,然后像这样相乘:
n的右边距乘数等于n右侧fr单位的总和。n的左边距等于n左侧fr单位的总和。
因此,对于grid-template-columns
值为2fr 3fr 2fr 4fr 1fr
:
<code> 2 3 2 4 1 0/10 2/7 5/5 7/1 11/0</code>
如果您发现自己经常编写calc()
,您甚至可以将其编写为mixin。例如,以下是如何将内部网格与父网格对齐:
……以及以下是如何在名称在内部指定但数字在网格外指定时自动计算边距:
我相信您可以想到其他解决方案,例如切换到命名行,或添加额外的固定宽度列,甚至使用12个命名区域每行编写所有地图。有很多方法可以处理这个问题,但我认为很多方法都消除了命名区域的优势。区域为我们提供了一个可读的布局图,其中包含我们未来的自己需要知道的内容。它是代码作为文档。
需要明确的是,我正在引导我们解决的设计问题不是对齐问题。使用grid,对齐很容易。问题不在于解决直接的、微不足道的布局问题,而在于以一种支持我们目标的方式解决它,即能够在六个月后理解:
- 组件中包含哪些元素。
- 它们的布局方式。
- 为什么代码以这种方式编写。
grid规范非常庞大,很容易迷失在选项中。也许更好的计划是重置为12列网格,并在需要绝对对齐时使用数字规范(即明确链接到我们的页面网格,该网格使用数字规范)——但我确实觉得有一个更智能、更简单的解决方案有待发现。对于此网站,我们最终编写了一个页面网格对象,并使用类向其添加了嵌套的内部网格单元:.o-page-grid\_\_sidebar
。
你们怎么看?我肯定预见到对此会有不同的看法。?♀️
真实的grid!
我们可以使用它来创建一个通用的页面标题:
或者,我们可以创建一个主页的变体:
那么,一个超出我们容器的英雄标题呢?当然!或者我们也可以在容器外提供它:
接下来是什么?一个带有全宽信息栏(粘贴)和一个与父网格上的侧边栏对齐的内部按钮的主题化事件标题?没错。我将包含一个父网格,以便更容易查看:
那么带有居中对齐的搜索呢?让我们使用折叠列技术:
以下是所有这些变体作为单个部分的演示。是的,它是一张地图!它是一个包装!
约定
哇,我们涵盖了很多内容!但是您可以看到像这样的系统有多灵活和自文档化,对吧?
- 字体由单独的字体系统处理。
- 颜色由一个主题部分处理,该部分描述设计的底层颜色规则,而不是简单地临时着色元素。
- 元素被称为它们是什么,用英语,并在部分顶部使用模板mixin作为列表包含。此列表可以作为参考包含在Twig或模板中。
- 始终使用正确的HTML,并且嵌套不会破坏grid。这意味着您可以通过设置约定将任意数量的嵌套grid应用于相同的布局空间。
- 精确的对齐是在数字规范中完成的,而不是名称规范(但请注意,可以使用名称规范进行对齐)。
- 支持IE 11。
我还有一张快速说明和另一个使用命名区域构建的组件示例。在此示例中,卡片不是区域,而是放置在网格中的组件,因此没有理由使用12的fr约定。您可以预期媒体对象部分如下所示:
<code>.c-card { &--news { align-content: start; grid-template-areas: "image" "datetime" "title"; } &--search { justify-content: start; grid-template-columns: 1fr 3fr; grid-template-areas: "image page" "image title" "image summary"; } &--merchandise { grid-gap: 0; grid-template-columns: $b 1fr 1fr $b; grid-template-areas: "image image image image" ". title title ." ". summary summary ." ". price action ."; } &--donations { // donations thanks button is too long and must take up more space than input grid-gap: 0; grid-template-columns: $b 1fr 2fr $b; grid-template-areas: "image image image image" ". title title ." ". summary summary ." ". input action ."; } } // ...</code>
以上是代码作为文档:CSS网格的新策略的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

关于Flex布局中紫色斜线区域的疑问在使用Flex布局时,你可能会遇到一些令人困惑的现象,比如在开发者工具(d...
