Confused by CSS selector - html

So.. I have this code:
<div id="slider">
<div class="current"><img id="img1" src="http://i.imgur.com/gWGqZly.png" /></div>
<div><img id="img2" src="http://i.imgur.com/mC1FD81.png" /></div>
<div><img id="img3" src="http://i.imgur.com/HFx9mqa.png" /></div>
</div>
As you can see the first div have a class named "current" and that's the div that i want to select. The divs are positioned on top of eachother with position: absolute;
My CSS:
#slider div {
position:absolute;
z-index: 0;
}
#slider div.previous {
z-index: 1;
}
#slider div.current {
z-index: 2;
}
I'm trying to give the first div, the one with class "current" a z-index of "2".
The selector i use for doing this is:
.current {
z-index: 2;
}
But that doesnt seem to work, that way the image wont appear on the top.
But if i instead write the selector this way:
#slider div.current {
z-index: 2;
}
Now it works.
And im a bit confused by this, doesnt those two selectors basically work the same way? What's the difference between them in this case?
Made a jsfiddle out of this https://jsfiddle.net/x1L4tfw4/5/ If you remove the "#slider div" part from the css selector you will see the difference.

You haven't stated that you have the #slider div selector in your CSS as-well.
This overrides the .current selector because its more specific.

This is a specificity issue. #slider div has a specificity of 101. #.current has a specificity of of 10.
#slider div.current comes in at 111.
The selector with the highest specificity is the one used. Now, how did I get those numbers?
The CSS standard says that you add numbers with an infinitely large base together to get it. In practice, you can think of it as being digits.
Tag names are worth one point.
Class names or attribute values are worth ten* points.
ID names are worth 100 points.
(and !important things are worth 1000 by the way).
So you add them up and see which has the highest number. That's the rule that gets applied. If two rules come with the same specificity, the one that appears last in the source code is the one that is used.
I said ten here for simplicity, but remember that the spec said infinitely large base (though browsers actually use base 256, fun fact). So ten classes do NOT equal one ID: a single ID is more specific than any number of classes (in theory).

The way you did the CSS is quite confusing . I Think you know that , these CSS do respect a straight forward system for ID and Class . Javascript Does care about ID . And Browser has their specific advantages for ID's . But CSS doesn't care about ID and class. Not until you pull this type of confusion .
Never use #id element .class in your stylesheet if you have more than one same <element-tag> in your markup. This will ruin the style .

This is due to the CSS specificity in the selectors that you're providing (or perhaps a third party library is providing). Here is a good resource to understand how CSS specificity and inheritance works.
Summary
Here is the key part from the linked article relating to how the different CSS selectors are related:
Element, Pseudo Element: d = 1 – (0,0,0,1)
Class, Pseudo class, Attribute: c = 1 – (0,0,1,0)
Id: b = 1 – (0,1,0,0)
Inline Style: a = 1 – (1,0,0,0)
I've included their examples below to help understand how this works:
p: 1 element – (0,0,0,1)
div: 1 element – (0,0,0,1)
#sidebar: 1 id – (0,1,0,0)
div#sidebar: 1 element, 1 id – (0,1,0,1)
div#sidebar p: 2 elements, 1 id – (0,1,0,2)
div#sidebar p.bio: 2 elements, 1 class, 1 id – (0,1,1,2)
Your Scenario
Now for your particular case. The first selector you use is .current which according to the information above has a specificity of:
.current (0,0,1,0)
As #Admir Geri noted in his answer, you also have a selector #slider div which has a specificity of:
#slider div (0,1,0,1)
Since the specificity of your second selector outweights that of the first, the second takes precedence and therefore you don't see your changes.
Your last selector #slider div.current has the following CSS specificity:
#slider div.current (0,1,1,1)
Since this score outweights that of any other selector. Your changes will be displayed when using this selector which is why you see them on the screen.

Related

Prioritize id selector over an id and class

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/

Last-child of a certain class isn't working

