2024 如何编写 CSS
2024 年的 CSS 令人惊叹。
这篇文章将收集我对 CSS 生态系统和我目前正在使用的工具的笔记和想法。
用户体验
访问网站时加载样式表的最佳体验是什么样子的?
- 样式表应尽可能快速加载(文件小)
- 除非更改,否则不应重新下载样式表(适当的缓存标题)
- 页面内容应尽量减少或没有布局变化
- 字体应尽可能快地加载,并尽量减少布局偏移
开发体验
我们的工具必须帮助我们创造更好的用户体验。开发人员体验固然重要,但不能凌驾于用户体验之上。
我们使用的 DX 风格工具如何帮助我们创建更好的用户体验?
- 剪裁不使用的样式、最小化并压缩 CSS 以减小文件大小
- 生成散列文件名,实现安全、不可更改的缓存²。
- 将 CSS 文件捆绑在一起,以减少网络请求
- 防止命名冲突,避免视觉倒退
如何帮助我们编写更易于维护、更令人愉悦的 CSS?
- 在删除相应的用户界面代码时轻松删除样式
- 易于遵循设计系统或主题集
- 通过 TypeScript 支持、自动完成和内衬功能获得编辑器反馈
- 在编辑器中接收工具反馈,防止出错(类型检查、校对)
2024 年的 CSS
无需任何额外工具,就能轻松编写出色的样式。
下面的示例使用了许多跨浏览器支持的最新 CSS 功能,无需任何构建步骤。你可能不再需要 Sass 或 Less 了!
:root { --main-bg-color: #f3f4f6; --title-color: #262626; --text-color: #525252; --font-family: "Arial", sans-serif; } body { margin: 0; padding: 0; background-color: var(--main-bg-color); font-family: var(--font-family); } .blog-header, .blog-footer { text-align: center; padding: 1rem; background-color: var(--title-color); color: white; } .blog-post { container-type: inline-size; margin: 1rem; padding: 1rem; background-color: white; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); & .post-title { color: var(--title-color); margin: 0 0 1rem 0; text-wrap: balance; font-size: 1em; } & .post-content { color: var(--text-color); } } @container (min-inline-size: 500px) { .blog-post { padding: 1.5rem; & .post-title { font-size: 1.25em; } } }
这是否意味着不再需要工具?对某些人来说,是的。
构建步骤
为了满足上述设计限制,您可能需要一个构建步骤。
您的用户不可能都使用最新版本的浏览器。但更重要的是,总有一些尚未支持跨浏览器的较新语法是您希望使用的。
您可以手动编写 @supports 规则来检查浏览器是否支持,但这只能解决部分问题。与其让人类来优化 CSS,为什么不让机器来处理呢?
编译
编译器让以下工作流程变得简单:
- 自动删除任何未使用的样式,将文件捆绑在一起以减少网络请求,添加浏览器品牌前缀,并通过删除空白和注释对输出进行最小化处理
- 自动生成唯一的文件名,允许框架设置缓存标头,如向浏览器发送不可变信号,表示内容永远不会更改
- 指定目标浏览器(browserslist),并降低语法以编译现代 CSS 功能,使其适用于这些浏览器
流体化 CSS
您访问 Google 是为了预订机票。它无法预先计算您的意图,因此在初始用户界面上为您提供了一个搜索栏。您搜索 “Flight SFO to NYC”(飞往纽约市的航班),服务器就会流式传输航班小部件,供您选择日期。
谷歌不可能提前将所有可能的小工具都包括在内。货币换算、定时器、实时体育比分,应有尽有。这些小工具的用户界面和样式都需要动态输入。
现在,React(和 Next.js)通过流式 SSR 和 CSS 支持这种模式。在 React 模型中,您将用户界面定义为组件,而组件又依赖于样式。如何在不影响页面上任何内容的情况下,安全地将样式流导入到部件中?
样式需要具有作用域或原子性,这样,如果它们比要样式化的 DOM 内容更早加载,就不会改变页面上已有元素的样式。
例如,CSS模块的样式规则只适用于导入该模块的组件。Tailwind 使用原子实用工具类,它们被编译成一个样式表,并在使用任何类之前加载。StyleX 也会生成原子类。全局样式不能很好地与流媒体配合使用,除非在流媒体开始时加载。
我的建议
CSS 模块
CSS 模块是在普通 CSS 的基础上进行的一项小而有效的改进。
它们实现了我们所需的用户体验约束和大部分(但不是全部)的 DX 约束。几乎所有的现代捆绑程序和框架都可以使用它们。您可以复制/粘贴现有的 CSS 选择器,它们无需任何修改即可在 CSS 模块中使用。
它们不能生成原子样式。它们不支持使用多种主题(仅支持 CSS 变量)。此外,由于样式代码位于 TypeScript 文件之外,因此无法获得类型安全和自动完成功能。但这些限制对你来说可能没什么问题。
💡
Vite 使用了支持 CSS 模块的 Lightning CSS,Tailwind 和 Next.js 也即将使用它。像 postcss 和 autoprefixer 这样的工具正在被更快、一体化的 Rust 工具链所取代。
Tailwind CSS
Tailwind 使用编译器只生成使用过的类。因此,虽然实用 CSS 框架包含许多可能的类名,但只有使用过的类名(如 “font-bold text-2xl”)才会包含在编译后的单一 CSS 文件中。
假设你只编写 Tailwind 代码,那么你的捆绑包永远不会大于使用过的 Tailwind 类的总数。你使用所有这些类的可能性微乎其微。这就意味着您对生成的 CSS 文件大小有一个固定的上限,然后对其进行最小化、压缩和缓存,以获得最佳性能。
您不必只编写Tailwind 样式。Tailwind 类只是符合设计系统的普通 CSS 的实用工具。例如,你可以将 Tailwind 与 CSS 模块混合使用。
Tailwind 并非没有取舍。与之搭配的工具有很多:
集成 VSCode,可实现自动完成、语法高亮等功能
Prettier 集成,可自动排序类名
Tailwind最受争议的部分是语法。它让人又爱又恨。我是在使用 Tailwind 构建了一些东西之后才开始欣赏它的。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Minimal Blog</title> <script src="https://cdn.tailwindcss.com"></script> </head> <body class="bg-gray-100 font-sans"> <header class="text-center text-3xl font-bold py-8 bg-neutral-800 text-white"> <h1>Minimal Blog</h1> </header> <main class="w-full px-4"> <article class="my-4 p-4 bg-white shadow-md"> <h2 class="text-neutral-800 mb-4 font-bold">The Art of CSS</h2> <p class="text-neutral-600 leading-5"> Discovering the latest features in CSS can transform the way we design and interact with web content. </p> </article> <article class="my-4 p-4 bg-white shadow-md"> <h2 class="text-neutral-800 mb-4 font-bold">Exploring Web Design</h2> <p class="text-neutral-600 leading-5"> A journey through the evolution of web design, from static pages to dynamic, responsive experiences. </p> </article> </main> <footer class="text-center py-8 bg-neutral-800 text-white"> <p>© 2023 Minimal Blog</p> </footer> </body> </html>
StyleX
大多数 CSS-in-JS 库都存在两个问题:
- 性能:组件必须将 JS 中编写的样式转换为 CSS,以便在渲染时插入到文档中。这可能会产生很大的成本,这也是各种库转向 StyleX 这样的 “零运行时 “库的原因。
- 兼容性:许多现有的 CSS-in-JS 库都增加了对 React 流式服务器渲染的支持,但仍然与其他性能优化不兼容,例如将应用程序的某些部分移至 React 服务器组件。
为了解决这些问题,Vanilla Extract、Panda 等 “零运行时 “CSS-in-JS 库应运而生。
StyleX 是最新的 CSS-in-JS 库,它可以解决这些问题以及更多问题。如果你想深入了解,我推荐你阅读 “Thinking in StyleX”。
这个例子是我第一次使用 StyleX。虽然它仍然是开源领域的新成员(生态系统也反映了这一点),但它并不是一个新的库。它为所有 Meta 网站提供支持:Facebook、Instagram、WhatsApp 和 Threads。
不过你还是得给东西命名🫠 输入buttonWrapperContainer
。
结论
现在 CSS 对我来说……有趣吗?我想是的。我很期待未来几年的发展。
你会选择不同的东西吗?我错过了什么吗?请留言。
¹:更多:linear() easing, subgrid, dynamic viewport units, color spaces, 和@layer.
²:由于文件名保证唯一,因此可以设置不可变缓存标头,告诉浏览器内容永不改变。这样,浏览器就可以永久缓存文件,从而大大提高性能。
本文文字及图片出自 How I'm Writing CSS in 2024
你也许感兴趣的:
- 【外评】CSS masonry 砌体布局的替代建议
- 你需要知道的现代 CSS 技巧(2024 年春季版)
- 使用 :has() 作为 CSS 父选择器及其他更多内容
- 一个 Div 能做的事情
- 基于时间的 CSS 动画
- 【外评】请帮助我们实现 CSS grid 布局 Level 3,又称“砌体 Masonry”布局
- 最漂亮的 CSS 动画背景示例及源代码
- CSS Grid 网格布局中新引入的 Fr 单位用法教程
- 60+ CSS 搜索框代码 codepen 示例
- 响应式图片
你对本文的反应是: