Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS styling conflict prevention and namespacing techniques

Say you're building a conceptual widget named Awesome Widget and you want to completely protect it from conflicting with either surrounding elements or child elements that reside as content inside the widget.

What we don't want

div ul li {}

Solution 1: CSS child combinator

Using the CSS child combinator selector to specify that only direct children should be targeted.

.awesomewidget > div > ul > li {}

Solution 2: class namespacing

Using aw (Awesome Widget) as the namespace for each class, decreasing the chance of any other elements on the page using that exact namespace + classname.

.awesomewidget .aw-container .aw-list .aw-listitem {}

There's also something like @namespace in CSS but that's only for XML.

Besides solution 1 and 2, are there any others that can be used? Which one would you prefer? Any best practises?

EDIT: example of a problem that arises without proper namespacing / styling conflict prevention

Widget styling:

.awesomewidget > div ul li {
background-color:red;
}

User styling:

ul li {
background-color:blue;
}

Markup:

<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>
like image 332
DADU Avatar asked May 25 '11 16:05

DADU


People also ask

How can CSS conflict be prevented?

You need to keep the widget CSS rules as self-contained as possible, which means that you will need to specify every property that is critical to you design, and make sure that properties like float: none , position: static and so on are explicitly set.

How is the conflict among multiple style sheets resolved?

To resolve such conflicts, you have CSS Cascade. The CSS Cascade is a way for browsers to resolve conflicting CSS declarations. By specifying CSS rules, you specify where the CSS style is added to the cascade hierarchy. The further down a hierarchy a declaration falls, the less likely it will end up as the final style.


3 Answers

I would prefer to use a combination of the two solutions like:

.awesomewidget > div ul li {}

Because the second one adds a LOT of unecessary weight to the markup.

Update

For your example, I would add a wrapper around the user content with class .user and then prepend their CSS with .user. However, this is not graceful, it adds some markup, and I think it would be prone to failure.

like image 92
rockerest Avatar answered Oct 20 '22 00:10

rockerest


XBL might help if it ever gets implemented in browsers as it has ways of designing widgets which can avoid passing on styling information.

Another advantage, btw, to including the child combinator is performance. It does not need to check all levels of possible children to determine how to render.

But if you're going to do class-namespacing for brevity, two at most should be enough I would think, unless you're not naming distinctly enough:

.awesomewidget .aw-listitem {}

You could also give a container (with a well namespaced class) to the non-user content section(s) at the highest level possible which does not enclose the user content, saving yourself from that risk. <div/> is pretty handy for that kind of arbitrary grouping and made for that purpose...

like image 27
Brett Zamir Avatar answered Oct 19 '22 23:10

Brett Zamir


If you're experiencing many CSS namespacing conflicts, maybe it's time to consider switching to a front-end JS framework like Facebook's ReactJS. This, in conjunction with Webpack Module Loader, will allow you to leverage many fine JS libraries that will streamline your development workflow. CSS-loader, for example, will help you manage your CSS development by doing local scoping, which is just what you're looking for.

like image 23
e18r Avatar answered Oct 19 '22 22:10

e18r