Sometimes I find myself creating a CSS class for a single element. So instead, I can use an ID and set a rule for this ID. Which way is preferable stylistically?
I'd say that this is more of a person-by-person preference.
For me, I try to think ahead: will I ever create two of these on one page? If the answer is even vaguely "yes," then I use classes. If I can't see the need for creating a second of the particular element, I'll use an ID.
In terms of the ID itself, I try to name it something that I won't conflict with. For instance, I'll choose something like:
#aboutus_team_wrapper {}
It's long and ugly, but I know exactly what it's for, where I'm using it, and I know I'll never create something that conflicts with the name.
Hope this helps!
Don't forget about selector specificity! I avoid using ID selectors whenever possible.
Reference: http://www.w3.org/TR/CSS2/cascade.html (6.4.3)
An ID selector is 10 times stronger than a class selector. That means you would have to use 11 class selectors to cancel an ID selector, or you would have to append the same ID selector to every CSS rule you write, or my favorite, use inline styles or !important rules!
"But why use a class style on an element that I know is only going to show up once? That's what ID selectors are for."
Because ID selectors screw up the cascade. Consider the following (un-semantic) code to illustrate this statement.
<style type="text/css">
#header a { /*Selector Weight: 101*/
font-weight: normal;
}
.bold { /*Selector Weight: 10*/
font-weight: bold;
}
</style>
<div id="header">
Happily not bold.
Sadly, not so bold.
</div>
SO bold...
To make this work, you'd have to add:
#header .bold { /*Selector Weight: 110*/
font-weight: bold;
}
Great, now we have two bold classes. You can see how quickly this can ruin you. Imagine trying to deal with this on a full featured web application.
No hard and fast rules on this one, it's as much about:
why you're using the style
what you're doing
where you're going
more than the number of elements that are involved.
If a style only refers to one, unique element, an ID based selector is the most appropriate.
If a style may refer to multiple elements, use a class.
The other thing to keep in mind is ID based selectors have higher priority than class based ones. This helps if any of your unique, ID'd elements inherit styles from more generic, classed based rules.
I prefer to use the ids for the most important elements that are repeated in the page, such as the Stackoverflow logo (and all the header) on this page.
Use a CSS class when the elements are not page-specific and can be repeated among different pages, or many times in the same page.
Related
I am building websites for a while, and I have a question about CSS I can't really rid over. So there is that frequent situation when multiple classes affect a DOM element, and both classes declare the same properties. For example:
.first {
color:white;
}
.second {
color:black;
}
I know that if I have an element with class="first second" in that the text will be black. If I rather want it to be white, I have several options:
Using !important: I know this one is handy and I use it, but sometimes, if I use it too often, my CSS may become messy. I mean, multiple !important's can result the same basic situation.
Reordering the classes inline: if I am correct, which class comes first, it will be the priority one. This is nice, but i often work with environments where I can't affect that. Secondly, this is not a global but a local solution.
Reorder the CSS itself: well, this sounds interesting, but if I work with many stylesheets (and I do), it is hard to track, especially when it is WIP.
Actually what I am looking for is some workaround like z-index but for priorizing which class is stronger. Because I can't really find anything useful in this topic, I am just curious maybe it is a user error, and you guys know something I don't. How do you manage this? What do you suggest?
class="first second" is the same as class="second first". The priority is based on the position of the declarations in your css and not in their position on the html element.
So, if you want priority of a class against another, put the top priority class LAST on the css file.
.first {
color:white;
}
.second {
color:black;
}
in this example, class second has always priority over class first. This happens because browser scans through the css top-to-bottom and always applying the rules of matched classes that finds. So, the last matched class has priority over the previous matched classes.
see this fiddle: http://jsfiddle.net/5c29dzrr/
At the same specificity level, the CSS selector that is furthest down the stylesheet will be applied. So in your example, if you wanted in that situation to have the element with the white colour you would have to order your properties like so:
.second {
color: black;
}
.first {
color: white;
}
The order of the classes in the HTML tag is not important; it is the order in which they appear in your CSS.
The better way to handle this is to go with some better naming convention such as BEM or SMACSS so that you don't have the issue of conflicting class names.
Edit: It might be worth reading up on specificity and the cascade for a better understanding of this. I found this calculator to be pretty handy in determining which rules will take precendence, although these days you can just use the developer tools to find out that information.
I know that in a stylesheet div#name and #name do the same thing. Personally I've taken to using div#name for most styling I do, with the reasoning that it's slightly faster, and means that I can identify HTML elements more easily by looking at the CSS.
However all of the big websites I seem to look at use #name over div#name (stack overflow included)
In fact I'm finding it very difficult to find many websites at all that use div#name over #name
Is there some advantage to doing #name that I'm missing? Are there any reasons to use it over div#name that I don't yet know about?
Since the div part of div#name is not required (because ID are unique per page), it makes for smaller CSS files to remove it. Smaller CSS files means faster HTTP requests and page load times.
And as NickC pointed out, lack of div allows one to change the HTML tag of the element without breaking the style rule.
Since ID's have to be unique on the page, most ID's you'd run into would only ever appear once in your style sheet, so it makes sense not to bother including what element it would appear on. Excluding it also saves a few characters in your style sheet, which for large sites which get visited millions and millions of times a day, saves quite a bit of bandwidth.
There is an advantage to including the element name in the case where a division with ID "name" might appear differently than a span with ID "name" (where it would show a division on one type of page and a span on another type of page). This is pretty rare though, and I've never personally run across a site that has done this. Usually they just use different ID's for them.
It's true that including the element name is faster, but the speed difference between including it and excluding it on an ID selector is very, very small. Much smaller than the bandwidth that the site is saving by excluding it.
a matter of code maintainability and readability.
when declaring element#foo the code-style becomes rigid - if one desires to change the document's structure, or replace element types, one would have to change the stylesheets as well.
if declaring #foo we'll better conform to the 'separation of concerns' and 'KISS' principals.
another important issue is the CSS files get minified by a couple of characters, that may build up to many of characters on large stylesheets.
Since an id like #name should be unique to the page, there is no reason per se to put the element with it. However, div#name will have a higher precedence, which may (or may not) be desired. See this fiddle where the following #name does not override the css of div#name.
I would guess that including the element name in your id selector would actually be slower – browsers typically hash elements with id attributes for quicker element look up. Adding in the element name would add an extra step that could potentially slow it down.
One reason you might want to use element name with id is if you need to create a stronger selector. For example you have a base stylesheet with:
#titlebar {
background-color: #fafafa;
}
But, on a few pages, you include another stylesheet with some styles that are unique to those pages. If you wanted to override the style in the base stylesheet, you could beef up your selector:
div#titlebar {
background-color: #ffff00;
}
This selector is more specific (has a higher specificity), so it will overwrite the base style.
Another reason you would want to use element name with id would be if different pages use a different element for the same id. Eg, using a span instead of a link when there is no appropriate link:
a#productId {
color: #0000ff;
}
span#productId {
color: #cccccc;
}
Using #name only:
Well the first obvious advantage would be that a person editing the HTML (template or whatever) wouldn't break CSS without knowing it by changing an element.
With all of the new HTML5 elements, element names have become a lot more interchangeable for the purpose of semantics alone (for example, changing a <div> to be a more semantic <header> or <section>).
Using div#name:
You said "with the reasoning that it's slightly faster". Without some hard facts from the rendering engine developers themselves, I would hesitate to even make this assumption.
First of all, the engine is likely to store a hash table of elements by ID. That would mean that creating a more specific identifier is not likely to have any speed increase.
Second, and more importantly, such implementation details are going to vary browser to browser and could change at any time, so even if you had hard data, you probably shouldn't let it factor into your development.
I use the div#name because the code is more readable in the CSS file.
I also structure my CSS like this:
ul
{
margin: 0;
padding: 0;
}
ul.Home
{
padding: 10px 0;
}
ul#Nav
{
padding: 0 10px;
}
So I'm starting generic and then becoming more specific later on.
It just makes sense to me.
Linking div name: http://jsfiddle.net/wWUU7/1/
CSS:
<style>
div[name=DIVNAME]{
color:green;
cursor:default;
font-weight:bold;
}
div[name=DIVNAME]:hover{
color:blue;
cursor:default;
font-weight:bold;
}
</style>
HTML:
<div name="DIVNAME">Hover This!</div>
List of Css selectors:
http://www.w3schools.com/cssref/css_selectors.asp
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
in some CSS code I found out this type of selector
div#someid
Is this formally correct?
If the answer to (1) is YES, what's the need for the div selector before the #someid, shouldn't the id be unique in a valid web page?
Thanks!
Yes it's correct.
It might be because it makes the selector more specific. The more specific a selector it is the higher priority it is.
It is fine.
The stylesheet might be reused between pages which have the id on different elements
The explicit type provides information for the maintainer about the element
It makes the selector more specific, e.g. to override #other div.
The answer is they are the same but using the div in front of #id is superfluous and removing it does no harm while leaving it in only takes up space. Some may feel it makes the markup more readable, however, since it identifies the type of element the id is associated with.
I did read, once, that placing the div in front of the id may cause the browser to search through all divs first while just using #id does not but I'd have to look up that reference.
From what I understand, CSS will rank selectors based on how specific the selector is, if two rules apply to the same element,
ie
#someId{
color: black;
}
.someClass{
color: green;
}
And you had this div:
<div id="someId" class="someClass">
Then which wins? (There are rules in place to govern this particular example, I believe the ID would win anyway).
But say you had these rules:
.someClass{
color: black;
}
div.someOtherClass{
color: green;
}
Then I the second rule would trump it, because it's more specific.
However as David pointed out, ID's are generally rated a lot higher, so ID will win a lot of the time.
So there are two reasons I can see for using element#id selector
I) It's to trump some convoluted rule, ie div#canvas>div>div#main>div:last-child>div
II) So you know what element it is referring to, ie if your div had and id of "postcodeContainer" and you were trying to find it in the html file, it might be harder because you have to look at every element (unless you used your IDE's search/find option), where as div#postcodeContainer you know you are looking for a div element.
div#someid - select a div with id someid
#someid - select any type of element with id someid
One reason for having the tag selector is that it assumes some basic CSS, like it's a block tag with zero margins/padding.
Is there any way with CSS to target all inputs based on their type? I have a disabled class I use on various disabled form elements, and I'm setting the background color for text boxes, but I don't want my checkboxes to get that color.
I know I can do this with seperate classes but I'd rather use CSS if possible. I'm sure, I can set this in javascript but again looking for CSS.
I'm targeting IE7+. So i don't think I can use CSS3.
Edit
With CSS3 I would be able to do something like?
INPUT[type='text']:disabled that would be even better get rid of my class altogether...
Edit
Ok thanks for the help! So here's a selector which modifies all textboxes and areas which have been disabled without requiring setting any classes, when I started this question I never thought this was possible...
INPUT[disabled][type='text'], TEXTAREA[disabled]
{
background-color: Silver;
}
This works in IE7
Yes. IE7+ supports attribute selectors:
input[type=radio]
input[type^=ra]
input[type*=d]
input[type$=io]
Element input with attribute type which contains a value that is equal to, begins with, contains or ends with a certain value.
Other safe (IE7+) selectors are:
Parent > child that has: p > span { font-weight: bold; }
Preceded by ~ element which is: span ~ span { color: blue; }
Which for <p><span/><span/></p> would effectively give you:
<p>
<span style="font-weight: bold;">
<span style="font-weight: bold; color: blue;">
</p>
Further reading:
Browser CSS compatibility on quirksmode.com
I'm surprised that everyone else thinks it can't be done. CSS attribute selectors have been here for some time already. I guess it's time we clean up our .css files.
Sadly the other posters are correct that you're
...actually as corrected by kRON, you are ok with your IE7 and a strict doc, but most of us with IE6 requirements are reduced to JS or class references for this, but it is a CSS2 property, just one without sufficient support from IE^h^h browsers.
Out of completeness, the type selector is - similar to xpath - of the form [attribute=value] but many interesting variants exist. It will be quite powerful when it's available, good thing to keep in your head for IE8.
w3 reference
browser support reference
You can do this with jQuery. Using their selectors, you can select by attributes, such as type. This does, however, require that your users have Javascript turned on, and an additional file to download, but if it works...
Sorry, the short answer is no. CSS (2.1) will only mark up the elements of a DOM, not their attributes. You'd have to apply a specific class to each input.
Bummer I know, because that would be incredibly useful.
I know you've said you'd prefer CSS over JavaScript, but you should still consider using jQuery. It provides a very clean and elegant way of adding styles to DOM elements based on attributes.