自定义属性的一种使用方法是将其视为设计令牌:颜色、间距、字体等等。您可以在页面根部设置它们,并在整个 CSS 中使用它们。非常有用,并且在过去一百万年里,不仅是自定义属性,而且是预处理器变量的经典用例。
另一种使用方法(可以与设计令牌方法结合使用)是更彻底地使用它们,用于任何给定元素上的每个主要独特样式选择。
假设您有一个这样的卡片(为了演示目的而简化):
<code>.card { background: hsl(200deg 15% 73%); border: 4px solid rgb(255 255 255 / 0.5); padding: 2rem; border-radius: 8px; } .card > h2 { margin: 0 0 1rem 0; border-bottom: 3px solid rgba(0 0 0 / 0.2); }</code>
很好。
但是,当您不可避免地制作卡片的变体时,您需要自己覆盖这些规则集。CSS 自定义属性方法可以是这样的:
<code>.card { --card-background: hsl(200deg 15% 73%); --card-border: 4px solid rgb(255 255 255 / 0.5); --card-padding: 2rem; --card-border-radius: 8px; --card-title-margin: 0 0 1rem 0; --card-title-border: 3px solid rgba(0 0 0 / 0.2); background: var(--card-background); border: var(--card-border); padding: var(--card-padding); border-radius: var(--card-border-radius); } .card > h2 { margin: var(--card-title-margin); border-bottom: var(--card-title-border); }</code>
目前来看,稍微冗长一些,但是看看当我们想要进行变体时会发生什么:
<code>.card-variation { --card-background: purple; --card-padding-block: 2.5rem; --card-title-margin: 0 0 2rem 0; }</code>
以下是三个显而易见的优势:
与其在顶部声明自定义属性,然后在下面使用它们,我可以用这种方式同时进行:
<code>.card { background: var(--card-background, hsl(200deg 15% 73%)); border: var(--card-border, 4px solid rgb(255 255 255 / 0.5)); padding: var(--card-padding, 2rem); border-radius: var(--card-border-radius, 8px); } .card > h2 { margin: var(--card-title-margin, 0 0 1rem 0); border-bottom: var(--card-title-border, 3px solid rgba(0 0 0 / 0.2)); }</code>
现在,如果像 --card-background 这样的属性被设置了,它将覆盖此处的回退值。我不完全喜欢这个,因为它意味着 .card 上方 的元素可以覆盖它。这可能是您想要的,但这与一开始在 .card 级别声明值并不完全相同。这里没有强烈的意见。
这里的一个例子是您可能想要单独控制填充。
<code>.card { --card-padding-block: 2rem; --card-padding-inline: 2rem; --card-padding: var(--card-padding-block) var(--card-padding-inline); padding: var(--card-padding); }</code>
现在,如果我想要,变体可以只控制填充的一部分:
<code>.card-variation { --card-padding-inline: 3rem; }</code>
但是您必须注意一个很大的问题。这意味着如果您在根部声明所有这些,这将不起作用,因为这些嵌套属性已经被解析了。但是,只要它首先在 .card 上声明,您在这里就会没事。
假设您想要对值的每个部分进行超级终极控制。例如:
<code>html { --color-1-h: 200deg; --color-1-s: 15%; --color-1-l: 73%; --color-1-hsl: var(--color-1-h) var(--color-1-s) var(--color-1-l); --color-1: hsl(var(--color-1-hsl)); }</code>
这有点巧妙,但这可能太过分了。颜色几乎肯定会在根部声明并保持不变,因此这个很大的问题将使覆盖低级子属性成为不可能。此外,如果您有 --color-1,您可能还有 2-9(或更多),这很好,因为颜色系统比简单的颜色部分的数学运算要精细得多。
毫无疑问,Tailwind 非常受欢迎。它使用原子方法,其中大量 HTML 类分别控制一个属性。我认为它受欢迎的部分原因是,如果您从这些预配置的类中进行选择,那么设计最终会相当不错。您无法偏离正轨。您是从一系列经过设计以使其看起来不错的有限值中进行选择的。
我不会说基于自定义属性的样式方法完全相同。例如,您仍然需要考虑类名抽象,而不是直接将样式应用于 HTML 元素。但是,它可能会享有一些与 Tailwind 和其他原子类方法相同的约束/限制。如果您只能从预定义的 --spacing-x 值、--color-x 值和 --font-x 值中进行选择,您可能会实现比以往更具凝聚力的设计。
就我个人而言,我发现朝着更依赖自定义属性的设计系统迈进感觉很好——如果没有什么比这更能使变体和覆盖更易于管理了。
第三方设计系统如何将它们提供的功能作为……只是一组大型自定义属性供您随意使用?
第三方交付成果甚至不必像这样包含所有内容。例如,Adam Argyle 的 transition.style 提供了一个“Hackpack”,它仅仅是转换动画帮助器的自定义属性。
我听到的一个反对这种更全面的自定义属性方法的论点是新手可理解性。如果您编写了该系统,它可能对您来说非常有意义。但它是在 CSS 之上的额外抽象。所有的人都共享 CSS 知识,而定制系统知识仅由积极参与该系统的人员共享。
刚接触大量使用自定义属性的系统将会有一个非常陡峭的学习曲线。
以上是不同程度的自定义属性使用的详细内容。更多信息请关注PHP中文网其他相关文章!