保护库组件不被消费者设计样式的标准方法

问题描述 投票:0回答:2

我正在 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 angular scope
2个回答
2
投票

基本上,我如何以一种限制消费者的方式使用 CSS 当类名冲突时破坏东西?

我认为更重要的是尝试防止类名冲突,而不是处理发生冲突时发生的情况。如果存在冲突,假设选择器具有相同的 specificity 最后定义的样式将获胜。因此,取决于消费者是在他们自己的样式之前还是之后添加您的库,这将影响适用的冲突规则。如果您认为您的库非常重要,您可以将 !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;
}

0
投票

根据我的经验,构建组件库依赖于在易于定制和保护组件库样式之间取得平衡。 我会说对于图书馆来说,使用前缀几乎总是一个好主意。 我也同意 ryanm 的观点,使用

!important
不是一个好主意,它在大多数情况下不允许自定义任何样式。

在我的案例中,库是一些使用它的项目的关键/核心部分。 这就是为什么我和我的同事决定使用 Sass 来设计样式,并方便地将我们所有的类选择器嵌套在父 ID 选择器中,这样可以提高特异性,但不会为我们做太多额外的工作。

此外,当我们为我们的组件设置文本样式时,我们尝试将样式设置得尽可能低,例如,如果我想使用类

<a>
div
内的所有
myParentName
标签设置样式,我会这样做:

.myParentClass a {
    color: red;
}

代替

.myParentClass {
    color: red;
}

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

.myParentElement > div,
.myParentElement *
© www.soinside.com 2019 - 2024. All rights reserved.