When working with css selectors we face many choices how to select an element (using combined selectors, using ids or classes). I am asking if there are any guidelines and best practices about how to make a choice about selectors and classes/ids to have maintainable websites with easy portable parts ?
I find this article helpful - https://developer.mozilla.org/en-US/docs/CSS/Writing_Efficient_CSS
If I'm getting your question right, the choice on which selectors to use will depend on good mark-up as well as appropriate naming of classes and ID's.
Generally, know your target audience and what browsers they use. For instance, you can use something like:
p + ul in IE7, but only if, in your html code there are no comments or elements between a p and the next element, which in this case is a ul.
So knowing what browsers your site is dominantly viewied with is the first thing really. Then, you can work backward or forward as needed.
In the end, it's about IE7+ and whether your user base is using that because there are many kinds/types of selectors that only work in later browsers.
Related
This question already has answers here:
What is the difference between id and class in CSS, and when should I use them? [duplicate]
(15 answers)
Closed 7 years ago.
So I often use a website LiveWeave.com to test HTML, CSS, and JavaScript code that I've written. It has a syntax checker, and whenever I use an ID as a selector in the CSS section, it says that it is improper to use an ID as a selector.
I have demonstrated it in this Weaver. To the right of line three in the CSS window is a yellow icon, which, when hovered over, says that it is improper to use IDs as a selector. I was under the impression that that is specifically for the purpose of being used as a selector for a single DOM element, as opposed to classes, which are designed to be applied to multiple DOM elements.
Am I wrong? IS it improper to use an ID as a selector?
The only other instance I can think of an ID being used is for JavaScript document.getElementById(), and similar functions. What is the proper use of an ID?
Note that I am NOT asking the difference between an ID and a Class, but rather whether it is proper to use an ID as a selector.
Using an ID is the most efficient way of selecting a DOM node in both CSS and Javascript. I personally like to use classes for all repeated items and ids for unique items, or unique configurations of repeated modules. There are many CSS patterns, I use a style called BEM (Block, Element, Modifier as seen here) which is a class based naming convention. Look at your favorite websites, right click or inspect. You will find that there is no one right answer to your question, only many right answers.
May I also say that both exist in the standard for a reason and serve a purpose depending on your applications needs.
Below is the order of efficiency for selectors. IDs are the most efficient and pseudo classes and pseudo elements are the least efficient.
id (#myid)
class (.myclass)
tag (div, h1, p)
adjacent sibling (h1 + p)
child (ul > li)
descendent (li a)
universal (*)
attribute (a[rel=”external”])
pseudo-class and pseudo element (a:hover, li:first)
See here...
It is not improper to use ID's as selectors, so long as the ID being used corresponds to only one element in the DOM (document object model).
If you'd like a selector that is multi-purpose, and able to be applied to multiple elements in the DOM, use a class. Although I'm sure you knew that.
The main reason ID's are frowned upon by some CSS developers, and full stack designers, is simply because they aren't as versatile and they have a higher specificity than classes, which can either help or hinder development (based on CSS knowledge).
For more information on CSS specificity, read here: https://css-tricks.com/specifics-on-css-specificity/
It's valid, it's just considered bad practice by some developers because it can make it difficult to maintain your CSS if you're not disciplined about it. I'm no expert on CSS but I'm pretty sure it's all to do with #'s having a really high specificity rating and if you have them dotted around your CSS files it makes it difficult to manage the cascade i.e. inheritance of style rules. So it's considered best by some to use IDs only for referencing elements in your JavaScript.
I've actually heard this argument before.
Some people push the idea of using solely classes for pure css stuff and keeping id for javascript and other id specific functionality.
It would seem that website follows that ideology, so they are trying to get their users to adopt it. I'm not sure if it is yet best practice to keep id out of css
You can decide for yourself whether an id is worth using, when you could just use a class instead.
If you used an ID as a selector and your using it in your Javascript too then you could make situation where if you decide to rename it then you've created a dependency that wouldn't be there if you had used a class name in your CSS.
Also, though using the ID is faster, it isn't faster if you then use #text a - since CSS reads right to left and has to check all the anchor elements first and then find the one with the ID of #text.
This also means the style isn't reusable and you can't use multiple classes either.
So I think the answer really is, based on all the pros and cons of using an ID as the selector, the best practice to keep you out of possible future problems is to not do it. Of course, this all really depends on how you code, the scope of the project and how many other people are working in the project. It's not against the rules, just not really best practice due to possible issues you might be building in that could bite you later.
On top of what has already been mentioned, even in CSS, ID's can be useful depending on what is the structural design.
For example; if every page in your website requires a header and a footer, I don't see why it would not be useful to make it an id.
What is wrong with doing:
#header {}
#footer {}
If you know for sure that your page has only one header and one footer, I don't see the point in using a class.
Mentioning the id is very specific and the page structure is undubious in this case.
Moreover, I also don't see what is wrong by doing something for example like:
.menu{}
#header .menu li{}
#footer .menu li{}
To add specific styling depending on the page segment. Seems very legit to me.
Ultimately, I even think that using ID's to indicate page sections might be more beneficial by ´knowing´ that they are unique (although they might be recurrent across different pages).
Reading an id in a CSS file should give the CSS designer the benefit of immediately knowing what page segment the following css rules are referring to.
A sheet with only classes would in that case seem less clear than using ID's imo.
I'm using XHTML (strict) to create a webpage - I cannot use HTML5 yet. When I run my CSS code through CSS Lint, I get the warning "Don't use IDs in selectors" several times.
I'm not sure why I'm getting these warnings. Should I be exclusively using classes instead of id's? I appreciate HTML 5 has the option to use semantic tags, but for now I need to stick with XHTML. Can anyone help?
You're perfectly fine to use IDs instead of classes. A lot of HTML validators would tell you otherwise, because they're written by people who don't like it.
It's entirely a style preference, and stating is as a rule is nonsense. Using IDs to style your HTML is perfectly valid CSS.
For more on this, see CSS Lint Is Harmful.
Using ID's have a very strict specificity issue. Realistically, according to the standards, you can only use an ID once in any given HTML document. That doesn't mean you can't use ID's as styling selectors, though, it does come with dangerous pitfalls in larger projects. They're fine if you're using them as targets in Javascript. Go crazy.
CSS Lint is basically telling you that ID selectors are very, very specific in targeting elements and in return, you end up with problems later down the line dealing with CSS specificity. Class selectors are reusable and have much looser specificity. CSS Lint may be harmful, but in the eyes of many professional developers, styling with ID's doesn't have anything different that a class selector doesn't have, so why use them if they're causing specificity issues? Read this and this. They are both fantastic articles on why ID's are not cool for CSS. It is a personal preference, but, making your CSS very specific is a front-end disaster in all real-world cases web development.
I have been reading a lot of CSS performance articles, such as;
Efficiently Rendering CSS
Writing efficient CSS selectors
Writing efficient CSS
I get why selectors like this are bad
#social a {
}
As the browser will read a first, then is forced to loop through all the <a> tags in the page.
But why is a selector such as a[title="home"] slower than using a class?
I assume that the browser creates some sort of an index to be able to figure out what elements have a certain class (Correct?).
But shouldn't browsers also have indexed up what elements have a certain attribute? (such as title)?
My question is; why is the CSS / element look up way slower when using selectors such as a[title="home"] compared to using a class? What or how does the browser act in order that the result is so much slower?
Browser implementors optimize the most common cases. Since classes are used very frequently to match styles, they must implement this as efficiently as they can. When they load in CSS, they index the classes to make this possible.
Since random selectors like title="home" are not used very frequently, they can get away with implementing them using simpler searches. It won't have as much impact on performance, because it will rarely be used.
Classes also require special treatment in the browser, because an element may have multiple classes, e.g. class="foo bar baz". When parsing the document, the browser needs to split this up so that it can match any of them against CSS selectors.
Benchmark
Conclusions
In most cases 'attribute selector with unknown attribute, e.g. [a="b"]' and 'attribute selector with known attribute, e.g. [title="a"]' showed up in the '3 Worst' category. It's safe to say you should avoid those selectors.
This is a long shot, but is there a tool available that optimizes CSS selectors by removing unneeded specificity?
I find that when I write CSS, I deliberately make my selectors more specific than necessary to avoid conflicts and for quasi-documentation.
It would be great if there were a tool that could analyze a given group of rules, determine their "uniqueness" in terms of overlap with other rules, and then strip away any unnecessary specificity.
I can't even begin to imagine how a tool developer would approach all of the scenarios this would require, but I've been blown away by others' ingenuities in this area before and figured it was worth asking.
Update:
I've added a bounty to this question, and the more I think about it, the more I realize how valuable a CSS Specificity Filter would be.
For example, when working with Nested Rules/Selectors in Sass and LESS, excessive nesting is a common and well-known antipattern that can easily lead to overly specific selectors.
There's a good illustration of this in the excellent TutsPlus course Maintainable CSS with Sass and Compass:
body {
div.container {
p {
a {
color: purple;
}
}
}
}
Sass will follow these nesting instructions and produce the following CSS output, raising no objection to any unneeded specificity:
body div.container p a {
color: purple;
}
If a Specificity Filter did/does exist, however, it would create potential benefits for CSS developers:
You could organize your stylesheets as a 1:1 mapping of the DOM, similar to what you see when you examine style rules in Firebug and Chrome Dev Tools. A smart editor/IDE could auto-populate styles for DOM elements with shared styles/classes. That redundancy would then, of course, be filtered out by the Specificity Filter/Optimizer.
Stylesheets could have their structure pre-populated by a tool that scans the DOM and translates it to CSS selectors/rules. This means a developer would only need to update the HTML; the CSS "tree" would be kept in sync to reflect the current state of the DOM. A smart editor would let you jump to the CSS definition for an element/class for styling -- or even make its style rules visible in a separate panel.
In a way, this almost seems like a step backward - like a feature you'd find in Dreamweaver or WebAssist to help newbs learn CSS. But the basic idea of a CSS selector optimization tool seems like a no brainer, and the type of workflow automation I've described would be the logical next step -- and the catalyst would be the Specificity Filter.
I looked into some of the better-known CSS editors and web IDEs, but haven't found anything offering this type of functionality beyond targeting a single element and generating a selector for it.
Update 2: CSS Selector Performance
In response to Spliff's comment, here are two great articles on CSS selector performance:
Performance Impact of CSS Selectors by Steve Souders
Efficiently Rendering CSS by Chris Coyier
Both agree that micro-optimizing CSS isn't worth the effort, but that over-qualified descendant selectors are "an efficiency disaster." I haven't benchmarked yet myself, but suspect that the kind of "DOM Mapping" approach I'm suggesting would cause a performance hit without an optimization step, either manual or automated.
Related Questions, Links, and Tools:
Points in CSS Specificity
Tool to See CSS Specificity
Tool for Cleaning Up CSS
Order by CSS Specificity
Top 5 Mistakes of Massive CSS
Google: Efficient CSS Selectors
Procssor
Clean CSS
CSS Tidy
You could attempt to take a different approach, try to write your selectors as small (low specificity) as possible. and only make them more specific when needed.
With that way of working you don't need a tool.
Just going to throw this out there-- it doesn't 'answer' your question,but it's a tool I like to spread the word about for people who do a lot of css programming: Firebug.
If you're not familiar with it, it's a tool for web browsers. You pull up your page once it's installed, right click and select 'Inspect Element.' It will show you all css affecting different elements on your page, and is useful for creating clean, precise css code. Also it makes it easier to see instant updates on what your page would look like with slight modifications. It will inform you of useless css code that's being overridden by other css code.
ALSO! Firebug now is available for almost all browsers. Not just Firefox. Personally, I'm partial to using it in Chrome.
We really can't do without specificity because it is the only thing that saves you when you have two or more rules colliding. Specificity brings sanity to the whole jumbled CSS rule, so it is more of a blessing than curse. Some of the stuff you talked about, like the CSS selector, can be done using Firefox/Firebug. I'm more disturbed by browser compatibility.
Actually there's a way you can do this using HTML5 and CSS3. The standard technique is to specify elements using the HTML 5 attribute "data-" and then do CSS selection for this attribute. This isn't the purpose of the attributes, but you can customly specify some elements that you can use to even switch the theme of a site.
So, for example, you can end up creating your specificity filters manually in CSS, by specifying
<b data-specificity=2>test</b>
where data-specificity only matches to parents above.
UPDATE:
Alright, so for example, let's say you have a paragraph class, but you want to specify which parent, or how many parents the paragraph can inherit properties from. You would use rules for each potential parent that can be inherited from:
p[data-specificity="1"]{
color:red;
font-family:verdana;
text-decoration:underline;
}
p[data-specificity="2"]{
color:black;
font-family:arial;
}
div.container > *[data-specificity="2"] {
font-family:impact;
color:blue;
text-decoration:underline;
}
So these rules mean that any p tag which is a direct child of the div container and has specificity 2, is allowed to inherit properties from the div container. The blue color of the div gets inherited by the p with data-specificity 2.
Here's a JSFiddle where you can see this!
The idea is that like this, using HTML5, you can control exactly which elements are allowed to inherit which properties. It's a lot of extra code to write (for both child and parent elements) but you can use this to get rid of some unnecessary specificity
I've never actually seen anyone use this method in practice, I pretty much just cooked it up for you, but I think it could be very useful, what do you think ?
I understand that in jQuery, it's advantageous to be more specific when using selectors so that jQuery doesn't have to traverse the entire DOM to find what you're looking for. For example, $('span.description') is better than just $('.description') if I know that the description class is only ever applied to <span> elements.
Is this the case with CSS, too? Is there any specific advantage for me to use span.description { } instead of .description { }? I'm thinking in terms of speed, optimization, etc. Am I saving the browser any work by telling it exactly where to look?
This is true in CSS -
A good rule is to descend from the nearest ID.
IDs are indexed so locating them is extremely fast. There is no reason to use more than one in your selector.
Google Code- Optimize browser rendering
This answered a lot of questions I had on the subject including this one-
I hope you find it useful.
Read up on css specificity - which is the most important reason to be more or less specific with your css.
http://www.w3.org/TR/CSS2/cascade.html#specificity
As browser performance is pretty much a non-issue (except for in jquery, as you've mentioned), my guideline is to be specific when you are controlling precedence, or when you want to make something a bit more readable in your css. Over specifying can make it tricky to re-use css selectors and make things overly complicated.
Edit
This looks like a bit of a duplicate:
CSS Performance Question
it always depends on your amount of html code and the structure. It is definitely a good idea to use especially ids and appropriate selectors. (ie #nav li instead of li.nav). Since browser first load the html and then apply the css you are helping a lot.
This said, when it comes to pure css (no jquery) the difference in speed is nowadays not easy to distinguish, because the rendering engines are highly optimized - especially when it comes to applying css. So normally it shouldn't matter.
As far as I know, how specific your selectors are make very little difference on the performance.
The two areas where more specific selectors are most useful, is to reduce the risk that it's not applied where you don't want it, and to make one selector take precedence over another.
A more specific rule has precedence over a less specific rule, so:
span.myclass {}
has precedence over:
.myclass {}
(no matter what the order is in which the rules were declared)