随着响应式网页设计和移动优先方法的出现,自从任何新概念迫使我们改编我们在基层编写CSS的方式以来,已经过去了七年。好吧,我没有任何太过开创性的东西可以提供给你,但我确实有一个小小的惊喜。看哪:Generic First CSS。
我认为可以肯定地说,Ethan Marcotte的响应式网页设计对于世界各地的网络开发者来说是一个受欢迎的启示。它引发了全新的设计思维浪潮和精彩的新前端技术。经常被鄙视的m点网站的统治也结束了。在同一个时代,Luke Wroblewski的Mobile First方法几乎同样具有影响力- 这是一项基于Marcotte令人印象深刻的基础的坚实改进。
这些技术是大多数Web开发人员生活的基石,他们为我们提供了很好的服务,但是,时间变化,开发人员不断迭代。随着我们提高方法的效率和项目要求变得更加复杂,出现了新的挫折感。
通用第一的旅程
我无法确切地指出是什么让我改变了我编写CSS的方式,因为这对我来说真的是一种自然的进展,几乎是在潜意识里发生的。回想起来,我认为它更像是我工作的开发环境的副产品。我工作的团队有一个很好的SCSS工作流程,还有一个漂亮的小混合,可以在CSS声明中轻松添加断点。你可能使用类似的技术。
这个精彩的小SCSS mixin突然变得很容易编写超级粒度的媒体查询。拿一个假设的传记块看起来像这样:
.bio {
display: block;
width: 100%;
background-color: #ece9e9;
padding: 20px;
margin: 20px 0;
@include media('>=small') {
max-width: 400px;
background-color: white;
margin: 20px auto;
}
@include media('>=medium') {
max-width: 600px;
padding: 30px;
margin: 30px auto;
}
@include media('>=large') {
max-width: 800px;
padding: 40px;
margin: 40px auto;
}
@include media('>=huge') {
max-width: 1000px;
padding: 50px;
margin: 50px auto;
}
}
图。1。 典型的移动设备首先使用级联媒体查询
这很好用 – 我过去写过很多像这样的CSS。然而,有一天我突然意识到,随着设备宽度增加而覆盖CSS声明只是没有意义。为什么声明一个CSS属性只能在下面的声明中被覆盖?
这就是我开始编写分区媒体查询的原因,而不是像图1中的示例那样向上(或向下)级联的媒体查询的更常见方法。
我开始创建有针对性的媒体查询,将样式封装在所需的屏幕宽度,而不是编写随着屏幕尺寸的增加而向上级联的媒体查询。该媒体查询混入将真正走进了自己的位置。现在我的SCSS媒体查询开始如下所示:
.bio {
display: block;
width: 100%;
padding: 20px;
margin: 20px 0;
@include media('>=small', '<medium') { max-width: 400px; margin: 20px auto; } @include media('>=medium', '<large') { max-width: 600px; padding: 30px; margin: 30px auto; } @include media('>=large', '<huge') { max-width: 800px; padding: 40px; margin: 40px auto; } @include media('>=huge') {
max-width: 1000px;
padding: 50px;
margin: 50px auto;
}
}
图2。 分区媒体查询的示例
这种新方法对我来说更直观,它减少了必须从前一个断点重置样式,并且它使CSS更容易阅读。更重要的是,它使媒体查询以更重要的方式自我记录。
我仍然对上述情况不是100%满意,但似乎仍有一个重大问题需要克服。
移动优先的问题
首先是移动设备的问题是,根据定义,您很可能必须在后续媒体查询中覆盖移动优先样式。这感觉就像一个反模式。
所以 – 对我来说 – 答案是显而易见的:让我们将媒体查询分区的概念理解为其逻辑结论 – 我们还将移动特定样式划分为他们自己的媒体查询。我知道,我知道,这违背了我们多年来所学到的共同惯例。“移动优先”无处不在,通常是招聘经理会提出的“技能”问题之一。所以任何选择肯定都是错的,不应该吗?这通常是人们首先一次又一次地说出手机时摇头的部分。
好的,所以我们将突破移动的第一个教条,并将我们所有的风格划分为相关的媒体查询。我们现在剩下的是在CSS选择器上声明的纯通用样式,其中所有其他设备特定样式封装在仅适用于相关屏幕尺寸的媒体查询中。我们现在有Generic First CSS:
.bio {
display: block;
width: 100%;
@include media('>=0', '<small') { padding: 20px; margin: 20px 0; } @include media('>=small', '<medium') { max-width: 400px; margin: 20px auto; } @include media('>=medium', '<large') { max-width: 600px; padding: 30px; margin: 30px auto; } @include media('>=large', '<huge') { max-width: 800px; padding: 40px; margin: 40px auto; } @include media('>=huge') {
max-width: 1000px;
padding: 50px;
margin: 50px auto;
}
}
如图3所示。 Generic First CSS的一个例子
是的,有更多的媒体查询,但是,我认为这是一个好处,任何开发人员现在都可以查看这个CSS并确切地看到在每个屏幕尺寸上应用了哪些样式而没有必须分开媒体的认知开销 – 查询特异性。
这对于不熟悉代码库甚至未来的人来说都很棒!
什么时候不分区
有时媒体查询分区是一种负担,在某些情况下,良好的旧> =媒体查询是好的。请记住,我们所要做的就是避免财产覆盖。
开发工具幸福
编写分区Generic First CSS的一个主要意外后果是您将从开发人员工具样式面板获得的经验。如果没有媒体查询级联,您现在可以更清楚地了解应用了哪些样式 – 您将不会有一个样式面板,其中包含来自覆盖的媒体查询规则的突出声明 – 噪音消失了!对我而言,这是Generic First CSS技术的最大好处之一。它为CSS调试体验带来了一些额外的理智,这在黄金方面是值得的。晚点再谢我。
图4。通用的第一个,分隔的CSS如何帮助您的开发控制台带来快乐和理智。
性能影响
所以这些Generic First CSS的好处开始听起来不错,但我认为还有一个我认为需要解决的关键问题。它是关于性能优化的主题。现在我还不确定,但我有一个暗示,完全分隔的媒体查询可能会带来轻微的性能优势。
浏览器执行称为计算样式计算的渲染任务。这是浏览器计算在任何给定时刻需要将哪些样式应用于元素的方式。此任务始终在初始页面加载时执行,但如果页面内容更改或发生其他浏览器操作,也可以执行此任务。您可以为流程的速度提供任何提升,这对于初始页面加载非常有用,并且可能会对网站页面的生命周期产生复合影响。
所以回到通用的第一个CSS:是否有任何与浏览器有关的性能问题必须解决大量级联媒体查询的CSS特性?
为了回答这个问题,我设计了一个测试用例,可用于衡量任何速度优势或缺点。
测试用例
测试用例由一个基本的HTML页面组成,输出一个“生物”块5000次,每个块的标记相同,但是类略有不同(数字微分器),这个块的CSS也输出5000次,类名是唯一不同的东西。输出的CSS通过一个名为CSS MQPacker的工具传输,这有助于通过将特定媒体查询的所有单独实例合并为一个来大大减少使用大量内联媒体查询的CSS的文件大小 – 这是一个很好的工具,可能会受益最现代的CSS代码库 – 我通过测试项目package.json中的npm任务将它用作独立的cli工具,你也可以将它用作postcss插件,这很方便!
第一个测试用例是移动优先级联媒体查询示例,第二个测试用例是CSS的通用第一个分区变体。这些案例的CSS有点冗长,可能用更简洁的术语编写,但它实际上只是用来测试论证的一个粗略的例子。
对于桌面版Google Chrome v70中的每个CSS变体,测试运行了20次,而不是大量数据,但足以让我大致了解性能增益/损失。
我选择使用的测试指标是:
- 总页面加载时间
使用<head>开头和<body>结尾处的Performance API标记检查页面加载时间的基本指标 - 从开发工具性能窗格中重新计算样式时间。
- dev工具性能窗格中的整体页面渲染时间。
被测量的关键指标是“重新计算风格”。
结果表(所有时间以毫秒为单位)
图6。 20个测试运行测量移动优先和通用第一CSS的关键负载/渲染指标。
从我公认的小数据集来看,我的初步怀疑似乎是正确的。平均而言,我看到样式重新计算任务花费的时间减少了42毫秒,速度增加了7.6%,因此整体渲染时间也减少了。差异不是令人兴奋,但它是一种改进。我不认为数据集足够大,不能100%确定,测试用例有点不切实际,但我很高兴不会看到性能下降。
我非常有兴趣看到应用于现实世界现有代码库的通用第一种方法,该代码库是以移动优先的方式编写的 – 之前的指标对于日常实践来说更加真实。
如果有人就如何在更广泛的迭代中自动化测试提出建议,请在评论中告诉我们!我想必须有一个可以做到这一点的工具。
结论
回顾一下这种新的开发方法的好处……
- 完全符合预期的CSS,没有第二次猜测;
- 自我记录媒体查询;
- 更好的开发工具体验;
- 页面渲染速度更快。
我想我不是唯一一个支持以这种方式编写CSS的人。如果你已经采用了通用的第一种思维方式,那就赶快行动吧!但如果没有,我想你会非常喜欢它带来的好处。我个人从整洁的开发工具体验中获益匪浅,这本身对很多开发者来说都是一个巨大的积极因素。这种编写媒体查询方式的自我记录性质也会给自己和更广泛的团队带来好处(如果有的话)。最后,这些好处不会在性能方面花费你任何成本,事实上已经证明了它们的边际速度提升!