CSS 是一种强类型语言

Avatar of Eric Bailey
Eric Bailey

DigitalOcean 提供适用于您旅程每个阶段的云产品。立即开始使用 价值 200 美元的免费积分!

您可以通过编程语言如何 强类型或弱类型 来对其进行分类。此处,“类型”是指在编译时是否已知变量。例如,将整数 (1) 添加到包含整数的字符串 ("1") 中。

result = 1 + "1";

包含整数的字符串可能是由于一系列复杂逻辑和大量移动部件意外生成的。它也可能是有意从单个真实来源生成的。

尽管“弱”和“强”这两个词的含义如此,但强类型编程语言并不一定比弱类型编程语言更好。在某些情况下,可能需要灵活性而不是严格性,反之亦然。与编程的许多方面一样,答案取决于多个外部上下文(即“视情况而定”)。

另一个有趣的部分是,强类型或弱类型没有正式的定义。这意味着,人们对强类型或弱类型语言的理解各不相同,并且可能随着时间的推移而发生变化。

TypeScript

JavaScript 被认为是一种弱类型语言,这种灵活性促成了其在网络上的早期采用。但是,随着网络的成熟和工业化,JavaScript 的用例变得更加复杂。

TypeScript 这样的扩展是为了解决这个问题而创建的。可以将其视为 JavaScript 的“插件”,它将强类型移植到该语言中。这有助于程序员处理复杂的设置。例如,用于电子商务的数据密集型单页应用程序。

TypeScript 目前在 Web 开发行业非常流行,许多新项目在首次设置时默认使用 TypeScript。

编译时间

编译时间 是编程语言转换为机器代码的时刻。它是 运行时 的前奏,运行时是计算机执行机器代码的时刻。

与网络上的许多事情一样,编译时间有点棘手。使用 TypeScript 的设置将把 JavaScript 代码的组件部分缝合在一起,并将其编译成单个 JavaScript 文件,供浏览器读取和运行。

组件部分编译的时间是它们全部组合在一起的时候。TypeScript 充当一种监督者,如果在组合发生之前您尝试违反为自己设置的类型约定,它会向您发出警告。

A tooltip that reads, “var content: any. Property ‘content’ does not exist on type ‘PropsWithChildren<Props>’. ts(2339). View Problem (Option F8). No quick fixes available. Tooltip is pointing towards an argument called “content.”
VS Code 中的 TypeScript 错误示例。

然后,缝合在一起的 JavaScript 文件由 浏览器获取,浏览器也有自己的编译时间。浏览器编译时间变化很大,具体取决于

  • 浏览器所在的设备,
  • 浏览器正在执行的其他工作,以及
  • 设备的其他程序正在执行的其他工作。

浏览器不会直接使用 TypeScript,但可以感受到它的存在。 JavaScript 很脆弱。 TypeScript 通过尝试在代码编辑器中上游防止错误来帮助解决这种脆弱性。这降低了浏览器读取的 JavaScript 中出现错误的可能性——这些错误会导致 JavaScript 停止在用户使用的网站或 Web 应用程序上运行。

CSS

CSS 是一种声明式、特定于领域的编程语言。它也是强类型的。在大多数情况下,CSS 中的值保持声明为已编写。如果值无效,浏览器将丢弃整个属性。

CSS 中的类型

CSS 中的类型列表 很全面。它们是

文本类型
  • 全局范围的关键字
    • initial
    • inherit
    • unset
    • revert
  • 自定义标识符,专门用于特定事物,例如提供 grid-area 名称
  • 字符串,例如 "hello"
  • URL,例如 https://css-tricks.org.cn/
  • 带破折号的标识符 (--),用于创建自定义属性(稍后会详细介绍)
数字类型
  • 整数,即十进制数字 0-9
  • 实数,例如 3.14
  • 百分比,例如 25%
  • 尺寸,在数字后附加单位的数字,例如 (100px3s)
  • 比率,例如 16/9
  • flex,用于 CSS 网格计算的可变长度
数量类型
  • 长度
  • 角度,例如 15deg
  • 时间,例如 250ms
  • 频率,例如 16Hz
  • 分辨率,例如 96dpi

尺寸和长度可能看起来相似,但尺寸可以包含百分比,而长度则不能。

颜色类型
  • 关键字
    • 命名颜色,例如 papayawhip
    • transparent
    • currentColor
  • RGB 颜色
    • 十六进制表示法,例如 #FF8764
    • RGB/RGBa 表示法,例如 rgba(105, 221, 174, 0.5)
  • HSL/HSLA 颜色,例如 hsl(287, 76%, 50%)
  • 系统颜色,例如 ButtonText
图像类型
  • 图像,它是对图像文件或渐变的 URL 引用
  • color-stop-list,两个或多个颜色停止点的列表,用于渐变符号
  • linear-color-stop,用于指示渐变颜色停止点的颜色和长度表达式
  • linear-color-hint,用于插值颜色的长度百分比
  • ending-shape,它使用 circleellipse 关键字之一,用于径向渐变
2D 定位类型
  • 关键字
    • top
    • right
    • bottom
    • left
    • center
  • 百分比长度,例如 25%

CSS 中的编程

CSS 中的大部分编程都是编写选择器,然后指定一系列属性及其所需的值。选择器集合会为内容提供视觉形式,就像 JavaScript 逻辑集合会创建功能一样。

