Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS child selector performance vs. class bloat

I'm trying to learn to write more efficient CSS, particularly as I'm working with a fairly complex site that needs to render fast.

I'm used to having a lot of this in my HTML/CSS (mainly because I like the readability):

.spotlight {}
.spotlight ul {}
.spotlight ul li {}
.spotlight ul li a {color: #333;}

<div class="spotlight">
  <ul>
    <li><a href="">link</a></li>
    <li><a href="">link</a></li>
    <li><a href="">link</a></li>
  </ul>
</div>

I now understand that browsers run the CSS rule matching process from right to left, meaning that the <a> element in the last CSS rule above would first match every link on the page, leading to performance loss.

So from what I gather, the browser-friendly solution would be to be more specific, and use, for example:

.spotlight {}
.spotlight-link {color: #333;}

    <div class="spotlight">
      <ul>
        <li><a class="spotlight-link" href="">link</a></li>
        <li><a class="spotlight-link" href="">link</a></li>
        <li><a class="spotlight-link" href="">link</a></li>
      </ul>
    </div>

(assuming I'm using inheritance where possible but often still need specific control over the last element down the tree)

What is causing me doubt is: doesn't all the extra HTML bloat from printing class names on elements throughout the page negate performance gains made from avoiding nested CSS child selectors? I'm used to trying to write less HTML and this sort of goes against it. Any insight would be appreciated.

like image 851
Tom Avatar asked Dec 23 '12 18:12

Tom


People also ask

Which selector is faster in CSS?

Class attribute need not to be unique like id. CSS Selector is best option if web element has no ID and name. CSS is faster than XPath.

Which selector has highest priority in CSS?

Id selector has highest priority because of unique nature of the ID attribute definition. We have two classes with one ID selector here it will apply font-size:12px and font-weight:500 due to the specificity rule as ID selector has highest priority after inline CSS.

Which CSS selector has the lowest weight?

CSS Selectors and Their “Weights” lowest weight : type and pseudo-element selectors. low weight : class, attribute, and pseudo-class selectors. medium weight : ID selectors. high weight : inline styling.

Which is better ID selector or class selector?

You should use a class if you need to use the same selector more than once within a page or a site. While an ID is specific to a single element, classes can be assigned to multiple elements on a page or throughout the website. They are not unique.


2 Answers

You have to weigh it up. Adding a class to every anchor is ridiculous, the extra bloat in the HTML would massively offset the rendering time saved (which would be 1/10,000th of a bee's leg). Not to mention how hard your code would be to maintain.

You just need to stop using unnecessarily expensive selectors, for example

.spotlight ul li a

Can be written as

.spotlight a

If you keep on specifying a single class on the same elements in your HTML (like your second example), you'd probably be better off using a tag selector instead.

You also have to weigh up your time vs the browsers time. How much is it going to cost in your time to save a few nanoseconds on each page load? In all honestly, it's not really worth it.

Also, making your CSS structure match your HTML structure negates the point of CSS - if the HTML changes, you need to change your CSS. So you always want your selectors to be as unspecific as possible.

But there is no right or wrong answer here.

like image 119
Christian Avatar answered Sep 18 '22 14:09

Christian


The best trade-off, I think, is using the child combinator > for elements that are repeated many times and using classes when things start to become too nested.

Bending the Rules of BEM

The above article strikes the perfect balance, I think, considering our options.

Using SCSS, which ought to be obligatory nowadays, my navigation menus usually look like this (which is definitely the most I will ever nest stuff):

.header__nav {
  > ul {
    > li {
      > a {}
    }
  }
}
like image 36
dalgard Avatar answered Sep 18 '22 14:09

dalgard