When Styling with no Class is a Good Thing

Micah Godbolt, Developer
Posted

When much of a website's content is entered via a WYSIWYG, we end up with a lot of h2s, h3s, p's, lists and anchors, and other non-qualified tags. Very often, we're asked to provide pretty specific styles for each of those tags. The problem with those .content-area h2  tags is that they will bleed into any other component we place into that region.

[xhtml]<div class="content-area">
  <!--- User content -->
  <h2>My Title</h2>
  <p>Some text in a paragraph</p>
  <a href="#">Click Me!</a>
  <!--- Blog Widget -->
  <div class="blog-widget">
    <h2 class="blog-title">My Amazing Blog</h2>
    <p class="blog-text">This post is all about cats.</p>
    <a class="blog-link" href="#">Visit the Blog Article</a>
  </div>
</div>[/xhtml]
  1. .blog-widget h2 {
  2. color: green;
  3. }
  4.  
  5. .content-area h2 {
  6. color: blue;
  7. border-bottom: 2px solid black;
  8. }

The problem should be pretty obvious. Our blog title was supposed to just be green, but putting it in the content area turns it blue and gives it a bottom border.

Possible Solutions

Change the order of blog-title and content-area declarations

Yes, our cascade is causing some issues here because we are styling our content area after the blog widget. We could also change .blog-widget h2  to .blog-widget .blog-title  to make it more specific. Either way we are just fighting a specificity and cascade battle, and we're still left with a border-bottom that we don't want.

Use a child selector like .content-area > h2

This approach would actually work in our case, but it is a very fragile solution that is markup dependent. If the user wraps their h2 in a div, table, blockquote, or any other piece of markup, the style will stop working.

MOAR better solution!

Use a :not([class])  pseudo selector to create a "no-class" selector

  1. .blog-widget h2 {
  2. color: green;
  3. }
  4.  
  5. .content-area h2:not([class]) {
  6. color: blue;
  7. border-bottom: 2px solid black;
  8. }

What we really want to do is target tags that don't have class attributes. We want to style our<h2> tags without those styles affecting our <h2 class="blog-title"> .  Using .content-area h2:not([class])  we can target only those h2 tags that don't have a class attribute.

Happy Styling!

Micah Godbolt

Developer