Can any body tell me how I use last-child selector to style my last div of subs?
This is my HTML -
<div class="main">
<div class="subs"></div>
<div class="subs"></div>
<div class="subs"></div>
<div class="subs"></div>
<div class="paginate"></div>
</div>
I tried it something like this in my CSS -
div.main div.subs:last-child {
border: none;
}
But its not working. If I remove paginate div, then it is working. So can I know how can I style last subs div without any extra id or class declaration.
Thank you.
Assuming there is only ever 1 element succeeding your .subs (.paginate), you can use this:
div.main div:nth-last-child(2) {
border:none;
}
See this JSFiddle
This can be seen as a little hacky, and if your paginate element is ever absent, then the wrong sub element will be targeted. Your only other option is to give the .subs their own container and then use :last-child:
Another JSFiddle
P.S: To understand why :last-child isn't working the way you want it to, I really recommend also reading Spudley's answer.
The problem you have is because of :last-child doesn't work the way you think it does.
The :last-child selector will select an element only if it is the last child of its parent.
In the case of your .main element, the last child inside it is the .pagination div. This means that .main>*:last-child can only select the pagination div. It doesn't matter if you filter it down by specifying .subs; you can't select anything else using :last-child because none of the other elements are the last child of .main. If the actual last child element isn't in the filtered selection, it will select nothing rather than selecting something that isn't the last child.
The best way to work around this is to wrap your subs elements inside an additional layer of markup, so that the last one then does become the last child of that container element. Either that, or move the pagination element outside of the main element; whatever works best for your layout.
The other selector you might have tried, :last-of-type works in a similar way. For the time being, there isn't a CSS selector you can use instead to pick the last .subs element, using your current markup. (unless you're happy to go with :nth-last-child(2) which will pick the second-last child, on the assumption that the pagination div will always be present).
In the new selectors being designed for CSS4, there is a set of 'match' selectors that would do exactly what you want to do. You would use :nth-last-match(1) to get the last matching element. This is the selector you need. Unfortunately, it isn't available in current browsers, and there's no real hint yet as to when (or even whether) it will be available in the future. For the time being, you can read about it here, but not use it. You might be able to use it or something similar via a JS library like jQuery.
Hope that helps explain things to you.
I would suggest that you add an extra class name to the last element. http://jsfiddle.net/5FQck/
div.main div {
border: #000 thin solid;
}
div.main div.subs.last {
border: none;
}
<div class="main">
<div class="subs">subs</div>
<div class="subs">subs</div>
<div class="subs">subs</div>
<div class="subs last">subs</div>
<div class="paginate">pagination</div>
</div>
None of the following selectors work in IE 8 and below, primarily because they are all CSS3 selectors.
:nth-child(N)
:nth-last-child(N)
:nth-of-type(N)
:nth-last-of-type(N)
You could also add that new class to the last element using JQuery: http://jsfiddle.net/5FQck/1/
$('div.main div.subs:last').addClass('last');
If I understand you correctly, I would do it like this.
.main .subs:nth-child(4)
{
border:none;
}

Why does my HTML not use the last style defined in the CSS?

