Disclaimer: This is just a thought about a different approach. I am by no means saying that this approach is better than anything else. :)

At first, I was intending to write some long-drawn blog post about how you can use a few Sass mixins to create a vocabulary abstraction that would allow a different, possibly more expressive way of writing BEM-classes. Instead, here's the short-form.

Update: I've updated the mixins, you can view them here.

If you didn't know already, you can write BEM in .sass (not .scss, sorry), like this:

  // import 'expressive mixins' from /andersschmidt/pen/MYZqar

// Example A: The classic media object
+new (media, object)
  +has (image)
    +when (reversed)
  +has (body)

// Example B: The person OOP example from CSS Wizardry
+new (person)
  +has (hand)
    +when (left)
    +when (right)

    +if-its (open)
    +holds (ring)

  +when (female)
    +has (hand)

// Example C: The puppet, using more classic OOP, 
// thanks to @zerratar for an awesome way of explaining OOP 
// in terms of puppets and puppetmasters
+new (puppet)
  +has (head)
  +has (face)
  +has (arm)
    +when (left)
    +when (right)
  +has (leg)
    +when (left)
    +when (right)
    +when (wooden)
  +has (foot)

// Example D: Menu with menu items that can have a dropdown
+new (menu, component)
  +has (item)
    +when (active)
    +holds (dropdown)

// Example E: Modal with title, gallery modifier and open state
+new (modal, component)
  +has (title)

  +when (gallery)

  +if-its (open) // translates to is-open

Which produces this CSS:

  .media-object {
  /* */
}
.media-object__image {
  /* */
}
.media-object__image--reversed {
  /* */
}
.media-object__body {
  /* */
}
.person {
  /* */
}
.person__hand {
  /* */
}
.person__hand--left {
  /* */
}
.person__hand--right {
  /* */
}
.person__hand.is-open {
  /* */
}
.person__hand.holds-ring {
  /* */
}
.person--female {
  /* */
}
.person--female__hand {
  /* */
}
.puppet {
  /* */
}
.puppet__head {
  /* */
}
.puppet__face {
  /* */
}
.puppet__arm {
  /* */
}
.puppet__arm--left {
  /* */
}
.puppet__arm--right {
  /* */
}
.puppet__leg {
  /* */
}
.puppet__leg--left {
  /* */
}
.puppet__leg--right {
  /* */
}
.puppet__leg--wooden {
  /* */
}
.puppet__foot {
  /* */
}
.menu-component {
  /* */
}
.menu-component__item {
  /* */
}
.menu-component__item--active {
  /* */
}
.menu-component__item.holds-dropdown {
  /* */
}
.modal-component {
  /* */
}
.modal-component__title {
  /* */
}
.modal-component--gallery {
  /* */
}
.modal-component.is-open {
  /* */
}


If you have these .sass mixins classes:

  // --------------------------------------------------
// Vocabulary mixins (for BEM and namespacing)
//---------------------------------------------------
=new ($name, $type: null)
  @at-root
    @if $type != null
      .#{$name}-#{$type}
        /**/
        @content
    @else
      .#{$name}
        /**/
        @content

=if-its ($state)
  &.is-#{$state}
    /**/
    @content

=holds ($something)
  &.holds-#{$something}
    /**/
    @content

=has ($name)
  @at-root
    #{&}__#{$name}
      /**/
      @content

=when ($name)
  @at-root
    #{&}--#{$name}
      /**/
      @content

It's just a different way of writing the same thing. I don't know if I particularly love this approach, but when I'm writing my CSS in this way it feels strangely "in tune" with my own mental model.

Stay sharp!


12,857 14 57