你不需要 CSS 框架

一. 关键要点

  • CSS 框架在短期内可以提高速度和一致性,但随着时间的推移会变得越来越难以维护。
    使用 CSS 框架的代码库将逐渐在其上构建自己的自定义框架。该框架将很难使用、理解和修改。
  • 对于完全采用框架设计系统而无需进行任何更改的应用,CSS 框架可能是一个不错的选择。这在理论上听起来不错,但在实践中却并非如此。
  • 使用 CSS 编写样式,而不是使用 SCSS 或 JS-to-CSS 等编译为 CSS 的选项。这样做会增加复杂性,而现代 CSS 拥有出色的功能,因此收益较低。
  • 构建 CSS 时,请从语义样式开始。这将向其他开发人员表达您的意图,并让他们有更多选择来选择模板策略。

开发人员使用 Material UI、Bootstrap 或 Pico 等 CSS 框架来减少样板代码、提高质量和实现一致性。然而,随着应用程序代码库的成熟,这些优势很难维持。应用程序的外观和感觉会随着框架的变化而变化,新组件不断增加,现有的布局和组件也会发生修改。开发人员必须配置和覆盖框架以适应这些变化。覆盖框架比从头开始实施更改更加困难。

我建议开发人员不要使用 CSS 框架,而是编写自己的自定义 CSS。随着应用程序需求的发展,开发人员会修改现有样式或从入门版中复制新样式,而不是覆盖现有样式。现代 CSS 具有许多功能,可以编写可维护的样式。将样式保留在代码库中而不是作为外部依赖项,可以使 CSS 代码库随着时间的推移保持精简和易于理解。

二. CSS 框架的缺点

1. 难以修改

修改框架耗时、难以维护且容易出错。当开发人员遵守规定的范围时,框架可提供最大的好处。许多框架都提供一定程度的自定义功能,但应用程序的自定义需求通常超出了框架的内置自定义选项。开发人员必须成为修改框架的专家,而不是使用 CSS 的专家。修改通常使用不属于框架公共 API 的功能,这使得自定义在升级框架时容易中断。

不久之后,框架修改变得如此广泛,以至于团队最终会拥有自己的自定义框架,其中包含许多修改、自定义和扩展。这个自定义框架使用自己的约定,很难保持可维护性。它通常看起来很陌生,即使对于底层 CSS 框架的专家来说也是如此。使用纯 CSS 可以轻松解决的问题变得很棘手,因为它们必须在框架的上下文中解决。

2. 难以保持一致性

团队有时会使用 CSS 框架,因为整个产品团队都承诺使用该框架的设计系统,并且从不偏离。许多团队都是从这个目标开始的,但几乎没有一个团队能长期坚持下去。框架的设计系统非常通用;它们试图满足大多数应用程序的大多数需求,而不是任何一个应用程序的所有需求。随着时间的推移,应用程序的设计需求将始终偏离框架提供的内容。

3. 与其他语言框架的区别

我们不能将 CSS 框架的缺陷推广到其他类型的框架,例如 Flask、Rails 或 Spring 等 Web 框架。开发人员经常会修改 CSS 框架的内部结构,但在使用 Web 框架时很少需要这样做。例如,需要通读 Flask 源代码来编写修改代码以改变 Flask 的路由或会话管理方式的情况很少见。但是,对于使用 MUI 的开发人员来说,styleOverrides修改滑块的渲染方式却很常见。CSS 框架代码经常被修改这一事实使 CSS 框架如此危险。

三. 编写自己的 CSS

当您编写自己的 CSS 时,通常从重置、主题、基本 CSS 样式和组件开始。我更喜欢每次都从头开始编写这些内容,但许多开发人员发现这太耗时了。为了减少样板代码,您可能需要考虑使用 CSS 入门代码库来提供基本样式。开发人员将入门 CSS 直接添加到他们的代码库中,而不是将其添加为外部依赖项。入门代码为开发人员提供了框架的好处(减少样板代码、提高质量和一致性),而没有缺点。

