-2

I'm re-evaluating the effectiveness of my CSS design choices after reading about SMACSS.

One of the conflicts I've examined is:

<button class="cool-text button"></button>

Semantics aside, the object in question has two classes which do not extend each other in anyway. Now, if the CSS were:

.cool-text {
    background-color: black; // want this
    color: green; // don't want this
    font-size: 16px;
    text-shadow: 0 1px 0 yellow;
}

.button {
    background-color: white; // don't want this
    border: 1px solid;
    border-radius: 4px;
    color: #eee; // want this
}

Once again, this is not an ideal example. I was wondering, what if I wanted the background-color from .cool-text and the color from .button. In a programming language, an object can have two classes, and you can specify how to resolve conflicts in method names. I guess similarly, I could specify .cool-text.button, but I would have to re-write the properties, which seems very bad.

.cool-text.button {
    background-color: black;
    color: #eee;
}

Are there any workarounds using SCSS?

Also, is it a bad idea to rely on the positions of the classes within the class attribute (in vanilla CSS). Classes that are specified first have higher priority, for instance:

<button class="green-button button"></button>

In this example, .green-button has higher precedence.

This seems to add CSS specificity to HTML. What if there were lots of classes, you would have to spend time figuring out which ones should go first and that seems very counter-intuitive.

Per Quentin, it's determined by the order within CSS.

John Smith
  • 1,750
  • 3
  • 18
  • 31
  • is cool-text limited to buttons? if not, the you can change their order in the CSS file where they are defined. `.button` seems more general and should be on top – Ibu Jul 22 '15 at 23:17
  • 2
    "In this example, .green-button has higher precedence." — No, it doesn't. Class order in HTML is irrelevant (unless you're writing weird attribute selectors). Specificity is determined only by the stylesheet. – Quentin Jul 22 '15 at 23:17
  • @Quentin hm let me test, how then is it defined? nvm, it's probably defined by it's order in the css. – John Smith Jul 22 '15 at 23:18
  • 1
    https://drafts.csswg.org/css2/cascade.html#cascading-order – Quentin Jul 22 '15 at 23:19
  • Would using !important work in this scenario? – ydobonebi Jul 22 '15 at 23:20
  • @QuinnRoundy And what if I extended .button and tried to change the property marked as !important? `.button { color: #eee !important; } .cool-button { @extend .button; color: blue; }` – John Smith Jul 22 '15 at 23:21
  • @Ibu Doesn't that add complexity to the stylesheet? That seems counter-intuitive. I don't think logic should be based on the position of the CSS, I would have to add a comment to that class that says "this has to be above .green-button". – John Smith Jul 22 '15 at 23:24
  • @JohnSmith Admittedly I don't use extend that often, but from my limited understanding, .cool-button should keep it's color property, .button would keep its property. Where both are used I believe the important will keep. So a button with class="button cool-button" will be color: #eee. Would be worth trying out and seeing how different browsers handle this. – ydobonebi Jul 22 '15 at 23:30
  • I also found this useful, I think it does explain stuff better than even what I understand : https://css-tricks.com/the-extend-concept/ – ydobonebi Jul 22 '15 at 23:32
  • @QuinnRoundy I didn't have to use @extend in that example. It could just be OOCSS: `.button {} .cool-button {}` where .cool-button has precedence over .button (as it should be, it appears later in the CSS). The point is that if you wanted to use .button as a base class, you would not be able to change it's color unless you used `!important` in sub-classes which is a slippery slope. – John Smith Jul 22 '15 at 23:34
  • I don't know why this is tagged sass, this is not a Sass problem: Sass only compiles to CSS. – cimmanon Jul 23 '15 at 01:13
  • You should write your CSS differently. For example: apply styles as you want them via element selectors, and then for special cases, add a class. – TylerH Jul 23 '15 at 01:35

1 Answers1

1

It all depends on the rule specificity and order.

Your solution makes perfect sense to me, because your original idea is not ideal (taking x from class1 and y from class2, yet the classes are parallel). However, if you end up writing too many of those exception rules, like:

.cool-text.button {
    background-color: black;
    color: #eee;
}

it means something's not quite right with your design. Why simply not design a cool-button class then? If your .button is meant to be one of the base classes, put it on the top of the CSS file, let the other (more specific) classes override it easily.

Also, please refrain from using !important unless absolutely necessary.

See this nice specificity calculator: http://specificity.keegan.st/

Community
  • 1
  • 1
Shomz
  • 37,421
  • 4
  • 57
  • 85
  • Using !important is never necessary :P unless you have a demo with a client in an hour. Thanks for answering, I will continue to look into an easy way to implement this in SCSS. This problem is true to any situation where 2 selectors have the same precedence. – John Smith Jul 22 '15 at 23:35
  • And if the client uses a terrible plugin that relies on `!important`! ;) Yup, CSS is not really meant to be used like that in parallel, try restructuring your classes, or simply make new ones where needed, but you should never rely on parallel classes. – Shomz Jul 22 '15 at 23:37