7

As far as I know there are two types of CSS namespacing:

Prefix one:

.myapp-alert {...}

and class one:

.myapp .alert {...}

Which one is preferable? Does one has benefits over the other one? Are there any other?

12

There are no namespaces in CSS. All you do in CSS ends up in global scope. This is by design.

This leads to two problems:

  • What happens to the apps using my library if, in the library, I introduce a given style?

  • What happens to other parts of my 100M-LOC app if I introduce a given style in the part I'm working on?

Those are two distinct situations, which can be handled with two distinct techniques you described in your question.

Prefixes work well for libraries and frameworks. If a framework has an alert icon, this icon may appear anywhere in the page. Thus, you can't just scope the style to a particular element (through class/id selector). This leads, indeed, to the selectors such as:

.my-awesome-framework-icons-alert { ... }

The choice of the prefix is, by the way, important in order to avoid collisions. Popular libraries and frameworks can use small prefixes, knowing that websites that use them will adapt themselves. For instance, a website which uses AngularJS will probably not use ng- prefix for its custom elements. Small libraries, on the other hand, would be better using more esoteric names if they want to be easily integrated within existent projects.

Containers, on the other hand, work well for app components. I don't want all the styles on my About page to be prefixed by about-page-. I would rather create an element <div id="about"> and use that as a scope for the styles which are used on About page only.

Using CSS preprocessors such as LESS, such code avoids much of the duplication compared to prefixes. I simply do:

#about {
    .contact { ... }
    .map { ... }
    ...
}

and let the preprocessor duplicate #about for every relevant style.

  • 2
    Good writeup, one negative about your container approach is that a different framework's .map class could add unwanted styles to #about .map. It really depends on how much you care about protecting against 3rd parties or other internal code on the same page. – pllee Jun 25 '17 at 23:21
  • @pllee good catch. Seems like you still need to prefix your "scopes" too. – Runnick Jun 26 '17 at 6:37
  • @pllee: unless I misunderstood your comment, this is exactly why third party libraries should use prefixes. So not .map, but .one-more-js-lib-map. – Arseni Mourzenko Jun 26 '17 at 11:35
  • @ArseniMourzenko yeah they should but they don't always. Also other "internal" widgets can forget to namespace as well. – pllee Jun 26 '17 at 15:07
  • you shouldn't use IDs github.com/airbnb/css#id-selectors – SandroMarques Apr 2 '18 at 19:45
0

We use BEM (block element modifier) to solve the problems in CSS that namespaces solve in other languages. http://getbem.com/introduction/

  • I don't think BEM solves all the problems, because if other library also uses BEM, it may still break things. You'll probably name things in similar fashion. E.g. if .card .media turns into .card__media it doesn't prevent other developer to name their cards same. – Runnick Jun 26 '17 at 6:38

protected by gnat Apr 2 '18 at 21:25

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.