SAP Spartacus 的 CSS 架构
在 Angular 中,组件的 CSS 样式被封装进了自己的视图中,而不会影响到应用程序的其它部分。
通过在组件的元数据上设置视图封装模式,你可以分别控制每个组件的封装模式。 可选的封装模式一共有如下几种:
ShadowDom 模式:使用浏览器原生的 Shadow DOM 实现,可以参阅 MDN 上的 Shadow DOM 文档来为组件的宿主元素附加一个 Shadow DOM。
组件的视图被附加到这个 Shadow DOM 中,组件的样式也被包含在这个 Shadow DOM 中。
记忆方式:不进不出,没有样式能进来,组件样式出不去。)
Emulated 模式(默认值)通过预处理(并改名)CSS 代码来模拟 Shadow DOM 的行为,以达到把 CSS 样式局限在组件视图中的目的。
只进不出,全局样式能进来,组件样式出不去。
你可以使用同样的方式来操作 Shadow DOM,就和操作常规 DOM 一样——例如添加子节点、设置属性,以及为节点添加自己的样式(例如通过 element.style 属性),或者为整个 Shadow DOM 添加样式(例如在 style 元素内添加样式)。不同的是,Shadow DOM 内部的元素始终不会影响到它外部的元素(除了 :focus-within),这为封装提供了便利:
注意,不管从哪个方面来看,Shadow DOM 都不是一个新事物——在过去的很长一段时间里,浏览器用它来封装一些元素的内部结构。以一个有着默认播放控制按钮的 元素为例。你所能看到的只是一个 标签,实际上,在它的 Shadow DOM 中,包含来一系列的按钮和其他控制器。Shadow DOM 标准允许你为你自己的元素(custom element)维护一组 Shadow DOM。
那么,SAP Spartacus 使用了本文目前为止提到的这些 Shadow DOM 机制了吗?
先了解 SAP Spartacus CSS 的设计原理。
Spartacus 作为一组标准组件提供,这些组件分布在 npm 库中。 这些库有助于确保 Spartacus 同时保持可扩展性和可升级性。
为了提供尽可能多的样式灵活性,所有 CSS 规则都在单独的 @spartacus/styles 库中提供。 这使得样式完全可选、可配置和可扩展。 您可以扩展或替换标准样式,也可以实现您自己的样式规则。
此外,现有的 UI 框架(例如 Bootstrap)可以在 Spartacus 中使用,而不会使其成为硬编码依赖项。
SAP Spartacus Style 版本机制
Spartacus 库支持语义版本控制,这意味着在主要版本的生命周期中不允许进行重大更改。对于样式库也是如此。会导致 UI 体验差异的新样式规则或调整后的规则被视为重大更改。Spartacus 库的发布假设客户依赖于语义版本控制方案,因此在主要版本的生命周期中不会进行重大更改,例如对样式库的隐式更改。
同时,Spartacus 很可能会从一个小版本进化到下一个。为允许样式层中的逐渐更改,为特定版本添加了新的或调整后的样式规则,但除非您明确选择接收这些更改,否则这些更改不会添加到样式构建过程中。您需要设置一个变量以利用最新的突破性样式更改。请注意,无论如何都会添加非破坏性更改。
以下示例说明了 2.2 版的附加样式:
cx-mini-cart { @include forVersion(2.1) { background: blue; } @include forVersion(2.2) { background: deepskyblue; }}
SAP Spartacus CSS 技术
Spartacus 是结合以下 CSS 技术开发的:
SASS,用作预处理语言,就像在当今大多数 UI 框架中一样。
CSS 自定义属性,用于全局主题。
CSS post 处理,旨在用于填充旧浏览器所需的任何语法。
SAP Spartacus 并未使用本文之前介绍的任何一种 Shadom DOM 实现技术。Angular 的模拟封装无法使用,因为组件样式是由样式库提供的。 BEM 被认为是老式和复杂的。 此外,定义明确、细粒度的组件架构不需要 BEM 来封装样式。
全局主题
全局主题是用变量组织的,因此主题不是硬编码的。 对于变量,您可以使用两种常用方法:
SASS 变量
CSS 自定义属性(换句话说,CSS 变量)。
Spartacus 使用 CSS 变量进行主题化。 CSS 变量具有运行时可配置的优点。 而且,它们可以穿透shadow DOM(即web组件)。 此外,CSS 变量是继承的,并且比 SASS 变量提供更大的灵活性。
主题变量有助于 Spartacus 向客户提供的所谓“合约”。 该合约旨在保持稳定,并且应该很少更改。只有在主要版本中,Spartacus 才能引入一组新变量,但这不被视为最佳实践。
为了提供一组稳定的变量,Spartacus 中的 CSS 变量主要用于配色方案和字体定义。 这些可以被认为是一组全局主题定义。
下面是 css 变量的一个例子:
:root { --cx-color-primary: red;}cx-link { color: var(--cx-color-primary);}
CSS 变量可以在文档的根或特定的选择器上进行定制。
Component Styles
Spartacus 包含大量可用于构建店面体验的组件。虽然商业可能是一种商品,但造型本质上是一个主观主题。不仅是颜色和字体的选择,还有组件的空间,以及背景、线条等。
无论 Spartacus 提供什么,它都不能代表您的品牌或企业形象。出于这个原因,Spartacus 具有高度的灵活性,因此您可以扩展组件样式,或者完全跳过它们。
由于 Spartacus 组件是在库中构建和分发的,因此无法使用组件样式, 因为 Component 和 style 的定义,在 Spartacus 里是分开的。这些样式将被预处理并烘焙到组件库中。这意味着 CSS 规则不是可选的,也不是很容易定制的。
取而代之的是,在样式库中可选择提供组件样式。您可以使用这些样式、扩展它们或完全跳过它们并从头开始构建 CSS 规则。样式库和组件库之间的契约是通过(唯一的)组件选择器完成的。
Placeholder Selectors
为了使样式库中提供的 CSS 规则完全可选,样式被包装在占位符选择器中。 占位符选择器是一种以百分比开头的 SASS 技术,例如 %cx-mini-cart。 占位符选择器不会添加到最终的 CSS 中。相反,它们需要显式被扩展,以最终出现在最终的 CSS 中。
以下是使用占位符选择器的组件样式示例:
%cx-link { a { display: inline; padding: 0; margin: 0; color: currentColor; display: block; }}
虽然可以安全地导入占位符选择器,但只有明确使用它才会影响最终的 CSS。
这些占位符选择器,只有被真正的扩展时,才会出现在最后的 css 里。
因此,样式可以扩展如下:
cx-link { @extend %cx-link !optional; a { color: red; }}
!optional 的含义:
可选标志确保代码不会在构建期间中断,只要特定导入不是导入样式的一部分。
Spartacus 通过迭代配置的组件选择器来生成组件。
Skipping Specific Component Styles
组件样式是可选的,因为它们是从样式库中提取的。 因此,您可能希望完全禁用某些标准组件样式。 要禁用标准组件样式,您可以将组件选择器添加到 $skipComponentStyles 列表。 以下是演示从样式库中跳过两个标准组件的示例:
$skipComponentStyles: (cx-product-carousel, cx-searchbox);
如果您需要从头开始创建样式并且不想覆盖来自 Spartacus 样式库的特定样式规则,则跳过特定的组件样式可能会有所帮助。
Page Layout Styles
全局主题和组件样式对于在页面上呈现组件最重要。 但是,在页面上编排组件的整体布局是另一个重要的样式层。 有关此图层的更多信息,请参阅页面布局。