CSS 有函数。它可以执行 计算条件逻辑算法表达式状态基于模式的行为。它还有 自定义属性,它们实际上是 CSS 变量,允许动态更新值。甚至可以用 CSS 解决 FizzBuzz 问题

像其他编程语言一样,CSS 也有一层“元”层,包含关于如何 组织、管理和维护 的不同思路和技巧。

抛出错误

与其他编程语言不同的是,其他编程语言的代码很大程度上存在于后台,而 CSS 则高度可视化。如果您对属性声明使用无效值,您不会在控制台中看到警告或错误,但您会看到不符合您预期的视觉效果。

这是因为 CSS 很健壮。当由于结构错误的声明而导致视觉效果无法更新时,CSS 会优先考虑 **确保内容无论如何都能显示**,并尽可能地渲染所有其他有效的声明。这符合 语言的设计原则平台的原则 以及 Web 任务的总体目标

证明

让我们通过三个例子来演示 CSS 中的强类型如何保持护栏:一个使用简单的属性/值声明,一个使用计算,以及一个重新定义自定义属性的例子。

示例 1:简单的属性/值声明

查看 CodePen 中 Eric Bailey (@ericwbailey) 的 基本示例

在这个例子中,浏览器不理解横幅的 border-style“potato”声明。请注意,其他 .banner 类选择器属性/值声明被浏览器识别并渲染,即使 border-style 存在类型不匹配。这是一个关于 CSS 健壮性的例子。

border-style 声明需要以下文本样式类型之一:

  • 全局范围关键字,或
  • 自定义属性的虚线缩进。

如果我们将 border-style 更新为使用有效的类型值为 dotted,浏览器将渲染边框!

示例 2:计算

CSS 中的 calc() 函数 允许我们使用两个参数和一个运算符来返回计算结果。如果其中一个参数没有使用有效类型,则计算将无法进行。

在这个 CodePen 中,p 选择器的 font-size 属性需要一个具有数值维度类型的的值(例如 1.5rem)。但是,计算函数为 font-size 属性生成了一个无效类型值。这是因为 calc() 函数中的第二个参数是一个字符串 ("2rem"),而不是一个数值维度类型。

因此,段落的字体大小将回退到下一个最适用的父节点——body 元素上声明的 font-size1.5rem

这有点深入,但值得指出:在 calc() 函数中组合两个自定义属性可能会导致错误。虽然两个自定义属性本身可能是有效的,但 calc() 不会接受带破折号缩进的文本类型。假设我们可能尝试将包含不匹配单位的自定义属性相乘,例如 --big: 500px--small: 1em

示例 3:重新定义自定义属性

与 JavaScript 变量类似,自定义属性值可以重新定义。这种灵活性允许进行一些操作,例如轻松创建深色模式颜色主题。

在这个 CodePen 的 :root 选择器中,我设置了一个名为 --color-cyan 的自定义属性,其值为 #953FE3。然后,在 .square 类中,我将 --color-cyan 自定义属性的值更新为 top。虽然 top 是一个有效的类型值,但它不是 background-color 接受的类型。

请注意,更新后的自定义属性的范围是 .square,不会影响其他用法,例如短语“Don’t play to type”的右侧边框。如果您从 .square 中删除重新定义的自定义属性,您将看到青色背景颜色恢复。

虽然这有点牵强,但它可以作为一个例子,说明如果您不注意的话,重新定义自定义属性可能会失控。

这种现象可能发生在通信不良、CSS 代码库庞大以及使用 CSS 预处理器大规模构建自定义属性的项目中。

工具

事后看来,我认为 CSS 缺少控制台警告是一个缺陷,并且导致了人们对该语言的许多负面看法。

希望开发人员能注意到可能很小的视觉变化要求太高,并且不符合他们大多数其他日常工具的现状。我知道有一些尝试解决这个问题的举措。

第一个是 stylelint,一个专门用于处理 CSS 和类似 CSS 的预处理语言的 linter。stylelint 可以与代码编辑器、任务运行器、命令行工具和 GitHub 操作集成,帮助您控制 CSS。这使它能够满足开发人员已经在使用的工具。

A tooltip that reads, “var content: any. Property ‘content’ does not exist on type ‘PropsWithChildren<Props>’. ts(2339). View Problem (Option F8). No quick fixes available. Tooltip is pointing towards an argument called “content.”
stylelint 终端输出。

第二个是 Firefox 在其 开发者工具 中提供的出色 CSS 检查选项套件。特别地,我想提请注意它识别未使用的 CSS 的功能。这对于识别可能出现类型不匹配的 选择器非常有用。

Tooltip attached to an unused selector in the Developer panel. The tooltip reads, “vertical-align has no effect on this element since it’s not an inline or table-cell element. Try adding display: inline or display: table-cell. Learn more. Screenshot.”
Firefox 开发者版

总结

CSS 自成为编程语言以来一直都是强类型的,作为一种编程语言,它已经存在很长时间了。它最近也经历了很大的成长。如果您还没有关注,有一些 新的惊人功能可用

随着强类型 JavaScript 的流行,我希望它能帮助开发人员更快適应 CSS 坚定而灵活的方法。


感谢 Miriam Suzanne 提供的反馈。