I have the following CSS that's written in this order:
h2:last-child, p:last-child, ul:last-child {
margin-bottom: 0;
}
.content-message {
margin: 20px -1.667em -1.667em -1.667em;
margin-bottom: -1.667em;
}
and my HTML:
<ul class="content-message">
<li>xx</li>
</ul>
When I check I can see that the ul is getting its style from the the first
CSS and it has a margin-bottom of 0. Can someone explain why this is. Also
is there a way that I could fix this.
It is done in order of specifity. In this case, ul:last-child is more specific because it has two conditions:
It has to be a ul
It has to be the last child
Whereas your second style only has one condition:
It has to have the class content-message
In order to make the second style as specific as the first you need to add another condition:
ul.content-message {
margin: 20px -1.667em -1.667em -1.667em;
margin-bottom: -1.667em;
}
Because the two rules are equally as specific, the second rule takes precedence because it is written last. Note that this is a simplification of css specificity - the ordering works something like this:
Inline styles with !important
Stylesheet styles with !important
Inline styles without !important
Selectors containing an id (#myItem)
Classes, tag names, pseudo classes etc.
Any selector from higher up the list will take precedence, while two selectors from the same level will be determined by how many of that type there are (so two classes are less specific than an id, but as specific as a style and a tag). Two styles will the same weighting will defer to the last defined style.
I may be wrong on all items in point 5 having equal weighting, but for a better understanding check out http://www.adobe.com/devnet/dreamweaver/articles/css_specificity.html or similar articles found on Google.
See this article that describes css specifity issues- http://www.stuffandnonsense.co.uk/archives/css_specificity_wars.html
Preference order- element selector < class selector < id selector
So specifying it as an Id attribute should work
#content-message {
margin: 20px -1.667em -1.667em -1.667em;
margin-bottom: -1.667em;
and <ul id="content-message">
Update- In your case irrespective of the above cases, you inline style- style="margin-bottom: -1.667em;" will override any other css. Surprised to see that doesn't happen with you.
Please put a "!important" mark to which style you what to apply.

CSS precedence logic

In this example:
http://jsfiddle.net/Ja29K/
<style>
/* Default links */
a {
color: #0F0; /* Green */
}
/* Header links */
#header a {
color: #F00; /* Red */
}
/* Login link */
#login {
color: #00F; /* Blue */
}
</style>
<header id="header">
<p>header link is red</p>
<p><a id="login" href="#">login link</a> is not blue</p>
</header>
Is not logical that the login link must be blue?
I know that the declarations have the same origin and same importance, so they need to be scored (selector's specificity).
To calculate selector specificity I created an table for each selector:
A = Number of inline styles: 0
B = Number of ID: 0
C = Number of classes: 0
D = Number of elements: 0
So the login element have 3 collisions related to his color: a, #header a, #login
element (A, B, C, D)
a (0, 0, 0, 1) = 1
#header a (0, 1, 0, 1) = 101
#login (0, 1, 0, 0) = 100
The selector "#header a" wins because it had the biggest score.
But
If we change the selector "#login" to "a#login", we will have:
a#login (0, 1, 0, 1) = 101
The selector "#header a" looses, because with a draw wins the last that was declared.
So, the thing that I can't understand is:
Since "#header a" selector refers to many elements and an ID selector (e.g. #login) just refer one element, is logical that we want to apply ID selector declarations to that element, right? I really can't understand this CSS precedence logic, because I think ID selector must be basically the most specific thing possible, just like inline styles.
P.S.: Sorry for my bad english :)
No, according to the logic of selectors, it is not.
#header a is more specific than #login. If you reduced your #header a selector to #header, then the header selector and the login selector would have the same specificity, and the rule that was last expressed (in your order the color from login) would be used. The same would be true if you increased the specificty of the login selector by adding a tag name to it.
You can't see "specificity" in a sense of which selector targets the fewest elements but simply what is most important.
Of course could the rules have been made even more complicated by differentiating such things like #header a or a#login. However this just would add more confusion to the whole system.
Also most likely this (c/w)ould be abused like the following: header#header a - this added a higher specificity but also could target more elements.
In my opinion this would add no further value to the system but only make it more complicated.
When writing CSS one should always try to keep the rules as short as possible for performance issues. If you need to overwrite a rule you still have the possibility to add another id or class - in addition to the normal cascading this is really more than enough.
You seem to be familiar with the concept of specificity, which is thouroughly described as part of w3 css specs. From the algorythm perspective, selector specificity values in the rule declaration are flat-weighted or non-positional. This means that #header a and a#login have the same specificity, meaning that if an element is eligible for both rules, the latter one will take precedence.
Personally, it took me much longer to come to terms with selectors having semantic specificity but no calculatory value. For instance, ul li and ul>li have the same weight even though the latter "feels" more specific!
I find that anyone with functional programming background finds it easier to compare specificity as four-byte values (this is in fact close to how it's implemented in major browsers - consequently overflowing the value when 256+ selectors of the same weight are used :)
It's just down to specificity - be more specific and it will work for you:
header a#login {
color: #00F; /* Blue */
}​
OP, perhaps you could think of it that CSS processes the first argument (#header, and #login) first, and only after that, then it processes the second argument (a in "#header a").
So on the first process, it's made red, and then blue, but on the second process, it's overwritten to red, due to the "a" in the second argument.
All it takes to fix this is changing #login to a#login letting the DOM know this command is specific to a link.
The #header a is more specific than just #login because it's pointing at a specific element in the DOM, not just a random id.

How can I set css for a class in a class?

With this HTML code.
<div class="noote">
<p class="first admonition-title">Noote</p>
<p class="last">Let's noote.</p>
</div>
How can I set the color of Noote to be red with css?
I mean, how can I set something for (div class="noote") and (p class="first") under it with css?
Try this:
/*this will apply for the element with class first
inside the element with class noot */
.noote .first{
color:red;
}
/* If you wanted to apply a rule for both individually
you can do: */
.noote, .first{
border:1px solid red;
}
div.note{
...
}
Refers to the div element that has the class note.
p.first{
...
}
Refers to the p element that has the class first.
div.note p.first{
...
}
Refers to the p element inside note that has the class first.
In addition, if you want to set an element child without setting a class to it,
div.note p:first-child{
/* it refers to the first p that contains noote */
}
#amosrivera's got it.
It's worth nooting that descendant selectors require more CPU. I always use more specific rules where possible. So instead of
.noote .first{
backgorund:red;
}
You could say
.noote > .first{
backgorund:red;
}
A nominal difference in most cases, but still a good habit.
Really?
Descendant selectors are
inefficient... The less specific the
key, the greater the number of nodes
that need to be evaluated.
— Google "Let's make the web
faster" docs
And
Descendent selectors are a major slow
down to the Safari browser
— John Sykes, May 2008
Some performance tests show little impact, and most writers agree that it only makes a difference on very large documents.
But mainly, I'm just going with my programmer instinct — say what you mean, and no more.