我维护了一个CSS 入门程序,可供任何人使用,但如果您不喜欢,您可以使用以下选项之一作为起点来创建自己的入门程序。

  • 你现有的代码库之一(当然,不是通过框架构建的)
  • 具有简洁风格的开源代码库
  • 像Pico CSS这样的最小 CSS 框架

请记住,对于任何这些选项,您可能希望从其 CSS 的一小部分开始,然后随着时间的推移复制新的部分。随着设计的发展,修改启动器的样式,而不是覆盖它们。

1. 主题

开发人员现在可以使用CSS 自定义属性(变量)将主题添加到 CSS 。主题可以使用prefers-color-scheme 媒体查询来响应用户对暗色或亮色模式的偏好。

构建主题时,在主题文件顶部将原始 CSS 颜色声明为变量。接下来,声明语义变量,例如基本主题的–text-color和–background-color。最后,根据需要为任何其他主题(例如深色主题)覆盖语义变量。在其余代码中使用语义变量作为所有颜色的值,以确保您的应用程序能够正确响应主题。

:root {
    --black: #222222;
    --white: #FFFFFF;

    --text-color: var(--white);
    --background-color: var(--black);
}

@media (prefers-color-scheme: dark) {
    :root {
        --text-color: var(--white);
        --background-color: var(--black);
    }
}

body {
    color: var(--text-color);
    background-color: var(--background-color);
}

2. CSS 范围

CSS 作用域可以将样式限定在给定元素或组件中。作用域允许开发人员为特定组件创建样式,而不必担心它们如何影响代码库的其他区域(也无需定义过于具体的规则)。浏览器对作用域的支持正在迅速改善,因此很快就能不受限制地使用它们。以下代码将颜色设为红色,h1但不会影响h1给定section标签之外的任何元素。

<section>
    <style>
        @scope {
            h1 {
                color: red;
            }
        }
    </style>

    <h1>Hello world</h1>
</section>

3. 嵌套语法

CSS 支持类似于 SCSS 所推广的嵌套语法,这使得 CSS 编写起来更加方便,并且有助于提高可读性。嵌套样式有助于表达样式的逻辑分组,并减少在多个规则中重复使用通用选择器的需要。

hgroup {
    margin-bottom: 1rem;

    h1 {
        font-weight: 700;
    }
}

4. 辅助函数

CSS 拥有越来越多的值函数,例如calc和color-mix,允许开发人员在定义 CSS 值时执行计算或处理。这有助于减少必要的 CSS 变量数量,并允许开发人员定义易于扩展的灵活样式。

button {
    --button-size: 1rem;

    font-size: var(--button-size);
    padding: calc(.5 * var(--button-size)) calc(1.25 * var(--button-size));
    background: var(--button-color);
}

button.large {
    --button-size: 2rem;
}

button.disabled {
    background: color-mix(in srgb, var(--button-color) 65%, transparent);
}

5. 非 CSS 复杂性

非 CSS 解决方案(如 SCSS 或 JS-to-CSS)存在重大缺陷,因此不适合用于应用程序样式。最大的缺点是编译步骤。如果在构建时将样式编译为 CSS,开发人员的工作流程和工作站设置将变得更加复杂。如果在运行时将样式编译为 CSS,性能可能会受到影响,并且编译失败可能会影响用户。无论哪种情况,浏览器都会以 CSS 运行(和调试)样式,因此开发人员需要了解生成的 CSS。

此外,开发人员需要考虑编译为 CSS 的解决方案如何与现有软件交互。较新的框架(如 NextJS 或 Remix)在浏览器和服务器上都运行客户端代码。这意味着样式编译必须能够同时在浏览器和服务器上运行,服务器可以是 Node 或类似工作器的环境(如 Cloudflare Workers 或 Deno)。许多当前的编译为 CSS 选项都不能很好地支持这些环境。此外,许多流行的框架(如 React)现在都利用了流式 HTTP 响应,这大大增加了运行时编译样式的复杂性。

6.使用语义 CSS

