7

Given an element with some styling and an additional class (mywidget_button--disabled) that works as BEM modifier, does it has sense, as practice, to use the !important clause?

.mywidget__default ~ .mywidget__button {
    border: 1px solid #000;
}

.mywidget__button--disabled {
    border: 1px solid transparent !important;
}

The first class is more specific and wins on the second one, but being the disabling class a modifier that (theoretically) should have more priority than the "common" styling, is it correct to rely on the !important clause?

Or does it make the code prone to spaghetti-headache?

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
Kamafeather
  • 8,663
  • 14
  • 69
  • 99
  • What is _BEM_ modifier – Tushar Sep 22 '15 at 10:34
  • Is a CSS naming style: http://getbem.com/naming/ – Kamafeather Sep 22 '15 at 10:37
  • Probably one of the areas where BEM falls completely apart. It's not a problem unique to BEM, but it's one that it simply doesn't solve. – BoltClock Sep 22 '15 at 10:41
  • BEM is the general approach I'm following and is fine for all my project. Just in some specific cases like this I need to find different approaches. I wonder if avoiding to use _!important_ to solve this would be a correct approach, or if that reduces the maintainability/extendibility respect to try to align the specificity of the two classes. – Kamafeather Sep 22 '15 at 10:46

6 Answers6

3

I personally prefer using BEM with namespaces, and then chaining the temporary states to other classes, which, in turn, increases the specificity.

Harry Roberts from CSS Wizardry has some great resources that cover these more-complicated situations. Namespaces, theming, and general guidelines.

Without seeing your specific project, it's hard to tell what might be the best approach, but either a chained state class, or a utility class — which does allow for !important — should work well. That is, of course, if you choose to take BEM up a notch with these additional techniques.

jabacchetta
  • 45,013
  • 9
  • 63
  • 75
3

There are only two good reasons I can think of for ever using `!important``

  • to over-ride an injected inline style that has come from a 3rd party library over which you have no control, for example, if you've implanted some sort of widget that grabs javascript that in turn makes style changes to your site.

  • during debugging, to assert whether the selector you are editing actual does select what you want it to. You can do something like background: #f00 !important; and be almost certain whether or not you're in right place. Such a declaration has a very high probability of over-riding any mismanaged specificity.

Using BEM you should never have to use !important to control any code you've written. With BEM classes you add one class on everything and have a long list of classes, without nesting, in your css. The name-spacing is unique and there's well defined modularity. The result is that you don't have style leaks and specificity problems which are the primary mistaken reasons for using !important.

Toni Leigh
  • 4,830
  • 3
  • 22
  • 36
1

I think !important is ok. Personally I try not to write to specific as your first rule, if I did, I would probably go with

.mywidget__button.mywidget__button--disabled {
    border: 1px solid transparent;
}
Dejan.S
  • 18,571
  • 22
  • 69
  • 112
  • Thanks. In my case I'm specific because the styling react on eventually slightly different markup, and must be applied just when the _.mywidget__default_ element is present. But yeah I could add an additional class to distinguish better the cases (but the specificity would remain the same; probably adding more specificity to the modifier could be a correct approach (even if it goes a little against what I'm using BEM for). – Kamafeather Sep 22 '15 at 10:43
1

Based on my experience !important can give issues usually when multiple webparts have their own stylesheets. Best practice is to avoid using !important in CSS as it can override other styles, as long as your selectors are specific you shouldn't need to use !important.

Mark
  • 17
  • 6
  • Yes. I wonder if in the case of a BEM modifier (that should be a sort of "final modifier", having BEM no deeper parts than the modifier) it would be ok to use _!important_, being the class some sort of "final state" (that, just theoretically, shouldn't need to be overridden). – Kamafeather Sep 22 '15 at 10:50
1

Of course it's better not to ever have to use !important

The BEM naming convention has to be applied as broadly as possible to avoid having to resolve to that sort of trick.

BEM's main advantage being that it targets elements on a very precise level, it's a bit sad to have to combine it with important!.

In this case I would try to find a solution without .mywidget__default ~ so that .mywidget__button can be declared on its own, but it may not be possible in your case.

Underfrog
  • 1,307
  • 11
  • 14
  • 1
    Yes I agree. Is I'm not sure what would be the best way to solve it. For now the only thing is to dynamically add a class to my *__button* so that it knows when a *__default* element has been rendered before it (regardless is adiacent. Actually the styling is trying to adapt to two different (even if slightly) HTML markups; probably the best solution is to separate the styling in two SCSS mixin and use one or the other depending on the rendered markup. Probably is the more maintainable way, I will reduce the specificity of the first class, and I will not have to rely on _!important_. – Kamafeather Sep 22 '15 at 11:00
1

!important declarations should not be used unless they are absolutely necessary.

I would say don't use it, for example i'm currently adding a disabled button in a warning popup, this button now needs a red border in staid of a transparent one and this would not be possible when i would have a !important on the disabled button

Ivo
  • 2,588
  • 6
  • 25
  • 43
  • Good point. Is exactly what I worry about; future changes that could be prevented from _!important_. And I was wondering if it had any sense or could be "less risky" in the context of a BEM naming. But the answer seems to be: "No, it's not less risky" – Kamafeather Sep 22 '15 at 11:03