Let's say I have the following HTML:
<span id="id1" class="class1 class2">This is a test</span>
and if #id1, .class1 and .class2 all have different sets of mutually exclusive CSS rules, which one wins? I have been testing an example and in one case it's choosing (I think) the one that is listed at the bottom of the CSS file, but in another case it seems non-deterministic.
Is there a specific rule in this case?
The basic principle of cascading in CSS is that you have one element, and one or more CSS rules that apply to the same element (because the element matches their selectors). In this process, all applicable styles are computed, with any conflicts resolved (or cascaded), and then, well, applied.
If the rules and their declarations are mutually exclusive, then none of them "wins" over any of the others per se, since there's no conflict to resolve and therefore nothing to override. For example, if you have these rules:
#id1 {
color: red;
}
.class1 {
border-width: 1px;
}
.class2 {
border-style: dashed;
}
Then your element will have red text and a dashed red border that's 1 pixel thick. There are no conflicts, so all of them will combine in effect. (Note that the border is red due to special behavior.)
jsFiddle preview
It's only when you have the same property declared in more than one rule that selector specificity and cascading become relevant, because then you'd need to override values for that same property. In that case, then as already mentioned IDs take precedence over classes and equally-specific rules are applied from the top down; read about selector specificity.
For example, if you have these rules:
#id1 {
color: red;
}
.class1 {
text-decoration: underline;
color: green;
}
.class2 {
text-decoration: none;
color: blue;
}
Then your element will have red text with no decoration, because
the color value in #id1 overrides that in both classes, and
the text-decoration value in .class2 overrides that in .class1.
jsFiddle preview
Remember that all this has to apply to the same element. If you have a parent that only has an ID, with a child that only has a class, then none of this will apply because you're dealing with entirely separate elements. What comes into play instead is inheritance, which is also covered in the document I link to above.
CSS reads up to down, so class2 will win!
More Info
http://css-tricks.com/specifics-on-css-specificity/
ID will take precedence over class.
If an element has same styles defined multiple times using ID, the latter will take precedence over the former except the case that you're using !important
The order of precedence with CSS is as follows:
1. !important
2. Inline styles which defined inside an HTML element
3. Internal styles which defined in the head section
4. External stylesheet which is a link to a sheet (<link rel="stylesheet" type="text/css" href="style.css" />)
5. Browser default
This is easy - the one that is closer and more refined win (just like life)
I.e.
Got a blank sheet then:
Start off with class - apply those (aka class1, class2)
But you know about that individual (id)
And then apply that..
So (if there is a "winner") the id wins
Unless the tag has style in its attributes - That would win
Related
test.html
<html>
<head>
<link rel="stylesheet" type="text/html" href="external_1.css"/>
<link rel="stylesheet" type="text/html" href="external_2.css"/>
<link rel="stylesheet" type="text/html" href="local.css"/>
</head>
<body>
<span class="class1 class2">Some text</span>
</body>
external_1.css
.class1 {
color: red;
font-weight: bold;
}
external_2.css
body .class2 {
color: green;
font-style: italic;
}
local.css
body .class2 {
color: remove-property;
}
external_1.css and external_2.css files are external and I can't change those. All I can do is to override them with local.css
My question is: How can I override the class .class2 and remove the property color in a way that the property from .class1 is applied to the span, to in the end the properties on span would be:
{
color: red;
font-weight: bold;
font-style: italic;
}
Edit: I don't know what the property value in .class1 is. Maybe it's dynamic, I shouldn't set color: red; in local.css.
Edit : As you edited in your question, it changes the entire meaning of what you have asked. CSS is not a dynamic language hence it cannot decide on its own or even conditionally of what to pick and what not to. You need to specify the properties for each rule.
Things you should do in such cases is to use CSS Preprocessors which are capable of conditional CSS rules and can nest the rules inside other or you need to change your dirty way of tackling these issues by getting rid of such confusing way of declaring classes.
Or you can use JS at last to tweak up the markup on the run.
This is where specificity comes handy, all you need to do is to write a rule in your local.css file which is more specific than your previous loaded CSS files.
.wrapper span.class1.class2 {
color: red;
}
Demo
Lets assume that you have SOME kind of wrapper element with a class or an id on it, all you need to do is to write a specific selector to override the color of your span element from green to red.
Surely you can use things like !important but I suggest you not to use so because later it will give you more specificity issues so keep it simple and write a specific selector in your local.css stylesheet.
Also whats the great thing about this is that you won't have to worry anymore how your stylesheets are loaded and in what order till you have a specific rule which will override the base ones.
Last but not the least this will target all the span elements having both the classes nested under an element with a class of .wrapper so if you want to be more specific simply address the only span you want to target. Surely you can use nth-child or nth-of-type to select the span precisely.
You have to redefine color. CSS is not dynamic, as you are saying you have no control on both external css. There is no option so you can use external_1.css's .class1 color value. If you try to call external_1.css after external_2.css, still external_2.css class will be preferred because it has deeper element declaration...
body .class2{color:green;}
while in external_1.css only class declaration...
.class1{color:red;}
I have a situation in which I load a style with a selector that should be prioritized over another.
The situation looks like the one in this fiddle, in which a specific id selector is not being prioritized over another one that uses a class that is under a specific id.
--HTML
<div id="cont">
<p class="hello" id="hello">I wish I was blue</p>
</div>
--CSS
#hello {
color:blue;
}
#cont .hello {
color:red;
}
Result is red text
I'm pretty sure this could be possible without using !important - which I really would like to avoid since this will be maintained by designers with no css skills for A/B testing. I want to make a selector for them that they will only edit it's properties.
Edit: To be clear, the #hello selector is injected to the page and I want to change it to one that actually works, but I don't want to change the other selector for that purpose. Of course if I have no choice I will, but it seems reasonable to be that this css is valid as it is and overriding that selector should be possible without modifying it.
Simply use the :not selector to exclude the #hello element.
Change the first to:
#cont .hello:not(#hello) {
color:red;
}
Demo Fiddle
More on :not from MDN
The negation CSS pseudo-class, :not(X), is a functional notation
taking a simple selector X as an argument. It matches an element that
is not represented by the argument. X must not contain another
negation selector, or any pseudo-elements.
Alternatively- per the comments below, you can increase the specificity of the second selector whilst providing variations for various contexts:
#hello, #cont #hello, #hello.hello {
color:blue;
}
Demo Fiddle
I suggest you to add another id selector to the first set of CSS rules.
#cont #hello {
color:blue;
}
#cont .hello {
color:red;
}
DEMO http://jsfiddle.net/a_incarnati/53q74jah/
In this case the color was overridden in red because you were using just one id selector #hello and that it's less specific than a selector with 2 ids combined or one id and one class combined, like you have done:
#cont .hello {
color:blue;
}
One of the things to take into account when writing CSS code, it’s the concept of CSS specificity. Understanding well this concept will avoid you to have to use !important;
As Mozilla Developer Network defines it, specificity is nonetheless:
Specificity is the means by which a browser decides which property
values are the most relevant to an element and gets to be applied.
Specificity is only based on the matching rules which are composed of
selectors of different sorts.
The following list of selectors is by increasing specificity:
Universal selectors
Type selectors
Class selectors
Attributes selectors
Pseudo-classes
ID selectors
Inline style
You can measure specificity counting how many selectors are present in a CSS statement.
CSS Specificity can be represented by 4 columns of priority:
inline=1|0|0|0
id=0|1|0|0
class=0|0|1|0
element=0|0|0|1
Left to right, the highest number takes priority.
You don't need two different selectors. You can keep one:
.hello {
color:red;
}
#cont .hello {
color:blue;
}
http://jsfiddle.net/vkftfj2n/4/
Consider the following HTML markup:
<input id="foo" class="bar" name="baz">
Are the following selectors equal (or even valid):
CSS
input#foo.bar[name=baz] { }
input.bar#foo[name=baz] { }
input[name=baz].bar#foo { }
/* etc */
And is it possible to move the element name to, say, end?
Edit: I know what specificity is, I want to know in which order the tag, id, class and attributes need to be specified.
They are all valid, as they comply with the syntax of sequence of simple selectors. They are equivalent, since their meaning, including specificity, are defined in a manner that does not depend on the order of the components.
It is not possible to move the element name (type selector) to the end, for purely syntactic reasons. The spec says that a simple selector “always begins with a type selector or a universal selector. No other type selector or universal selector is allowed in the sequence”. This is to be interpreted so that the type selector, if present, must appear first. This is natural since there would be no way to distinguish it from e.g. a preceding class selector (a space could not be used since it has a quite special meaning in CSS selector syntax: .bar input is a valid selector and means something quite different from input.bar).
Please refer the answer of #Jukka as OP seemed to have changed the meaning of the question by minor edit, but if anyone's interested in specificity question before edit, than please read ahead.
First of all, neither of the selectors make sense, to be true, they are over specific.
Your selector holds an id which will be unique, so defining class as well as attr=val is not required
(If you are not using the same id for other element in some OTHER document..)
If for some case, you need them, say to override, like... (makes sense)
input#foo.bar[name=baz] {
/* More specificity overrides the selector below */
}
input[name=baz] {
/* Styles here */
}
Are the following selectors equal - YES, they are equal as far as the specficity goes, they all return a score of 121
Credits
(or even valid) - Completely Valid
Does order of tag(Not relevant), id, class - NO, whatever the order of attributes are, it doesn't matter.
BUT
The order of your CSS declaration block in the stylesheet matters, the last selector will override common properties as all the three selectors have equal specificity.
Demo (All three will render green text, regardless of the order of their attributes, but if you shuffle the CSS selectors block, the last one will override the common properties of previous two selectors - unless you define !important in one of the selector properties)
And is it possible to move the element name(Attribute) to, say, end? - YES
Pros & Cons —
All the selectors are overspecific
Bad as far as performance goes
Using attr=val selector, you are assuming that the value of the name attribute won't change, if it does, you will have to change your selectors as well.
P.S : Have an habit of quoting the attribute values.
Those are all legal:
<input type-"text" id="foo" class="bar" name="baz">
input#foo.bar[name=baz] { border:1px solid blue; }
input.bar#foo[name=baz] { border:1px solid red; }
input[name=baz].bar#foo { border:1px solid green; }
http://jsfiddle.net/hGj5B/
Remove the various style blocks and note that each selector will select the textbox.
By "equal", if you are asking is they have equivalent specificity, then the answer is yes given each selector has the same amount of elements, classes, attribute selectors, and ids. Since they are all equal, the order of the blocks in your stylesheet will serve to determine which conflicting styles will win out.
You cannot move the element to the end, as the other segments of the selector describe it by coming after.
Yes all of them are legal , But while execution the Later one Will over ride the Earlier Declarations,but some exceptions are there
check the Flow exceptions Here
input[name=baz].bar#foo { border:1px solid green; }
input.bar#foo[name=baz] { border:1px solid red; }
input#foo.bar[name=baz] { border:1px solid blue; }
input { border:1px solid #000000; }
http://jsfiddle.net/hGj5B/
for More Details Refer this Question..
The sequence of execution of CSS
I am trying to change the font for the whole page in HTML. By whole I mean everything: buttons, forms, etc. Is there a way to do this in CSS?
html {
color: green;
}
This would make the text green, but not the text of buttons.
Well, there's universal selector:
* {
color: green;
}
Take note, though, that specificity of this selector is the lowest (MDN).
Wild card selector
* {
color: green;
}
It may be the case that you need to over ride inline CSS and javascript generated CSS. In this case use !important as well
* {
color: green !important;
}
Use the * universal CSS selector.
The universal selector matches any element type. It can be implied (and therefore omitted) if it isn’t the only component of the simple selector.
The selector div * will match the following em elements:
"Universal" in the h1 element ( matches the <h1> )
"emphasize" in the p element ( matches the <p> )
"not” in the first li element (matches the <ul> or the <li>)
"type” in the second li element (matches the <ul> or the <li>)
Example:
This rule set will be applied to every element in a document:
* {
color: green;
}
Also to add, it's compatible with most browsers, although it can be buggy in Internet Explorer 5.5, 6.0, 7.0.
If you don't need to support IE < 8, and want something that's less smelly, set an explicit color only on html and force everything else to inherit the color. Colors are already inherited by default on most elements, but not all of them.
Since this means applying two different color declarations, you will need two separate rules:
html {
color: green;
}
body * {
color: inherit !important;
}
Honestly, you shouldn't rely on a wildcard selector for doing this. You should take advantage of CSS's native inheritance. The best thing to do would be to remove the specific color declarations from your stylesheet (as needed) and add the color to your body or html tag. Using a wildcard is similar to this, except you are declaring that every single element should have the CSS as apposed to the native inheritance.
I have a template that has a lot of CSS formatting, but now when I try to add my text I cannot add any formatting to it. Within a paragraph, I try to put superscripts, italics, but nothing works. Is there a way around this?
Here's a little explaination about overiding CSS
I'll take for my example this simple HTML :
<div id='home' class='current'></div>
If you have, for example, a css like
#home{color : blue;}
.current{color : orange;}
The text will be blue since #home is "stronger"
If we put values to selector: id=10 class=5 node selector (div) = 1
so #home = 10 and is higher than .current wich equal 5, #homestyles will override.
you could use li.current but again, 5+1=6 wich is lower than an id.
But #home.current will equal 15! Wich will overide #home styles!
But if your color style is on the node itself within the attribute style="" you have to remove it with jquery or use !important :
.current{
color: blue !important;
}
It will override EVERY css but it is not recommended.
Note that the value i am using are not the exact one, so .parentClass .class will maybe not over an id and i can't find the original values... But keep in mind that the more selective you are, the more chance you have to override a style.
At last, if you have 2 selector with the same value, the last one called will be the one overriding.
Use chrome inspector or firebug to see what's overriding what.