How long do your selectors get?

I’ve somehow gotten into a habit that creates a lot of long selectors. I find myself listing most of the path to an element in the selector. For instance:

form.profile .userinfo span.userinfovalue { display:inline-block; width:60% }

Conceivably, the style could be just this:

.userinfovalue { display:inline-block; width:60% }

I’m not sure which is the best solution. I tend to indent my stylesheets with children of an element… like this:

form
    form.profile
        form.profile .userinfo
            form.profile .userinfo span.userinfovalue
            form.profile .userinfo span.userinfotitle

and etc. I think that’s how I ended up writing selectors like this.

If I had another use for .userinfovalue arise, I’d write it like this:

form
    form.profile
        form.profile .userinfo
            form.profile .userinfo span.userinfovalue, form.register .userinfo span.userinfovalue
            form.profile .userinfo span.userinfotitle

Of course, there are classes that I always keep general, for instance:

.fineprint { font-size:10px; font-style:italic; }

I like the organization of this system, and I like that the long selector tells me something about how and where the style is being used. But because it creates quite a few long selectors, I’m not sure it’s the best way.

Opinions?

Thanks.

The selector should be as long as it needs to be and no longer. Any redundancy is a waste of effort and a waste of browser effort in working it all out.

Your selectors should be as simple as possible.

Long paths are a maintenance nightmare and bloat the css very quickly and make the browsers work like mad to find out the right rule. The shorter the better and the less prone to error they will be.

Usually when I see a long selector then its because the author hasn’t thought carefully enough about the task in hand and is over-riding things with longer and longer pathnames.

Long pathnames also add to specificity so if you want to override a class somewhere you have to give it more weight which would involve an even longer pathname yet again. Rather than having long convoluted pathnames in most cases an extra class would have done the job more easily.

There are of course times when you need to qualify the selector via its location but that’s usually down to bad planning. If you re-use the same element in different places and you want to style it differently depending on its location then surely using a new class instead would save all the long path names.

Simplify your selectors and make them only as long as they need to be.