使用语义类名(基于语义含义命名的可重用类)对常用样式进行分组。语义类向消费者表达了一组样式的意图。命名是我们作为开发人员所做的最重要的事情之一,可以使我们的软件更易于使用和适应。作为开发人员,我们应该在命名我们的 CSS 类上投入大量精力,尤其是在开发一个可供他人修改和扩展的系统时(毕竟,软件的阅读次数比编写次数多)。

语义类名还允许开发人员灵活地确定其模板策略。原子 CSS 类名(基于视觉功能命名的单一用途类,由Tailwind CSS推广)迫使开发人员通过创建细粒度的 UI 组件或部分组件来减少标记重复。开发人员必须拆分组件来封装样式,从而导致组件过于通用,并带有大量令人困惑的选项。

7. 使用现代布局选项

Flexbox 和 Grid 等现代布局选项允许开发人员使用简洁的标记和 CSS 构建响应式布局。这意味着我们不再需要为过时的 12 列网格布局而烦恼,这种布局限制了灵活性并导致标记混乱。一个好的经验法则是,在一维布局元素时使用 Flexbox,在二维布局元素时使用 Grid。

8. 如何构建自定义 CSS

首先,编写或引入构建应用基本全局样式所需的最少样式集。这可能包括 CSS 重置、颜色主题样式、基本布局和排版。当您需要更复杂的组件(如按钮、下拉菜单、表格、模态框、工具提示等)时,请将这些样式直接编写或添加到您的代码库中。

将应用样式视为代码库的一部分,而不是外部依赖项。当应用的样式与开始时的样式不同时,请修改基本样式,而不是覆盖它们。这有助于保持样式精简且易于理解。

优先考虑全局并根据需要编写范围样式
全局样式是适用于整个应用程序的 CSS 样式。如果没有全局样式,就很难保持一致的外观和感觉。您编写的第一个样式可能是全局样式。这些样式适用于您的整个应用程序,并且很少被覆盖。

编写新样式时,请花一些时间确定其范围。起初,它们的范围可能有限,因此可以使用类或将它们编写为范围狭窄的样式@scope。随着时间的推移,范围样式中重复的常见模式可能会被提取到全局样式中。经常重构您的 CSS!

四. 总结

总之,虽然 CSS 框架很流行,但我认为它们通常不是设计应用程序样式的明智之选。在下一个项目中使用纯 CSS 构建,可以从头开始。您会发现,您可以快速构建应用程序的初始样式并随着时间的推移对其进行很好维护。

相关推荐

  1. 需要 CSS 框架

    2024-07-17 09:02:07       23 阅读
  2. CSS中那些知道的选择器

    2024-07-17 09:02:07       36 阅读
  3. 知道的CSS函数:attr() 的深度探索

    2024-07-17 09:02:07       31 阅读
  4. 知道的CSS链接:解锁网页导航的秘密武器

    2024-07-17 09:02:07       24 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-17 09:02:07       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-17 09:02:07       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-17 09:02:07       58 阅读
  4. Python语言-面向对象

    2024-07-17 09:02:07       69 阅读

热门阅读

  1. 使用 RocketMQ 实现消息的顺序消费

    2024-07-17 09:02:07       26 阅读
  2. c#之修饰符知识点

    2024-07-17 09:02:07       24 阅读
  3. Conda的冲突解决艺术:在包依赖中寻找和谐

    2024-07-17 09:02:07       27 阅读
  4. zookeeper+kafka群集

    2024-07-17 09:02:07       28 阅读
  5. C++11中引入的bind绑定器和function函数对象

    2024-07-17 09:02:07       25 阅读
  6. IPython 日志秘籍:%logstate 命令全解析

    2024-07-17 09:02:07       24 阅读
  7. 系统架构师(每日一练2)

    2024-07-17 09:02:07       22 阅读
  8. 【文章收录】-站在巨人的肩膀上一起飞

    2024-07-17 09:02:07       20 阅读
  9. 蒙特卡洛采样

    2024-07-17 09:02:07       18 阅读
  10. 接口,抽象类,类

    2024-07-17 09:02:07       26 阅读