CSS 自定义属性在Web组件中的应用
今天我们不聊什么是 CSS自定义属性 ,而把重点放在CSS自定义属性在组件中怎么使用,她又会给我们设计组件带来什么样的变化和相应的优势。在这篇文章中,我们主要会探讨CSS自定义属性为Web组件服务,以及怎么利用CSS自定义属性来维护组件。
设计背景
Web组件的设计对于Web从业人员来说是最常见的一部分了,随着JavaScript框架到来,除了给我们为组件设计带来了红利,但也给我们造成一定的约束性。比如说,我们设计的一个Web组件,应该提供什么样的方式给Web开发人员使用是最佳的姿势。不管是CSS方法论的基础上设计的UI组件,还是基于JavaScript框架上(比如Vue、React)设计的UI组件,在提供给开发者使用上来说还是存在一定的约束性。或者说可扩展性并不是非常的灵活。这也是令很多设计Web组件的同学来说头痛的地方,也在致力解决的一个点。
值得幸运的是,CSS Houdini的出现,给Web组件的设计带来了一些灵感,至少我在这方面得到较强的设计灵感。接下来,我们来阐述CSS Houdini给Web组件的设计带来什么灵感?感兴趣的同学请继续往下阅读。
CSS Houdini给组件带来的扩展性
在《 提示框组件的实现给我带来的思考和探索 》一文中的结尾处向大家演示了如何通过 CSS Houdini来设计一个Tooltips的组件 :
同时给大家留下一个还需要继续探讨的话题:
如何将CSS自定义属性运用于Web组件中,来构建一个复用性,灵活性和可扩展性更强的Web组件。
设计稿中的组件
接下来先拿一个最简单的组件来举例。在讲故事之前,我们先来看设计稿中对某个组件的理解,比如 按钮(即 Button
) :
从Sketch设计面板上可以看到,对按钮在UI上有影响的属性,如果拿CSS来对比的话,可能会有:
- 宽度 ─➤
width
- 高度 ─➤
height
- 边框 ─➤
border
- 圆角 ─➤
border-radius
- 阴影 ─➤
box-shadow
- 背景 ─➤
background
(可能是background-image
,也可能是background-color
) - 字体 ─➤
font
(比如font-size
) - 文本颜色 ─➤
color
其中一些属性是用于UI风格(比如 border-color
、 color
、 background
和 box-shadow
),一些属性是用于UI大小(比如 width
、 height
、 border-width
和 font-size
)。如果我们把这些都声明成一个自定义属性(可灵活调整):
--backgroundColor: #F2F3F7 --borderColor: #C4C6CF --borderRadius: 3px --fontSize: 16px --color: #333 --padding: 5px 10px
CSS Framework中的UI组件
在社区中 CSS Framework 有很多,比如大家熟悉的 Bootstrap 就是其中之一,就我个人而言一直喜欢这个CSS框架。在Bootstrap中有很多UI组件,同样拿按钮来举例:
就上图而言,整个Bootstrap在设计UI组件的时候也采用了一些CSS方法论。 2019年的CSS报告中统计了社区中常用的一些CSS方法论 :
有关于2019年CSS报告中更有趣的东西,可以阅读《 从9102年的CSS状态报告中看CSS特性的使用 》一文。
Bootstrap中就使用了OOCSS的相关特性。比如按钮他有一个基类 btn
,然后有一个扩展类 btn-primary
:
.btn { display: inline-block; font-weight: 400; color: #212529; text-align: center; vertical-align: middle; user-select: none; background-color: transparent; border: 1px solid transparent; padding: .375rem .75rem; font-size: 1rem; line-height: 1.5; border-radius: .25rem; transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out; } .btn-primary { color: #fff; background-color: #007bff; border-color: #007bff; }
其他风格的按钮也是采用类似方式实现的。可以说,这种设计UI组件的方式是个古老的方式。
如果你对CSS方法论感兴趣的话,可以花点时间阅读《写CSS的姿势》一文。
CSS自定义属性给UI组件带来的变革
这些年CSS的技巧在不断的革新,特别是近几年,可以说是一种飞跃性的发展。其中CSS 自定义属性的进展就足以令我们目瞪口呆, 发展神速 。
CSS的自定义属性给UI组件的设计带来更多的灵活性。
从设计软件中我们可以获知,设计的任何UI组件,都有很多参数可以用来控制组件的样式风格,比如说大小,皮肤等。而这些参数就可以和CSS自定义属性匹配起来。
继续拿 Button
来举例,我们可以在基类中声明按钮UI所需的参数,比如:
.button { // 声明CSS自定义属性 --backgroundColor: #fff; --borderColor: #ccc; --borderRadius: 5px; --fontSize: 16px; --color: #333; --padding: 5px 10px; // 按钮的基本样式 display: inline-flex; justify-content: center; align-items: center; // 调用CSS自定义属性 background: var(--backgroundColor); border: 1px solid var(--borderColor); color: var(--color); font-size: var(--fontSize); padding: var(--padding); border-radius: var(--borderRadius); }
效果如下:
其中 --padding
、 --fontSize
用来控制按钮大小; --backgroundColor
、 --color
、 --borderColor
和 --borderRadius
用来控制按钮的皮肤。如果我们需要其他风格的按钮时,我们可以这样使用:
// CSS .primary { --backgroundColor: #007bff; --borderColor: #007bff; --color: #fff; } .danger { --color: #fff; --backgroundColor: #dc3545; --borderColor: #dc3545; } .large { --padding: .5rem 1rem; --borderRadius: .3rem; --fontSize: 1.25rem; }
看到上面的示例,你可能会问为什么不显式的设置 width
和 height
来控制按钮的大小呢?就我个人经验来说,能不显式设置 width
和 height
来控制元素大小就尽量不要使用,就算是要设置,也更应该考虑 min-width
和 min-height
这样的属性。另外在CSS中,还有更为灵活来控制元素在大小的属性,即 min-content()
、 max-content()
和 fit-content()
函数和 fill-available
( width
的一个属性值)等。有关于这几个函数的使用可以阅读W3C的 CSS Intrinsic & Extrinsic Sizing Module Level 3 规范或者@张鑫旭大师的《 理解CSS3 max/min-content
及 fit-content
等 width
值 》一文。
另外为了更好的向大家演示CSS自定义属性给UI组件带来的灵活性和可维护性,下面一个示例,借助CSSOM中的 CSSStyleDeclaration
中的 setProperty()
和 getPropertyValue()
方法来重构一个CSS自定义属性构建的UI组件:
操作右侧表单项,就可以轻易的控制按钮的样式风格:
CSS自定义属性在Vue组件中的应用
时至今日,仅基于CSS来构建UI的场景越来越少了。随着类似Vue和React这样的优秀框架的诞生,在组件构建方面大部分都基于这两大体系。接下来就和大家一起探讨CSS自定义属性怎么在JavaScript框架中来构建组件。
同样拿 Button
组件来举例。在Vue的项目中构建一个 Button
组件,在样式的构建和维护上同样使用CSS自定义属性:
// Button.vue