On non-conflicting yet concise CSS selectors

#css #scss

I like OOP-like concise CSS class identifiers, such that SCSS pushes you to use:

<div class='page'>
  ...
  <div class='developer'>
    <div class='name'>...</div>
    <div class='job'>...</div>
    <div class='site'>...</div>
  </div>
  <div class='developer'>
    <div class='name'>...</div>
    <div class='job'>...</div>
    <div class='site'>...</div>
  </div>
  ...
</div>

One problem with them is that if you have short class identifier for a top-level element, this identifier is likely to match some of nested classes somewhere deep inside tree of rules. Then some elements could match both top-level class rules and nested class rules:

.page {
  margin: 0 auto;
}
.person {
  .contacts {
    .page {
      padding: 4px;
    }
  }
}

In this example an element that match .person .contacts .page selector will also match top-level .page selector with its margin: 0 auto property.

Even if we nest all of these rules in such a way:

.page {
  margin: 0 auto;
  .person {
    .contacts {
      .page {
        padding: 4px;
      }
    }
  }
}

we still will have these missmatched rules.

It may became more obvious if you translate last SCSS code to fully prefixed CSS:

.page { margin: 0 auto; }
.page .person .contacts .page { padding: 4px }

There's of course simple solution — just assign unique identifiers everywhere!

.main_page {
  margin: 0 auto;
}
.person {
  .person_contacts {
    .person_page {
      padding: 4px;
    }
  }
}

Or use id-selectors for top-level rules:

#page {
  margin: 0 auto;
}
.person {
  .contacts {
    .page {
      padding: 4px;
    }
  }
}

But there's another solution using direct descendant selector:

body > .page {
  margin: 0 auto;
}
.person {
  .contacts {
    .page {
      padding: 4px;
    }
  }
}

or even:

body {
  >.page {
    margin: 0 auto;
    .person {
      .contacts {
        .page {
          padding: 4px;
        }
      }
    }
  }
}

Notice this body > .page, it will match only top-level elements, so .person .contacts .page elements will be ok]

 

For obvious reasons direct descendant selector should be faster than normal descendant selector in any optimized layout engine.

As I understand, SCSS hierarchical rules can be automatically fixed to eliminate such conflicts in cases when we have identical selectors in one rules tree.

Remember, that CSS is code, and as any code it'll be better to be reusable, and heavly nested rules are against this.

 

shitpoet@gmail.com

 

Прислушайся
2015-11-21
Откровенно говоря, иерархия более, чем из двух классов нагрузит браузер нехило. Естественно, мы говорим о каких-то миллисекундах. Но если такой подход использовать повсеместно, то получится код-улитка, который на любом устройстве затянет процесс обработки CSS на непозволительную секунду.
author
2016-06-12
I'm not sure about that: CSS Selector Performance has changed! (For the better) http://calendar.perfplanet.com/2011/css-selector-performance-has-changed-for-the-better/


 

free hit counters