views:

334

answers:

8

I was wondering what the experts do when it comes to writing CSS code. Is it bad to use the tagname.className style? Does inheritance cause a noticeable performance loss? Does it only affect the browser when loading a page or also after? eg: user scrolls down further the page, would poor CSS be a culprit to sluggish scrolling when viewing a page with a lot of rows of results?

CSS Examples:

div.result-row{...}
div.result-row div.photo-column{...}
div.result-row div.main-column{...}
div.result-row div.main-column div.text-row{}
div.result-row div.main-column div.date-row{}
div.result-row div.action-column{...}

vs

div.result-row{...}
div.photo-column{...}
div.main-column{...}
div.action-column{...}
div.text-row{...}
div.date-row{...}

My page is outputting a lot of user posts like this...

<div class="result-row clearfix">
    <div class="photo-column">
     <img src="..." />
    </div>
    <div class="main-column">
     <div class="text-row">
      User's text
     </div>
     <div class="date-row">
      Today
     </div>
    </div>
    <div class="action-column">
     <a href="#">...</a>
     <a href="#">...</a>
    </div>
</div>
+4  A: 

It should only affect file size and therefore load time.

A good way to go about it is while you are developing make the css as readable as possible (using as many selectors as needed for this), but when you go to put the site live take out unneeded selectors and compact it.

in development

div.result-row{...}
div.result-row div.photo-column{...}
div.result-row div.main-column{...}
div.result-row div.main-column div.text-row{}
div.result-row div.main-column div.date-row{}
div.result-row div.action-column{...}

live

.result-row{...}.photo-column{...}.main-column{...}.text-row{}.date-row{}.action-column{...}

EDIT

After reading some comments on this page, it makes sense that using complicated selectors can affect rendering time. According to the test results i've read about the load time is so small it won't be noticable, but it seems as if it does indeed affect it.

This should still not affect scrolling though.

Read these:

http://www.stevesouders.com/blog/2009/03/10/performance-impact-of-css-selectors/ http://code.google.com/speed/page-speed/docs/rendering.html#UseEfficientCSSSelectors https://developer.mozilla.org/en/Writing_Efficient_CSS

Galen
Doesn't really answer his question (slow scrolling).
musicfreak
any good tool to use for this? minification? i guess a tool still will not strip out unnecessary tag selectors tho
iceangel89
@musicfrea - sure it does, check my first sentence
Galen
@iceangel89 - yeah minifiers won't edit the tags just remove the whitespace and maybe unneeded trailing semicolons.
Galen
Please read pw's answer
Andy Ford
A: 

CSS rules are all applied as the page loads. As the user moves around the page the CSS has already done it's job.

Ian Elliott
A: 

Poor css can definitely impact rendering, however I don't believe it would impact scrolling once rendered. In your example, at least avoid the selectors 3 levels deep. Single level css selectors will be faster than double level selectors. Putting the tag type should speed up the selection process, because instead of matching *.class in your DOM document, it only has to match div.class, filtering the type of dom nodes you are having to look at class for.

Crad
A: 

Not exactly sure if Galen's answer is 100% correct. There are a couple of nice articles with benchmarks out there with a different conclusion "Performance Impact of CSS Selectors". However in most real world cases you won't notice any difference and therefore the possible benefit is not worth the effort.

merkuro
+2  A: 

CSS won't lead to sluggish scrolling. What might, though, is fixed backgrounds (via background-attachment: fixed). In my experience, I've noticed that those tend to slow down the browser when scrolling, so that's the most likely thing. If you don't use any of those, then just check to make sure you aren't using enormous background images.

musicfreak
the reason for that is that borwser has to re-render on everyscroll, otherwise it renders only the invisible part of the page leaving the visible on as is
Mike
+1  A: 

Be careful. Removing and adding scope for your selectors changes the priority of rules and may lead to unexpected results on your production output.

Minification is overrated. Modern, well-configured webservers will send gzip'ed CSS which will collapse whitespace and repeated words very effectively. The performance gains of a few K per CSS file are not perceptible to humans using anything faster than a 56k modem. By contrast a single 100x100 px JPEG image could easily consume more bandwidth than your CSS and JS files combined.

Combined with caching this largely makes the need to optimise CSS size redundant, or at least far less important than keeping your code maintainable.

As for how it affects rendering speed, i don't know, however I suspect that is largely implementation dependent (browser specific).

SpliFF
+1  A: 

Removing the tag names isn't going to do anything but save a few bytes from the file size. I find the elm.className notation to be more comprehensible than simply throwing class name-only selectors in there. Not to mention, removing the tags will change the level of specificity for that rule. For complicated (or poorly written) CSS layouts, this could have some very unusual consequences. The performance gains would be limited to a few extra characters that the CSS parser doesn't have to read, which is going to be imperceptible.

Andrew Noyes
+3  A: 

The documentation for Google's Page Speed has a section about using efficient CSS selectors. It mentions how descendant selectors are inefficient because once the rightmost selector has been matched "the browser must [also] traverse up the DOM tree, evaluating every ancestor element until it finds a match or reaches the root element." Mozilla even says "the descendant selector is the most expensive selector in CSS." So div.photo-column{...} would be preferable to div.result-row div.photo-column{...}.

It also mentions that you should remove redundant qualifiers such as "class selectors qualified by tag selectors (when a class is only used for one tag, which is a good design practice anyway)." That makes sense because if you have div.photo-column{...} instead of .photo-column{...} the browser has to make two checks, one to check for class="photo-column" and, if that's true, one to check if the element is a div, rather than just checking for the class, if that's all you specify.

pw
Those links were helpful. Thanks bro.
Seth