As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
I am wondering which selector is better practice and why?
Sample HTML Code
<div class="main">
<div class="category">
<div class="product">
</div>
</div>
</div>
and we want to reach .product with CSS selectors:
.product
.main .category .product
div.main div.category div.product
I am comparing them to the following criteria:
Performance
Maintainability
Readability
We may assume that .product is unique throughout the page. We can have used id instead of class but in this case, we chose class attribute.
We may assume that .product is unique throughout the page.
Performance-wise the best would of course have been an ID selector but since you're using a class instead, .product would come second.
As for maintainability, readability and semantics (there's a bit more on performance as well)...
.product means
Find any elements that have a class product.
Very easy to understand, almost identical to an ID selector if you use this based on the above assumption.
I guess the only difference between using a class selector and an ID selector in this case is that an ID selector enforces uniqueness of this element, and not only because there just happens to be one such element. In other words, an ID selector acts on the knowledge that a document will only have one such unique element, while a class selector does not.
.main .category .product means
Find any elements that have a class product
which are contained in any elements that have a class category
which are contained in any elements that have a class main.
Browsers are tasked with checking the ancestry of these elements, which is redundant if you only have one .product. Many browser layout engines evaluate CSS selectors from right to left, similarly to how I translated the selector to English as above.
div.main div.category div.product means
Find only <div> elements that have a class product
which are contained in only <div> elements that have a class category
which are contained in only <div> elements that have a class main.
In addition with checking the hierarchy of elements, you expect a browser to only match a div with the class product. If you want to match any element of this class then this selector wouldn't work as intended.
If you're sure you will only have exactly one div with that class, and you want to only match that element, then you could use div.product instead, but .product still performs fractionally better.
I'm no guru but I can at least comment.
I think first way is easily the best:
it prevents the CSS from having to traverse the DOM tree to find an element,
if you edit any of the parent elements then you will have to edit the CSS selector. Readability: personal choice, some people may like the second, but most won't really mind
I always try to use the smallest selector possible, so I would just use .product (i.e. your first example). I think this also has performance benefits since the browser only has to find elements marked with that single class, rather than trying to find a matching parent first, then checking to find out if it has a descendant marked with that class, etc.
The only reason I generally have to use the other methods you mention is if:
I'm trying to add specific styling under a specific context. For example if I wanted to bold all internal links (under a .internal_link class), but wanted them to also be underlined if they appeared in a certain context.
I need to add specificity in order to force my rule to take effect.
Finally, if you're assuming that there will only be one element marked with the .product class, then you're probably better off using that as an ID rather than as a class.
All the three selectors have different meanings and should be used at different places as the need be.
Performance wise, the first should be the best, because we just need to travel the DOM once.
Readability wise also the second and the third selectors seem cumbersome and may be difficult to extend in future.
.product
.main .category .product
div.main div.category div.product
Using the above selectors are depending on how complicated your site is.
Ex.
If all these elements is use only ones. The first selector may be fit.
The second way is best practice if you were using this for multiple pages(ex. you have these elements for a set of products).
The 3rd way for me is unnecessary unless you have this class name in other HTML tags like span..
more tips: Mushu Tricks
The first way .product is the best and the most easiest. If you use the .product you need not go through the entire file to find what you are looking for. You can also use an ID selector without using a class.
Related
When I studied front end dev at the university a few years ago, our teacher taught us to always provide the full (almost) parental
DOM hierarchy of the targeted element within our CSS selectors.
So in our web projects we had to write selectors like:
div#container div#content p.bread a.external { }
instead of just:
#container #content .bread .external { }
or (I see the disadvantages with class conflicts that may occur here)
.external { }
I personally write my selectors like
#container #content p.bread a.external {}
until I recently read an article saying that it should be avoided (but with no obvious reason why) and another article saying the same but that one was intended for jQuery selectors.
Was my teacher wrong and what is the right (fastest to parse and with most support) way of writing CSS selectors?
Practically speaking, you should use the least specific selectors you can.
div#container div#content p.bread a.external { } is a very, very specific selector. It is unnecessarily specific. There can only be one #content element, and it will surely always be within #container.
Write general rules. Don't attempt to target the precise DOM element. If a.external will capture the set of elements you want, use that. Otherwise you'll end up having to write p.bread a.external, p.potato a.external, p.olive a.external, etc, etc.
The difference in performance will be minimal. The benefits of general, reusable rules are large.
My 2 cents
Specific enough to target only what needs targeting (as others have said) is the general rule.
I agree with lonesomeday that "difference in performance will be minimal," but every added element in the chain is one more check to be done.
So Think About How to Reduce It
Are the ID's needed?
I disagree with Spudley that "there should never be a need to specify more than one ID in a selector." If your site is set up to have different display on different pages, and so #page1 #content is different than #page2 #content for displaying, then that is a legitimate case of two id's in one selector. However,
If all pages are #container #content then the drop the #container.
Also, if all p.bread elements are inside #content, then drop that selector also.
Are element names needed?
Is .bread intended to be used on anything other than a p? If not, drop the p.
Is .external intended to be used on anything other than an a (probably linking to an external site)? If not, drop the a.
Is the decedent relation of classes needed?
Is the .bread .external significant for display? That is, does .external exist outside of a .bread parent and does it change because of that parent? If so, then keep the relation. Otherwise, if the important thing is only the .external (no matter where it is), then that is the only selector you need.
Yes, your teacher was wrong.
From your example:
div#container div#content p.bread a.external { }
Given that an ID in a DOM document must be unique, there should never be a need to specify more than one ID in a selector. So the above selector that contains both #container and #content is immediately wrong simply by that criteria.
An ID is the most efficient and direct way to reference an element. Again, it's unique and instantly accessible, so there's no need to qualify it in any way, so adding div in front of either of the #container or #content here is redundant.
The other two parts of the selector p.bread and a.external are likely to be wrong, but it's not so clear-cut for these.
A selector only needs to specify the parts that are necessary to select the elements required and exclude any elements that are not required. In this example, if all .bread elements are ps or all .external elements are as then the element type a or p would be redundant and should be dropped. But without seeing your actual HTML content, it's not possible to be certain of this in the way that it is possible for the IDs because a given classname can legitimately be applied to multiple elements of multiple type.
Longer selectors such as div#container div#content p.bread a.external { } do take longer, yes. But rarely do they make any noticeable impact on the paint time.
Also, since IDs are (supposed to be) always unique, div#container and div#content should really just be #container and #content, respectively.
Elements are superfluous (or rather should be) when used with ID selectors (#), since your DOM should contain only unique IDs for elements.
It's also worth noting that classes should be used to bunch the styles of the same elements. In case you have two .bread elements in your DOM, but want them styled differently, you should consider using a different class name.
Both ways will work, and the impact on speed will probably be minimal. However there is no need to add the element to your rule, and I would encourage you not to as it helps your rules become more reusable - something you should always aim for.
You should also avoid using location to target elements. E.g. .sidebar h3. Instead, add a class to those h3s and target the class. This means you can reuse those styles you wrote elsewhere, just by adding the class. These are all concepts of Object Oriented CSS, and will help you write more efficient CSS by reducing the amount of duplicate code.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I understand the title is a bit misleading, but I come from an Object-Oriented background, and I've recently began a shift towards web development. I've only got a basic grasp of HTML, and been learning and messing around with CSS, but there are some parts of it that are a bit confusing, and I'm trying to get it into terms I can understand.
My CSS:
.Person .span4 p
{
margin-left: 10px;
margin-right:10px;
margin-top:10px;
}
From what I can understand, this means that any p tag that is inside a container, like with the class of "span4", which is in turn inside another container that has class="Person" will be formatted with the specifications listed above.
In other words person.span4.p.format(String[] formatArgs), where the formatArgs are the margin-left, right, and top.
The Question: Is this an appropriate way to look at it?
I know it might be comparing apples to oranges, but I'd like to get an opinion before I go running with some conclusion that could be very wrong, and an actual explanation on how these work.
Your question about .Person .span4 p is correct, that will style a p element that's a descendant of an element with a span4 class that's a descendant of an element with a Person class.
However I wouldn't try to interpret classes in HTML as similar in any way to OO classes. They're completely different concepts, and I think that'll just end up confusing things.
Classes can be assigned to HTML elements using the class attribute (class="span4"), and these can then be used in CSS or JavaScript to apply additional styling or behaviours to those elements. Think of giving an element a class as tagging it with a particular keyword, so it can be easily targeted later. Elements can also be assigned multiple classes by separating them with a space, eg. class="span4 box".
In addition, .Person .span4 p isn't actually a "class", it's a selector. The .span4 syntax is called a class selector, the p is an element selector, and using a space between two selectors creates a descendant selector. Additionally #myId is an ID selector, and there are plenty of other types of selector as well.
I'd recommend this guide as a good way to get up to speed on the correct terminology.
I have a div with an ID:
<div id="main">
What's the correct (or difference) between
div#main {
and
#main {
Regards,
There is a great doco on using efficient CSS selectors, focus on rules with overly qualified selectors:
ID selectors are unique by definition. Including tag or class
qualifiers just adds redundant information that needs to be evaluated
needlessly.
Instead of just applying the style to an element with id main, your selector will re-qualify the element by checking whether or not it's also a div (in that order). To clarify: css selectors are evaluated right to left, unlike same selector syntax when used in jQuery etc.
Re pixelistik's suggestion that div#main is more specific than #main - yes, that is technically correct, however if you have to resort to this to raise a rule's specificity, chances are the structure of CSS you're working on is not as thought through as it should be.
#main matches everything with ID 'main', whereas div#main matches only <div> elements with ID main.
Ideally, you should never have two elements with the same ID, so realistically the two don't make a difference, but there's probably performance related issues regarding whether specifying div makes it find the result faster.
So difference is that:
When you write div#main style will be only for <div> element.
When you write #main it can be used as style for <div>, <span>, <p>, etc.
And what recommend is hard to say, every developer it has it different. So i using for example
span.<nameClass> when is nested in <li> for example.
#nav li span.href a {
...
}
I think it's used when you want that someone class with specific name can have only one element.
So when your write span#href it will works only for <span id="href">Simply dummy text</span> not for others. When you write #href it will works for <span id="href">Simply dummy text</span> or Link but both are correct when you also asking about this. Differences i wrote above.
Both are correct.
div#main is more specific than #main, which means that styles defined with the first selector will override the ones of the second.
Here's a good introduction to CSS specifity:
http://htmldog.com/guides/cssadvanced/specificity/
I want to package up a widget to be easily included in an arbitrary project. I don't want to require that the user link to my personally-created style sheet in their host page - I just want the css to be magically injected when they use my code.
I understand that CssResource can go some ways towards this dream, but after scouring documentation I haven't found any reference to natural type selectors. For instance, I want to style the <tr>s in my widget without having to add a class name to each one.
Is this achievable with GWT? GWT's own widgets all come pretty thoroughly styled, but it seems they've added a style class to every single element in the DOM!
You're on the right track - a CssResource or UiBinder's inline <ui:style> will achieve what you're looking for. With regards to styling elements by type instead of class it certainly can be done:
<ui:UiBinder>
<ui:style>
.myTable tr {
color: red;
}
</ui:style>
<table class="{style.myTable}">
<tr><td>A row!</td></tr>
</table>
</ui:UiBinder>
GWT, however, has a reason for preferring explicit class names over descendent selectors: if you have the above style, for example, every time the browser renders a <tr> element it has to walk up the DOM and visit all of the ancestors of that element to see if any of them have the .myTable class. If your application uses a lot of <tr> elements (<div> would be a better example here), most of which don't have a .myTable ancestor, it can cause a noticeable decrease in rendering performance.
I think, I would use UiBinder, and only give the outermost element a class name, like this:
<ui:style>
.outer tr {
...
}
</ui:style>
<div class="{style.outer}">
...
<tr>...</tr>
...
</div>
Now you don't have to assign a class to each tr - you just use the selector ".outer tr", which only applies to <tr>s within some element marked with the class attribute {style.outer} (doesn't have to be a <div> by the way). The same principle would work without UiBinder, too, of course.
Ok I didn't really understand the whole question, maybe still don't but I think your asking for a way to "bulletproof your CSS" from specificity - I get the CSS bit now after seeing the other answers
Unique classnames (a bit of a oxymoron is CSS terms but heyho) added to everything are advised by most to make sure the site (not your) CSS fails as quickly as possible no matter how specific (weighted) their rules are
But you can make you widget CSS completely unique, i.e. so that it cannot be overruled by a site CSS,no matter how many ID's are in their selectors, without very much ado and without specifically classifying everything
e.g. #mywidget div {} could be overruled by site CSS very easily #wrapper #content div {} will do it - your div is a descendant of those two ID's too, and as their rule had 2 ID's versus your one, your CSS will lose - it's impossible to guess every permutation of a site CSS so the easiest thing is to add all those "extra" classes and why YUI and Blueprint are as they are
however if you write your CSS: #mywidget>div {} yours will likely always win, as never in their CSS will a div they're targetting likely be an immediate child of your widget ID (unless of course they choose to customise yours, which they could do with the 'class everything' method too)
so to bulletproof your CSS without adding classes to everything .. I assume your widget already has a unique iD wrapper? then if you don't already have an inner div wrapper, add one, it doesn't need to have a class but giving it one will place an extra layer of bulletproofing on this technique.
then prefix all your rules with #mywidget>div.myclass e.g. #mywidget>div.myclass td {} - the sites own rules, no matter how heavily weighted (many ID's and classes in a selector make a selector more weighted) theirs will fail as soon as they cannot match that particular combination - so your tr's are safe from site CSS takeover ;)
add one div or class and search and replace your CSS to add the prefix to everything.. as for how to package I've no idea
So, I was wondering about the following: I have some main content div and a sidebar div and the CSS looks as follows:
.main{
width: 400px;
height: 300px
}
.sidebar{
width: 100px;
height: 300px;
}
I will not include now all the floating properties, since I am only interested in the following:
If I have a p element in both of them and I want them to have different styles, shall I give the paragraphs different classes or shall I define the style for them like this:
.main p{
color: blue;
text-align: right;
font-family: ...
}
And then for .sidebar p I would define something else...
The alternative would be to define a class p.myclass and define the style there.
I am trying to understand what a better practice is. Obviously I need less markup if I have 30 p elements in one of the elements with the first method, since I would have to give them all a class. On the other hand, I create CSS that I can only "use" for that parent element, instead of having a general definition that I can apply in more places in the site...
I noticed that in a lot of "big" websites, almost every single html element has its own class...
Any ideas?
I would definitely go ahead with the containment selector in the case you give. Fewer spurious classes in the markup is easier to maintain, and the rule ‘.main p’ says clearly what it does. Use your judgement to whether more complicated cases are still clear.
Note that ‘.main p’ selects all descendent paragraphs and not just direct children, which may or may not be what you want; accidentally-nested descendant matches are a potential source of bugs (especially for cumulative properties like relative font size). If you want only children to be selected you need ‘.main>p’, which unfortunately does not work in IE6.
This is one reason why many sites go crazy with the classnames: the more involved selectors that could otherwise be used to pick out elements without a classname, tend not to work in IE.
I vote for .main p and .sidebar p because:
It most clearly expresses your intention, as you're expressing it in English
It reduces the number of explicit classes you need in your HTML
If you change your mind later and want an explicit paragraph class with that style you can just add it: .main p, p.foo
In my opinion using nested selectors [ parent child relations ] will be harder to read and maintainable.
Evdn if the design changes in a frequent manner CSS should be less affected by that. So styling individual element will be easier in the case of maintainability.
If the element is going to exist in a predictable location then you can style it based on a parent element.
The major drawback of styling by class on each individual element is the bloat: If you have many of these elements, the CSS attributes will become a noticeable percentage of the transferred bytes. Especially for large documents, saving a couple of KB in the download can count. Even more so with AJAX requests or IE where parsing innerHTML is extremely slow.