保护库组件不被使用者设置样式的标准方法



我正在用 Angular 构建一个 UI 库,并且经常指定要用通用类(如.slider.form-control(设置样式的元素。 我遇到的问题是,有时使用者(使用库(对自己的元素使用相同的类,当他应用样式时,无意中破坏了库的 UI。

Angular 确实提供了作用域类,因此,例如,如果我有样式:

.form-control { line-height: 2em; }

然后在运行时,Angular 对其进行了修改以动态添加组件特定的属性:

.form-control[ng_content0] { line-height: 2em; }

而且由于该属性是动态添加到元素本身的,因此我的样式不会流失并影响使用库的客户端的元素。

真棒。 但是如何防止相反的情况呢? 基本上,我如何使用CSS,以限制使用者在类名冲突时破坏事物? 我唯一想到的是为所有类名加上前缀。 某种卡顿的命名空间:

.mylib_form-control { line-height: 2em; }

正确的方法是什么?

基本上,我如何以限制消费者的方式使用 CSS 当类名冲突时打破事物?

我认为更重要的是尝试防止类名冲突,而不是处理如果有冲突会发生什么。如果存在冲突,假设选择器具有相同的特异性,则最后定义的样式将获胜。因此,根据使用者是在自己的样式之前还是之后添加您的库,这将影响将适用的冲突规则。如果您认为您的库非常重要,则可以将 !important 添加到所有库样式中。这是个坏主意。你应该尽量避免冲突。

你也许可以为所有类添加一个前缀,比如beetle-ui,我假设消费者没有任何以此开头的类。

你可以做一些类似语义UI的事情,并且为了使HTML元素采用库的样式,它必须在它的类列表中具有类ui。然后,所有选择器都如下所示:

.ui.input {
}
.ui.header {
}

相应的 HTML 如下所示:

<input class="ui input" />

我会做一些像我的第一个示例一样的事情,并使用 BEM 并使用 SASS 定义我的 CSS,这样我的语法就可以更简洁一点并从前缀中受益。

.beetle-ui-form {
background-color: grey;
&__input {
outline: red;
}
}

这将生成如下 CSS:

.beetle-ui-form {
background-color: grey;
}
.beetle-ui-form__input {
outline: red;
}

根据我的经验,构建组件库依赖于自定义的便利性和保护组件库样式之间的平衡。 我想说的是,对于库来说,使用前缀几乎总是一个好主意。 我也同意ryanm的观点,即使用!important不是一个好主意,在大多数情况下,它不允许自定义任何样式。

就我而言,库是使用它的一些项目的关键/核心部分。 这就是为什么我和我的同事决定使用 Sass 进行样式设置,并方便地将所有类选择器嵌套在父 id 选择器中,这带来了规范性,但不会为我们做太多额外的工作。

此外,当我们为组件设置文本样式时,我们尝试尽可能低地设置样式,例如,如果我想使用类myParentNamediv内设置所有<a>标签的样式,我会这样做:

.myParentClass a {
color: red;
}

而不是

.myParentClass {
color: red;
}

除此之外,我们创建了一个仅包含大约 5 个点的简短文档,以帮助开发人员使用我们的库,这样他们就不会意外地覆盖任何样式,而是故意的。 因此,警告他们可能是一个好主意,例如,在某些场合不要使用下面这样的选择器,因为它们可能会影响库样式:

.myParentElement > div,
.myParentElement *

最新更新