使用自定义属性的一种方法是把它们看作是设计标记。颜色、间隔、字体,以及其他的东西。你在页面的根部设置它们,并在整个CSS中使用它们。非常有用,这不仅是自定义属性的经典用法,也是过去100万年来预处理程序变量的经典用法。
另一种使用自定义属性的方法,可以在设计标记的方法之外进行,就是更加努力,在任何给定的元素上的每一个主要的独特的样式选择上使用它们。
想象一下,你有一个这样的卡片(当然,为了演示而简化):
.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);
}
很好。
但是,当你不可避免地制作卡片的变体时,你就得自己去覆盖这些规则集了。一个CSS自定义属性的方法可以像:
.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);
}
暂时还比较啰嗦,但看看当我们想做变体的时候会发生什么。
.card-variation {
--card-background: purple;
--card-padding-block: 2.5rem;
--card-title-margin: 0 0 2rem 0;
}
这里有三个明显的优势:
- 我只改变我明确设定的要改变的值。我的主卡原型保持了我希望它保持的完整性。
- 我可以为变体的孩子们设计样式,而不需要正确地重写这些选择器。
- 我现在可以从HTML中的
style属性传递样式覆盖,以实现快速、一次性的变化。
CodePen嵌入回退
回落时不那么啰嗦了
与其在顶部声明自定义属性,然后在下面使用它们,我可以像这样同时进行:
.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));
}
现在,如果像--card-background 这样的东西碰巧被设置,它将覆盖这里的回退值。我并不完全喜欢这样,因为这意味着.card 上面的元素可以覆盖它。这可能是你想要的,但这与一开始就在.card 上声明这些值不完全一样。这里没有强烈的意见。
把它拆得更碎
这里的一个例子是,你可能想单独控制padding:
.card {
--card-padding-block: 2rem;
--card-padding-inline: 2rem;
--card-padding: var(--card-padding-block) var(--card-padding-inline);
padding: var(--card-padding);
}
现在,如果我想的话,一个变体可以只控制一部分padding:
.card-variation {
--card-padding-inline: 3rem;
}
不过你得注意一个大问题。意思是说,如果你在根部声明所有这些,这是不可能的,因为那些嵌套属性已经被解决了。但只要它首先在.card ,你在这里就可以了。
太远了吗?
假设你想对一个值的每个部分进行超级终极控制,比如说:
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));
}
这有点整洁,但可能太远了。颜色几乎肯定会被声明在根部,并且不受影响,所以这个大问题会使覆盖低级别的子属性成为不可能。此外,如果你有一个--color-1 ,你可能也有一个2-9(或更多),这一切都很好,因为对于一个颜色系统来说,有比颜色部分的简单数学操作更微妙的设计魔法。
可交付的设计系统?
毫无疑问,Tailwind已经享有很多的知名度。它采用了一种原子式的方法,一连串的HTML类分别控制一个属性。我认为其中一些受欢迎的原因是,如果你从这些预先配置的类中进行选择,那么设计的结果是相当不错的。你不可能脱离轨道。你从有限的价值选择中选择,这些价值已经被设计得很好。
我不会说基于自定义属性的风格设计方法是完全一样的。例如,你仍然需要考虑类名的抽象性,而不是直接对HTML元素应用样式。但是,它可能享有一些相同的约束/限制,这些约束/限制使得Tailwind和其他原子类的方法成为可取的。如果你只能从预定义的--spacing-x 值、--color-x 值和--font-x 值中挑选,你可能会取得比其他方式更有凝聚力的设计。
就我个人而言,我发现逐步建立一个更多基于自定义属性的设计系统感觉很好--如果没有其他原因的话,使变化和重写的管理更加合理。
第三方设计系统所提供的东西......除了一大套 "自定义属性 "供你随意使用外,什么也没有?
第三方的交付物甚至不一定是整个厨房的水槽,就像这样。例如,Adam Argyle的transition.style 提供了一个 "Hackpack",除了过渡动画助手的自定义属性外,什么都没有。
