2

How do I get rid of the !important tag in the following example?

<html><head><style>

  .class1.class2::after {
    content: ".class1.class2";
  }
  .class3::after {
    content: ".class3" !important;
    /* how do we make this higher priority without "!important"? */
  }
  

td {padding-right: 20px;}

</style></head>
<body>

<table>
<tr><td>class1 class2</td><td><div class="class1 class2"></div></td></tr>
<tr><td>class1 class2 class3</td><td><div class="class1 class2 class3"></div></td></tr>
</table>

</body></html>

I am aware of 3 rule precedence mechanisms in CSS:

  1. Specificity. The issue with the above example is that according to the browser's specificity algorithm, .class1.class2 is considered more "specific" than .class3. So specificity is not a good fit here, since the browser invents an illogical relationship between .class1.class2 and .class3.

  2. Declaration order appears not to work either: since specificity takes precedence over declaration order, it does not matter what order the rules are written in.

  3. !important. But it is frowned upon (if you can educate me on why it's frowned upon, that might give us some insight). Can I avoid !important if I want .class3 to take higher precedence in the example above?

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
personal_cloud
  • 3,943
  • 3
  • 28
  • 38

2 Answers2

3

As you've already mentioned, it comes down to Specificity. You can modify your CSS to make the .class3 entry more specific and add-on the original selector .class1.class2.class3::after, .class3::after.

.class1.class2.class3 will override .class1.class2 because the former contains the latter.

I think that !important is frowned upon purely because it's seen like a bit of a hack/workaround to force a particular style in the absence of properly formatted and written CSS.

<html>

<head>
  <style>
    .class1.class2::after {
      content: ".class1.class2";
    }
    
    .class1.class2.class3::after,
    .class3::after {
      content: ".class3";
    }
    
    td {
      padding-right: 20px;
    }
  </style>
</head>

<body>

  <table>
    <tr>
      <td>class1 class2</td>
      <td>
        <div class="class1 class2"></div>
      </td>
    </tr>
    <tr>
      <td>class1 class2 class3</td>
      <td>
        <div class="class1 class2 class3"></div>
      </td>
    </tr>
  </table>

</body>

</html>
Jordan
  • 1,390
  • 2
  • 9
  • 24
  • Thank you, this approach seems to work well. The browser still finds the containment relation, even if I expand the first rule to, say, `.stuff1.stuff2,.stuff3,.stuff4::after, .class1.class2::after, .stuff5.stuff6,.stuff7,.stuff8::after`. And it's pretty readable - seeing a selector and a more specific one on the same rule just says "Here's how I want to resolve this specific ambiguity." – personal_cloud Dec 18 '22 at 23:49
2

The important flag (!important) is "frowned upon" by some because it is often used as a substitute for good coding practices.

It can be seen as encouraging sloppy code because, in the end, "we can just use !important".

Eventually, however, this practice results in problems like these: How to override !important?

But if you're already writing good quality code, or you're trying to override code that is beyond your control (e.g., WordPress), or you need to make a change in one page, but not the whole site, then the important flag can be a handy tool.

Bottom line, there's nothing wrong with !important when used properly. It exists for a reason.

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
  • 1
    Thank you. This addresses the second part of my question. Needless `!important`s making the code sloppy makes sense... and I also like your examples of where `!important` might be good practice after all. (Thankfully, per Jordan's answer, the simple example I gave is not one of those occasions. Before I understood Jordan's answer, however, `!important` seemed to me like a more urgent necessity). – personal_cloud Dec 18 '22 at 23:54