CSS Intelligence: Speculating On The Future Of A Smarter Language
CSS已从纯表现层语言演变为具备逻辑能力的语言——这得益于容器查询、关系型伪类和if()函数等特性。它是否仍仅用于样式设计,还是正在变得更强大?Gabriel Shoyombo探讨了CSS这些年的智能化发展、未来方向、解决的挑战、是否变得过于复杂,以及开发者如何应对这一转变。
历史背景:CSS的刻意简化
回顾CSS历史,这个语言诞生之初是为了分离内容与表现,使网页更易管理和维护。1996年发布的CSS1引入了字体属性、颜色、盒模型(内边距、外边距和边框)、尺寸(宽度和高度)、简单显示属性(none、block、inline)和基础选择器。
两年后,CSS2推出,通过定位、z-index、增强选择器、表格布局和媒体类型等功能扩展了样式能力。但存在不一致性问题,直到2011年CSS2.1成为现代CSS标准,简化了网页创作和站点维护。
在CSS1到CSS2.1期间,CSS基本上是静态和声明式的。开发者依赖表格布局、定位或浮动等替代方案实现复杂设计,导致容器坍塌和意外换行等问题。尽管如此,基础样式直观易学,新手可快速上手。CSS与内容和逻辑分离,因此性能高效且轻量。
CSS3:迈向上下文感知的第一步
CSS3发布后情况改变。开发者期待像之前版本那样的单一整体更新,但现实是模块化系统,包含Flexbox、CSS Grid和媒体查询等强大布局工具,首次定义了响应式设计。超过20个模块的CSS3标志着“智能CSS”的开端。
2012年左右引入的Flexbox提供了灵活的一维布局系统,而2017年推出的CSS Grid通过二维布局框架进一步推进布局能力,使复杂设计可用最少代码实现。如Chris Coyier所述,这些进步减少了对浮动等技巧的依赖。
媒体查询是CSS3的重要发布,极大贡献了CSS智能化。通过媒体查询,CSS可响应不同设备屏幕,调整样式以适应屏幕尺寸、宽高比和方向,这是早期版本难以实现的。第五级增加了用户偏好媒体特性,如prefers-color-scheme和prefers-reduced-motion,通过适应用户设置增强可访问性。
CSS3标志着上下文感知CSS的开始。
驱动智能化的新CSS特性
多个特性正推动CSS向动态和自适应边缘发展,使其更智能,其中容器样式查询和if()函数值得关注。
什么是容器样式查询?为什么重要?
要理解容器样式查询,需先了解其近亲:CSS Containment Module Level 3引入的容器大小查询。
容器大小查询允许开发者基于父容器尺寸样式化元素。这对基于组件的设计是巨大胜利,消除了将响应式样式硬塞到全局媒体查询中的需要。
|
|
容器样式查询更进一步,允许基于容器上设置的自定义属性(即CSS变量)样式化元素。
|
|
这些特性在CSS中很重要,因为它们解锁了上下文感知组件。按钮可根据父级设置的–theme属性改变外观,无需JavaScript或硬编码类。
if()函数:未来一瞥
CSS if()函数可能是最激进的转变。当实现时(截至版本137,仅Chrome支持),它将允许开发者在属性声明中直接编写内联条件逻辑。想象CSS中的三元运算符。
|
|
这行假设代码或伪代码(非语法)设置文本颜色为白色(如果–theme变量等于dark)或黑色(否则)。目前if()函数尚未在任何浏览器支持,但CSS工作组已关注,且有影响力的开发者如Lea Verou已在探索其可能性。
新CSS:CSS和JavaScript的边界是否模糊?
传统上,样式关注点分离如下:CSS负责外观,JavaScript负责行为。但容器样式查询和if()函数等特性开始模糊这条线。CSS开始具备行为能力,不是指API调用或事件监听器,而是基于逻辑或上下文条件应用样式的能力。
随着Web开发演进,CSS开始 encroach on JavaScript领域。CSS3引入了动画和过渡,这是交互式Web开发的强大组合,早期没有JavaScript不可能实现。今天,研究证明CSS已承担多个先前由JavaScript处理的交互任务。例如,:hover伪类和transition属性允许视觉反馈和平滑动画。
不仅如此。切换手风琴和模态框以前是JavaScript领域,但今天可通过强大CSS组合实现,如用于手风琴的HTML标签,或用于模态框的:target伪类。CSS还可使用aria-label与content: attr(aria-label)处理工具提示,以及通过单选输入和标签处理星级评分。
另一篇文章“5 things you can do with CSS instead of JavaScript”列出了如scroll-behavior: smooth用于平滑滚动和@media (prefers-color-scheme: dark)用于深色模式等功能,这些任务曾需要JavaScript。同一文章中,还可看到使用CSS滚动捕捉功能创建轮播而无需JavaScript(且我们甚至不谈专为纯CSS创建轮播设计的功能,最近在Chrome中原型化)。
CSS向JavaScript领域的这些扩展使后者仅处理Web应用中的复杂关键交互,如用户输入、API调用和管理状态。虽然CSS伪类如:valid和:invalid可作为输入元素中的错误或成功指示器,但仍需JavaScript进行动态内容更新、表单验证和实时数据获取。
CSS现在解决了许多开发者从未知存在的问题。在许多样式场景中排除JavaScript后,开发者现在拥有简化的代码库。依赖更少,开销更低,网站性能更好,尤其在移动设备上。事实上,这一转变使CSS更倾向于可访问Web,因为CSS驱动的设计通常更易被浏览器和辅助技术处理。
新特性带来的挑战
尽管新特性带来许多好处,但也引入了以前不存在的复杂性:
- 当逻辑分布在CSS和JavaScript中时会发生什么?
- 没有清晰触发视图时如何调试条件样式?
- CSS以前只需处理颜色、字体、布局和间距等基础样式,新开发者更易上手。随着这些新特性需要理解一度专属JavaScript的概念,学习曲线变得多陡峭?
开发者意见分歧。一些人欢迎更智能、组件感知Web的自然演进,另一些人担心CSS变得过于复杂——一个原本为格式化文档设计的语言现在处理逻辑树和样式计算。
分歧观点:CSS中的逻辑是有益还是有害?
尽管上一节证据倾向于边界模糊,但开发者间存在显著争议。许多现代开发者认为CSS中的逻辑早该出现。随着Web开发更加组件化,声明式样式的局限性变得更明显,支持者将逻辑视为一度纯样式语言的必要演进。
例如,在React等前端库中,组件常需要基于属性或状态的条件样式。开发者不得不依赖JavaScript或CSS-in-JS解决方案,但这些解决方案并不理想。它们引入复杂性并耦合样式和逻辑。CSS和JavaScript在Web开发中应有独立关注点,但CSS-in-JS等库忽略了规则并合并了两者。
我们看到SASS和LESS等预处理器证明了条件、循环和变量在样式中的有用性。不接受CSS-in-JS方法的开发者已 settled for these预处理器。尽管如此,如Adam Argyle,他们表达了對原生CSS解决方案的需求。通过原生条件,开发者可减少JavaScript开销并避免运行时类切换以实现条件呈现。
“对我来说,在JavaScript中操作样式设置从不感觉正确,当CSS是正确工具时。通过CSS自定义属性,我们可以向CSS发送需要从JavaScript来的内容。”——Chris Heilmann
此外,Bob Ziroll不喜欢使用JavaScript处理CSS本应处理的任务,并认为这不必要。这反映了即使涉及JavaScript,也偏好使用CSS处理样式任务。这些开发者拥抱CSS的新能力,将其视为减少JavaScript依赖以提升性能的方式。
其他人反对。将逻辑引入CSS是 slippery slope,CSS可能通过变得太像编程语言而失去其核心优势——简单性、可读性和可访问性。担心开发者 risk complicating the web more than it is supposed to be.
“我老派。我喜欢我的CSS与HTML分离;我的HTML与JS分离;我的JS与CSS分离。”——Sara Soueidan
这一观点强调传统关注点分离,认为混合角色可能使维护复杂化。此外,Brad Frost在具体谈论CSS-in-JS时也表示怀疑, stating that it, “doesn’t scale to non-JS-framework environments, adds more noise to an already-noisy JS file, and the demos/examples I have seen haven’t embodied CSS best practices.” 这突出了对可扩展性和最佳实践的担忧,表明模糊边界可能并不总是有益。
社区讨论,如Stack Overflow上的,也反映了这一分歧。像“Is it always better to use CSS when possible instead of JS?”这样的问题收到答案 favoring CSS for performance and simplicity, but others argue JavaScript is necessary for complex scenarios, illustrating the ongoing debate. 不要被欺骗。同意CSS在样式中性能优于JavaScript可能看似方便,但情况并非总是如此。
更智能的CSS而不失其灵魂
CSS始终通过声明式、可访问和目的驱动与全面编程语言如JavaScript区分开来。
如果CSS要变得更智能,挑战不在于为其自身 sake 增加功能,而在于演进时不妥协其主要关注点。
“那么,逻辑丰富但仍声明式的CSS可能是什么样子?让我们找出答案。
条件规则(if, @when…@else)与谨慎引入的逻辑
CSS演进的一个主要前沿是通过if()函数和@when…@else at-rules引入原生条件,这些是CSS Conditional Rules Module Level 5规范的一部分。虽然仍处于早期草案阶段,这将允许开发者基于评估条件应用样式,而无需转向JavaScript或预处理器。与JavaScript的命令式性质不同,这些条件旨在保持逻辑 ingrained in CSS’s existing flow, aligned with the cascade and specificity.
更强大、有意的选择器
选择器一直是CSS的主要优势之一,以 targeted way 扩展它们将使表达关系和条件更易声明式,无需类或脚本。目前,:has()让开发者基于子元素样式化父元素,而:nth-child(An+B [of S]?)(在Selectors Level 4中)允许更复杂匹配模式。 together, they allow greater precision without altering CSS’s nature.
无JavaScript的作用域样式
开发者在React或Vue等基于组件的框架中面临的挑战之一是样式作用域。样式作用域确保样式仅应用于特定元素或组件,不泄漏。过去,为实现这一点,您需要实施BEM命名约定、CSS-in-JS或构建工具如CSS Modules。CSS中的原生作用域样式,通过新的实验性@scope规则,允许开发者在特定上下文中封装样式,无需额外工具。这一特性使CSS更模块化,而不绑定到JavaScript逻辑或复杂类系统。
一个基本设计问题是,我们是否可以在不使CSS像JavaScript的情况下赋予其能力。 truth is, to empower CSS with conditional logic, powerful selectors, and scoped rules, we don’t need it to mirror JavaScript’s syntax or complexity. 目标是声明式表达性,给予CSS更多感知和控制,同时保留其清晰、可读 nature, and we should focus on that. 当正确完成时,更智能的CSS可以放大语言优势而非稀释它们。
真正的危险不是逻辑本身,而是 unchecked complexity that obscures the simplicity with which CSS was built.
注意事项和约束:为什么智能并不总是更好
推动更智能CSS伴随着 significant trade-offs alongside control and flexibility. 多年来,历史表明向语言或框架、或库添加新特性很可能引入复杂性,不仅对新开发者,也对专家开发者。危险不在于CSS获得能力,而在于如何实现、教授和使用 that power.
CSS的最大优势之一一直是其 approachability. 设计师和初学者可快速学习基础:选择器、属性和值。随着更多逻辑、作用域和高级选择器的引入,学习曲线变陡。风险是“基础CSS”和“真实世界CSS”之间的差距扩大, echoing what happened with JavaScript and its ecosystem.
随着CSS变得更强大,开发者 increasingly lean on tooling to manage and abstract that power, like building systems (e.g., webpack, Vite), linters and formatters, and component libraries with strict styling conventions. 这创建了 hard to escape 的依赖。工具成为先决条件而非选项, further complicating onboarding and increasing setup time for projects that used to work with a single stylesheet.
此外,更多逻辑意味着更多潜在意外结果。可能出现更难发现和修复的新问题。如DevTools等资源 then need to evolve to visualise scope boundaries, conditional applications, and complex selector chains. 直到那时,调试可能 remain a challenge. 所有这些都是CSS-in-JS中经历的挑战;原生CSS更多?
我们以前见过。CSS历史充满了过度复杂化的解决方案,如Flexbox之前的表格布局、依赖浮动与清除修复技巧,以及原生CSS Grid之前的过于 rigid 网格系统。在每种情况下,hacky solution eventually became the problem. CSS变得更好不是通过模仿其他语言,而是通过标准化 thoughtful, declarative solutions. 通过正确能力,我们最终可以使CSS更好。
结论
我们刚刚走过CSS的历史长廊,探索了其现状,并窥视了其未来可能。我们都同意CSS已从简单、声明式语言发展为动态、上下文感知且是的、更智能的语言。演进当然伴随张力:更智能的样式语言与更少脚本依赖,以及更复杂与更陡峭学习曲线。
这是我的结论:
CSS的未来不应是为其自身 sake 添加逻辑的竞赛。而应是 thoughtful expansion, power balanced by clarity and innovation grounded in accessibility.
“那意味着在发布新特性前问艰难问题。意味着确保新能力帮助解决实际问题而不引入新障碍。