Using BEM CSS with Angular Directives

I use BEM style CSS to style my angular directives and usually use replace: true so that my block level class can be at the "root" of the custom element. This makes it so that I can write all my CSS mostly using classes.

However, replace: true sometimes causes problems (with two ng-ifs, etc.) and is now deprecated. So I start to try to stay away from replacement.

But now I'm having trouble applying BEM to these elements that have an actual custom DOM tag - now I need to use the tag name instead of the class name, which means I can't use BEM anymore (since I have to use the tag name since I can't apply classes directly to my template element). Also, using modifiers on my custom element now seems impossible, just like using CSS selectors for sibling.

Here's an example that will hopefully illustrate what I mean:

Directive:

angular.module('my.module')
  .directive('customElement', function() {
    return {
      restrict: 'E',
      scope: {
        isSpecial: '='
      },
      template: '<div class="custom-element" ng-class="{\'custom-element--special\': isSpecial"></div>'
    };
  });

      

CSS:

.custom-element {
  background-color: white;
}

.custom-element--special {
  background-color: red;
}

.custom-element--special + .custom-element--special { // this won't work without replace: true
   background-color: blue;
}

      

If I use replace: true everything works as expected (but then it has its own headaches).

If I don't use replace, the classes are not applied to the root custom element, so the child selector doesn't work.

I could always add classes to an element in the postLink function, but that makes the template less clear.

Does anyone have any experience using BEM with angular and using classes instead of tag names in your custom directives? What have you done to solve this problem?

+3


source to share


1 answer


I knew the problem was replace:false

for readability purposes.

The actual problem is that we need OOCSS , but you are handling Angular. Components with custom tags have CSS objects and that's not the case.

There is no practical solution for this, I will not recommend that you add classes to a function postLink

.

However, what we need to do is treat the custom tag as a native CSS object, apart from the internal structure of the object. Forcing us to inject an additional CSS class for the custom tag.



block-context
  block-context__element 
    custom-element

      

Why do this when it block-context__element

is redundant?

  • Since the rest of your BEM structure is the one you will maintain, the block custom-element

    must have a value using self and the element is block-context__element

    not expected, you must abstract the CSS objects from the directive implementation if you start changing your html components at some point , your classes should still apply.

I hope this answer helps you

0


source







All Articles