DEV Community

Andrea Berardi
Andrea Berardi

Posted on • Originally published at andberry.me

BEM, CSS Namespaces and ITCSS

because writing CSS is easy; looking after it is not.

-- csswizardry

Yes, even though currenly there are lots of tools involved in CSS landscape nowadays, it's a pretty easy language to start with, and due to its design (pitfalls ?) it's also pretty easy to find yourself soon wasting time on deciding classes names and struggling to make your code more maintainable and scalable.

Basically HTML and CSS shares classes (and ids) to shape the final UI and reusing classes being sure to do exactly what you want, where you want, without introducing problems in a totally different part of the ui requires you, developer, to be really accurate/diligent.

Methodologies, naming conventions and architectures help you a lot.

This is what is currently helping me a lot.

BEM

Block Element Modifier is a methodolgy, or a naming convention suggestion that helps you giving classes a role, relationship, responsibilities and states in a clear way.

Definitely a way to save time when deciding class names.

  • Block: the parent, the standalone entity that has a meaning by itself (top level abstraction of your component)
  • Element: a part of the block, without meaning standalont by itself (a child item)
  • Modifier: a flag, a variation, a state to a block or element

Here is an example of BEM applied to a button

<a class="button button--big">
    <span class="button__icon"></span>
</a>
Enter fullscreen mode Exit fullscreen mode
.button {
    display: inline-flex;
    justify-content: center;
    align-items: center;
    border-radius: 6px;
    padding: 8px 12px;
}
.button__icon {
    margin-right: 6px;
    font-size: 0.5rem;
}
.button--big {
    padding: 12px 16px;
    font-size: 20px;
}
Enter fullscreen mode Exit fullscreen mode

CSS Namespaces

How many times have you looked at a piece of HTML only to wonder:

  • which classes do what
  • which classes are related to each other
  • which classes are optional
  • which classes are recyclable
  • which classes can you delete, and so on?

A lot of times, I bet.

A CSS Namespace will tell you exactly how a class behave in a more global sense.

Again, this methodolgy is meant to be used when deciding class names.

ere are the individual namespaces and a brief description.

Object: o-

A class name that starts with "o-" is an Object, an abstract layout implementation. Used in any number of unrelated contexts: tread carefully.

Eg. o-grid, o-sidebar-left

Component: c-

A class name that starts with "c-" is a Component: this is a concrete, implementation-specific piece of UI.

Eg. c-hero, c-card

Utility: u-

A class name that starts with "u-" is a Utility class. It has a very specific role and it can be reused and is not tied to any specific piece of UI.

Eg. u-color-primary, u-text-center

Theme: t-

A class name that starts with "t-" adds a adds a theme to a view. Overrides default style due to the presence of a theme.

Eg. t-light, t-saint-valentine

State: is- / has-

A class that starts with is- or has- indicates that this piece of UI is currently styled a certain way because of a state or condition. Used everywhere, not tighten to specific UI block

Eg. is-active, has-2-items

Javascript Hooks: js-

A class that starts with - js- indicates that this piece of the DOM has some JavaScript binds onto it.

Eg. js-carousel, js-accordion

ITCSS: Inverted Triangle CSS

It helps us to organize our CSS files to better deal with CSS specifics/issues/pitfalls like:

  • global namespace
  • cascade
  • selectors specificity.

At the end, we split CSS properties based on their level of specificity and importance.

Going from top to bottom symbolizes an increase in specificity, and each subsection of the triangle may be considered a separate file or group of files.

My personal implementation:

  • 1-settings: sass variables: font, colors, spacings
  • 2-tools: mixins and functions: bg-image(), abs-center()
  • 3-base: generic + elements, normalize/reset + base html elements style without classes: body, h1, table (this is the first CSS output)
  • 4-layout: (remember objects?) abstract layouts, unstyles patterns: grid, layout-sidebar, media
  • 5-components: style for a specific piece of UI: c-hero, c-footer
  • 6-modules: aggregation of modules: c-cards-list, c-cards-carousel
  • 7-trumps/utilities: utilities and helper classes with ability to override anything which goes before, all CMS specific stuff like base overrides, views, specific page style

Links

Top comments (3)

Collapse
 
avidworks profile image
avidworks

I do something very similar when I'm not using CSS in JS and it's been a game changer. I like using the same prefix in the class names as the names of the folders to make things easier to find. So I do something like:

00-config (theme tokens, custom properties, etc all live here)
01-reset (CSS reset file)
02-global (global styles -- things like anchor tags, body, etc. No custom classes live here.)
03-blocks (generic layout components... prefixed with b-, so b-container, etc.)
04-components (ui components like buttons... prefixed with c-, so c-button, etc.)
05-pages (css specific to pages, i.e. a hero section on a homepage)
06-utilities (utility classes that don't require their own class... prefixed with u-, so u-centered, etc.)
07-vendor (any third party CSS)

I really like the idea of the state prefix, I'll have to mark that one down to start utilizing.

Collapse
 
darkwiiplayer profile image
𒎏Wii 🏳️‍⚧️

I hate BEM with a passion, but somewhat like the namespace idea. But in the end I still think proper naming can make namespaces / prefixes mostly redundant. A class like grid is obviously a layout, and hero is also pretty self-explanatory.

Collapse
 
adam_cyclones profile image
Adam Crockett 🌀 • Edited

Way back before scoping, I used to use ECSS a rather nice user friendly specification and a great book, there's stuff to learn from it.

The pattern they choose uses a namespace but only to group related components and allow for a search with 3 chars

.nsp-Component_Varient
Enter fullscreen mode Exit fullscreen mode

I still use a namespace for the search besides it's really fun to think of silly abbreviations

crt = cart
brd = breadcrumb
shp = shop
hmm = well you get the idea