There’s an old thread here that may be of interest and a [URL=“http://www.css-101.org/descendant-selector/go_fetch_yourself.php”]funny article here.

Longer selectors mean more computing power needed to process them. You should try to keep them to a minimum where possible. If the only times you ever use class="fineprint" are in that context then .fineprint is all you need. Anything more than that increases the scope for confusion and mistakes. If you want to make it easier to see where you’ve used things, organise your CSS file by usage area and think about using comments to mark out what is used where.

Lol. Your funny article made the point very well, Paul. I always appreciate a laugh with my learnin’.

You said:
“If you re-use the same element in different places and you want to style it differently depending on its location then surely using a new class instead would save all the long path names.”

What I’m imagining here seems like bad practice. What I think you’re saying is something like this:

(This is just a quickly thought-up example)


.userinfo { display:inline-block; width:60% }
.userinfo-left { display:inline-block; width:60%; float:left; }
.userinfo-inline { display:inline; width:60% }
.userinfo-big-red { display:inline-block; width:60%; font-size:2em; color:red; }

That reminds me of all the horrible old class names like “.arial10gray” that we saw before folks got wise to semantics.

But let’s say the place I want the element to be inline is in only in the registration form. I feel like this would be more appropriate:

.register .userinfo  

than

.userinfo-inline

Note I at least didn’t write form.register :wink:

So… am I misunderstanding what you meant by creating additional classes?

Thanks.

Your selectors should be as simple as possible.

OK. I think this is like that “you shouldn’t use tables” thing again. Some how it we well meaning phrase that no gets interprted so that I even get clients asking me NOT to use table’s for tabular data… because “you shouldn’t use tables in your web pages”

I would phrase it this way : Use the lowest number of selectors to reach the desired element, keeping in mind specificity conflicts. Yeah, not as noob friendly off the bat, but a good compromise.

Here is what I mean:

  • AFTER you have written your mark up!! decide which element you need to style.

  • Any element you only use once… you could style with a unique class , or BETTER yet an ID. ( I favour the latter)

    div .someClass #myID .otherClass p{} /*unless you have specificity conflicts… anything before the ID is redundant */

#myID .otherClass p{} /* is better, again unless you are trying to resolve specificity conflicts OR you want to style the ONLY the Ps within .otherClass differently, this is too long}
#myID .otherClass {} /* and this would be more suited*/

/* but what is there were a SPAN with the P we wanted to target? agin we most ask questions… how wide is SCOPE of SPANs we want to target ? */

#myID span {} /*all spans? then this is it… anything else is too much. */
#myID p span {} /*ONLY those spans in paragraphs ? then this is it… anything else is too much. */
#myID .otherClass span {} /*ONLY THOSE spans in within .otherClass ? then this is it… anything else is too much. */
#myID .otherClass p span {} /*ONLY THOSE spans in paragraphs within .otherClass ? then this is it… anything else is too much. */
what if you only wanted to target SOME spans?
#myID .targetedSpan {}
OR
#myID p .targetedSpan {} /*if you ONLY needed target spans in paragraphs.

OR
*/#myID .otherClass .targetedSpan {} /*if you ONLY needed target spans ANYWHERE within .otherClass when it’s wrapped #myID */

Notice that this methodology, tho it takes more conscious thought( but that’s why you are asking questions right?) also helps you avoid adding classes to every tag in the mark up.

I you know you are styling all SPANs within As in a #mainMenu (UL)… why add classes in the HTML?

#mainMenu span{} will get u there.
If there is an oddball SPAN hit it with: #mainMenu .oddBall{}

voila!

Again if you have painted yourself in a corner an created a specificity conflict you JUST CANT RESOLVE with good code ( tho using this method should help you avoid that…) THEN you can add a selector anywhere to help…

for example:
#myID div.otherClass p span {}
or
div#myID .otherClass p span {}
or WTH did you do to deserve this!???!
div#myID div.otherClass p span {}

hope that helps

I think just using “.userinfovalue” and then placing it in your HTML content where it needs to be does the same job as the long selector. Seems to me that the longer selector just allows you to to have multiple class names in one stylesheet.

So, hypothetically, if you have the class name “.userinfovalue” occurring in your Nav, and “.userinfovalue” occurring in your Sidebar yet both need different styling you could have “#nav .userinfovalue” and “#sidebar .userinfovalue” then set up different styles for each.

Having the same classname with different styling for different areas of the layout is the only time I can imagine using long selectors filled with nothing but classnames would be necessary. But, I would avoid having the same name for classes altogether. I have found that I can take care of most situtations by having an ID or class, and then styling the elements within, like:

.userinfovalue p {}
.userinfovalue ul li {}

Etc and then just add the class to the form tag. Honestly that’s all I have ever needed for anything I have done.

No you more or less understood what I said but your implementation is flawed. The class names should not be presentational but should allude to the function they perform.

First of all we can reduce this bloat:


.userinfo {
	display:inline-block;
	width:60%
}
.userinfo-left {
	display:inline-block;
	width:60%;
	float:left;
}
.userinfo-inline {
	display:inline;
	width:60%
}
.userinfo-big-red {
	display:inline-block;
	width:60%;
	font-size:2em;
	color:red;
}

To something shorter and more meaningful like this.


.ui-register,
.ui-account,
.ui-login,
.ui-warning {
	display:inline-block;
	width:60%
}
.ui-account{float:left;}
.ui-login{display:inline}
.ui-warning {font-size:2em;color:red;}


Now when you have an element in your html.


<div class="ui-login">......

You know exactly what is is doing and more importantly the browser knows straight away (I found it! I found it!). The “ui” prefix can be your indication that these are similar user interface rules so no need to use descendant selectors to do that.

There may be situations where you want to define the same class differently by location but that should be achievable with 2 descendant classes at most and indeed if IE6 support wasn’t required you could use concatenated classes to effect the same sort of change.

However, in practice the single class approach has proved to be more maintainable and you only have to look at a standard wordpress page and see the plethora of classes added to elements that make it virtually impossible to understand where rules are coming from unless you use a tool to analyse the code.

As I said in my first post the selectors should be as short as possible to achieve what needs to be done and no longer. Of course there are times when you may want to break the rules to aid in your reading of the stylesheet and I will often write things like ul#nav instead of #nav because I like to know what the element is so that I remember to remove the bullet and margin and padding. However I wouldn’t use something like div#test everywhere because that is just unnecessary bloat.

Thanks for clarifying, Paul. That makes sense.