假设您正在构建一个名为Awesome Widget的概念窗口小部件,并且您希望完全保护它不会与作为窗口小部件内容作为内容的周围元素或子元素冲突。
我们不想要的
div ul li {}
解决方案1:CSS子组合器
使用CSS子组合子选择器指定只应针对直接子项。
.awesomewidget > div > ul > li {}
解决方案2:类命名空间
使用aw(Awesome Widget)作为每个类的命名空间,使用精确的命名空间+ classname减少页面上任何其他元素的可能性。
.awesomewidget .aw-container .aw-list .aw-listitem {}
在CSS中也有类似@namespace的东西,但这只适用于XML。
除了解决方案1和2,还有其他可以使用的解决方案吗?你更喜欢哪一个?任何最佳做法?
编辑:没有适当的命名空间/样式冲突预防而出现的问题示例
小部件样式:
.awesomewidget > div ul li {
background-color:red;
}
用户造型:
ul li {
background-color:blue;
}
标记:
<div class="awesomewidget">
<div>
<ul>
<li>
<!-- user content starts here -->
<p>I am the user and I want to add some content here. Let's add a list:</p>
<ul>
<li>Why is this list-item red and not blue?</li>
</ul>
<!-- user content ends here -->
</li>
<li>
<!-- user content starts here -->
<!-- user content ends here -->
</li>
</ul>
</div>
</div>
我更喜欢使用两种解决方案的组合,如:
.awesomewidget > div ul li {}
因为第二个会给标记增加很多不必要的重量。
对于您的示例,我将使用类.user
在用户内容周围添加一个包装器,然后使用.user
添加其CSS。但是,这并不优雅,它增加了一些标记,我认为它很容易失败。
XBL可能会有帮助,如果它在浏览器中实现,因为它有设计小部件的方法,可以避免传递样式信息。
包括儿童组合器在内的另一个优点是性能。它不需要检查所有级别的可能子级以确定如何呈现。
但是如果你为了简洁而打算使用class-namespacing,那么我认为最多两个就足够了,除非你没有足够明确地命名:
.awesomewidget .aw-listitem {}
您还可以向最高级别的非用户内容部分提供一个容器(具有良好的命名空间类),该部分不包含用户内容,从而避免了这种风险。 <div/>
对于那种任意分组非常方便,并为此目的而制作......
如果你遇到很多CSS命名空间冲突,也许是时候考虑切换到像Facebook的ReactJS这样的前端JS框架。这与Webpack Module Loader一起,将允许您利用许多优秀的JS库来简化您的开发工作流程。例如,CSS-loader将帮助您通过执行local scoping来管理您的CSS开发,这正是您正在寻找的。
以下是几个解决方案: