我目前正在与一个团队合作开发一组web组件,这些组件应该是客户公司开发的当前和即将开发的web应用程序的基础。
我希望这些组件支持颜色主题化;这方面的第一个用例是支持暗模式。
当前方法
-
我在文件
colorpalette.css
中定义了客户的公司设计颜色(这些颜色只是一个例子)::root { --color-blue: #004994; --color-light-blue: #0095db; --color-light-green: #afca06; --color-light-grey: #9c9c9c; --color-green: #51ae31; --color-grey: #555555; --color-orange: #f39200; --color-red: #d40f14; --color-turquoise: #008c8e; --color-violet: #b80d78; --color-yellow: #ffcc00; --color-white: #ffffff; --color-black: #000000; }
-
我正在确保所有其他使用或定义颜色的文件只使用此文件中的颜色。这导致了一个文件
colors.css
,我开始为每个主题定义不同的颜色:@import "./colorpalette.css"; :root { --bg-color-button: var(--color-light-grey); --text-color-button: var(--color-black); --border-color-button: var(--color-grey); } :root[data-theme=dark] { --bg-color-button: var(--color-grey); --text-color-button: var(--color-white); --border-color-button: var(--color-light-grey); }
到目前为止,我对这种方法感到满意。
问题
现在我开始添加这些按钮的不同语义版本:.btn-danger
、.btn-success
等,它们应该使用颜色作为传输这些语义的手段。
可能的解决方案-两种不同的替代方案
这是我不确定的地方,因为我看到了两个替代方案:
-
为这些语义创建新的变量,并在其名称中携带语义:
:root { --bg-color-button-success: var(--color-light-green); --text-color-button-success: var(--color-black); --border-color-button-success: var(--color-green); }
并在按钮样式定义中使用这些:
.btn { background-color: var(--bg-color-button); color: var(--text-color-button); border-color: var(--border-color-button); } .btn.btn-success { background-color: var(--bg-color-button-success); color: var(--text-color-button-success); border-color: var(--border-color-button-sucess); }
- 优点
- 只需修改两个文件,就可以重新设置整个应用程序的主题
- Cons
- 这种方法显然会产生无数的变量,因为我们需要为每个需要应用不同颜色的地方定义一个单独的变量
- 如果以后要引入其他按钮变体,则必须同时编辑
colors.css
和button.css
- 优点
-
另一种方法可以是在指定上下文中重新定义现有变量:
.btn { background-color: var(--bg-color-button); color: var(--text-color-button); border-color: var(--border-color-button); } .btn.btn-success { --bg-color-button: var(--color-light-green); --text-color-button: var(--color-black); --border-color-button: var(--color-green); }
- 优点
- alot更少的变量
- 变量只有在实际使用的地方才会被重新定义
- 定义新的按钮变体比其他方法更容易,因为您只需要编辑
button.css
- Cons
- 要重新命名组件库,除了
colorpalette.css
和colors.css
之外,您可能还需要触摸每个组件的css文件
- 要重新命名组件库,除了
- 优点
我试着总结了两种方法的优缺点。
问题
比起另一种方式,更喜欢一种方式的其他原因是什么?
提示
在最终投票关闭之前,请考虑以下:
我知道很多人可能会认为这个问题是离题的,因为它吸引了固执己见的答案,但我相信这个问题对许多开发人员来说有很大的实际意义,因为css自定义属性最近才成为事实上的标准,这通常会导致最佳实践慢慢出现。因此,固执己见的答案以及这些观点的原因正是我在这里有意问的。
这也绝不是最佳实践CSS主题的重复,因为这个问题来自2010年,当时CSS自定义属性并不存在。
在我看来,主题系统的优先级要求很容易改变外观。因此,您的第一个解决方案将适用于这种情况。让我们谈谈它的缺点。
这种方法显然会产生无数的变量,因为我们需要为每个需要应用不同的颜色
需要更多的变量。因为它们有不同的用途。当您重新设计主题时,它将帮助您快速更改外观,而无需进入所有组件文件。你只需要关心它,以防重新设计主题。所以我认为这不应该被视为缺点。
如果您以后想引入其他按钮变体,您可以必须编辑CCD_ 10和CCD_。
同样,我不认为这是缺点,因为您只需要在2个文件中添加一些额外的代码。这些代码不会影响以前存在的任何东西。
但是您忘了提到这种方法的最大缺点。你需要重写CSS规则。如果我们使用渐变背景会发生什么?代码是这样的:
.btn {
background: linear-gradient(to left, var(--text-color-button-1), var(--text-color-button-2) 50%, var(--text-color-button-3) 75%, var(--text-color-button-4) 75%);
color: var(--text-color-button);
border-color: var(--border-color-button);
}
.btn.btn-success {
background: linear-gradient(to left, var(--text-color-button-success-1), var(--text-color-button-success-2) 50%, var(--text-color-button-success-3) 75%, var(--text-color-button-success-4) 75%);
color: var(--text-color-button-success);
border-color: var(--border-color-button-sucess);
}
如果我们想把50%的数字改成另一个,那将是一场噩梦。因此,让我们将您的两种方法结合为一,以解决它们的缺点。
这是那些想要快速扫描的人的解决方案:
color.css
--color-red-100: red;
--color-red-500: red;
--color-red-900: red;
--color-green-100: green;
--color-green-500: green;
--color-green-900: green;
--color-bg-button-1: var(--color-red-100);
--color-bg-button-2: var(--color-red-500);
--color-bg-button-3: var(--color-red-900);
--color-bg-button-4: var(--color-red-100);
--color-bg-button-success-1: var(--color-green-100);
--color-bg-button-success-2: var(--color-green-500);
--color-bg-button-success-3: var(--color-green-900);
--color-bg-button-success-4: var(--color-green-100);
button.css
.btn {
background: linear-gradient(to left, var(--text-color-button-1), var(--text-color-button-2) 50%, var(--text-color-button-3) 75%, var(--text-color-button-4) 75%);
}
.btn.btn-success {
--text-color-button-1: var(--color-bg-button-success-1);
--text-color-button-2: var(--color-bg-button-success-2);
--text-color-button-3: var(--color-bg-button-success-3);
--text-color-button-4: var(--color-bg-button-success-4);
}
在这种方法中:
- 通过使用基本颜色变量,如果你只想调整一些灰度,你只需要更改基本颜色变量、按钮和其他任何东西都会相应地更改
- 通过使用作用域变量但链接到新变量,您不需要重写CSS规则,只需编辑一个文件中的变量值就可以轻松地重新设计主题
- 当然,这种方法仍然有第一个解决方案的两个缺点,但我认为它可以用于更高优先级的要求
对我来说,最佳实践应该放在特定的上下文中,所以这个解决方案非常适合,以防你的首要任务是轻松地重新设计主题。如果你只想使用CSS变量来轻松重用,并且没有任何改变变量值的计划,那么应该选择OP的第二个解决方案来进行快速编程。