Specificity issue in CSS - html

So I have a list of items inside a div with the class book-select and one of the li's in my unordered list has the class selected. According to the CSS rules I've defined, the li's in the div has the background color skyblue and the one li with the class selected would be steelblue.
The problem is that the book-select class is overwriting the selected class, which I don't understand. Wouldn't the div class be less specific than the li with the class selected? The li is in a ul which is in the div.
Here's the relevant CSS and HTML:
.book-select li {
font-size: 0.75em;
text-align: center;
list-style: none;
background: skyblue;
width: 25%;
margin: auto;
}
.selected {
background: steelblue;
}
<div class="book-select">
<h2>Pick a book:</h2>
<ul>
<li>Set A Volume 1, Course Foundation</li>
<li>Set A Volume 2, Expeditionary Airman</li>
<li>Set A Volume 3, Professional Airman</li>
<li>Set B Volume 1, Supervisory Communicator</li>
<li>Set B Volume 2, Supervisor of Airmen</li>
<li class="selected">All</li>
</ul>
</div>
This is part of a quiz and the idea is that the user clicks on a book and jQuery will change the class of the selected item to whatever is clicked on, with the last li with the text "All" being the default selected book. I could use a different jQuery method to change the background color, but the fact that CSS is giving me this specificity error is bothering me.
I know .book-select li is overwriting .select because the console is showing the background: steelblue; as crossed off.
Shouldn't it be the other way around? Isn't .selected the more specific class, as it only contains one element, which is itself?

Use this selector to increase the specifity of that CSS rule:
.book-select li.selected {
background: steelblue;
}
About "specifity": Simply said, one class plus one tag (.book-select li) has more "weight" concerning specifity than just one class (.selected), so a rule with one class plus one tag will overwritea rule with just one class. And the selector shown above will overrule that again, since it consists of two classes and one tag.

Even Something as simple as
li.selected
{
background: steelblue;
}
Should overide the background for you :)

for a possible solution, you can do this:
.selected {
background: steelblue !important;
}
important will avoid this style from being override

Related

CSS Change On same DIV

I have this in line:
<div class="blue-car">
Car
</div>
<div class="iColor">
Blue
<div>
.blue-car:hover { color: red; }
.iColor:hover { color: read; }
I would like to make when someone hover to Car div second div which iColor change css and when hover to iColor div blue-car change css.
ie. I hover to 'Car' , 'Blue' will change color to red and when I hover to 'Blue' , 'Car' will change color to red, I want to make people aware that this two link is related.
I would love to have this in css only. No jquery. I have tried many no achievement at this moment.
Let me clear this, here is an example on this site. You could see when you hover to a country map, css link on right side will change, and you could see when you hover to a country link, country map css will change. This means this two div work each other. How they do this on this site: http://www.avito.ru
To start, CSS does NOT have a previous sibling operator. The only siblings that can be selected are adjacent (using +) or general (using ~).
It is possible to achieve the effect that you are seeking using only HTML and CSS. Below is one solution: http://jsfiddle.net/KGabX/. Basically, the .area is displayed as a table, which makes it wrap around the link and the image. However, the link is positioned absolutely, which prevents it from being "included" in a territory wrapped by the .area. This way, the .area is wrapped only around the image. Then, hovering over the .area we highlight the link. And, by hovering over the link we highlight the image.
Markup:
<div class = "area">
Link
<img src = "http://placehold.it/100x100" />
</div>
Styles:
.area {
display: table;
position: relative;
}
.area:hover > a {
color: red;
}
.area > img {
cursor: pointer
}
.area > a {
position: absolute;
right: -50px;
top: 50%;
font: bold 15px/2 Sans-Serif;
color: #000;
text-decoration: none;
margin-top: -15px;
}
.area > a:hover {
color: initial;
text-decoration: underline;
}
.area > a:hover + img {
opacity: 0.5;
}
Although I could not interpret what you wrote very well, I immediately noticed a flaw in your css selector.
Change your code to this:
<style>
.blue-car:hover a { color: red; }
.iColor:hover a { color: red; }
</style>
What's different about it? iColor:hover a. Look at the a, anchor selector. It was added because your previous CSS was only selecting the div. In css the child element, in this case the anchor, will supersede it's parents. There's two ways you can approach this. The first, or make the anchor tags color in css inherit.
If this wasn't your problem I'll fix my answer.
I'm not quite sure what you're asking because your question is a bit unclear.
From what I can understand, your issue stems from the fact that you're referring to the color property of the div, rather than the color property of the link.
That's a simple fix: all you need to do is drill down through the div to the link.
.blue-car:hover a{
color: red;
}
.iColor:hover a{
color: red;
}
Demo
Keep in mind that this isn't the best way to do this unless you absolutely need to refer to the links within the context of the div. I understand that your question fits into a broader context within your code, but for the example you gave here, all you really need is this:
a:hover{
color: red;
}
Again, I realize that you may need to change the colors or be more specific, but there's probably a better way to do this, even if that's the case.
The issue with this particular implementation is that your div is larger than your link, and a hover on your div is what activates the color change, so you'll run into this issue:

how to give two different states in css?

I have this problem in css where i have two different states in css for example
#koolbutton .active {
color: #fff
}
#koolbutton{
color: #ccc //not active
}
When i try this html
<button id ="koolbutton" class="active">
It gives me the the normal grey koolbutton not the active one which is white! thanks
You need to omit the space between #koolbutton and .active.
#koolbutton { /*not active*/ }
#koolbutton.active { /*active*/ }
The issue is with your first selector:
#koolbutton .active
Since there is a space between the id and class selector, this applies to every element with a class of active and an ancestor with an id of koolbutton. What you want is to select every element with a class of active and an id of koolbutton:
#koolbutton.active
Although the order of your selectors doesn't matter due to CSS Specificity rules, in terms of creating more maintainable CSS I would recommend you put the default styles first, followed by any variations to that style:
#koolbutton { /* default styles */ }
#koolbutton.active { /* .active styles */ }
#koolbutton.foo { /* Another class styles */ }
If you are really wanting to style active/focus states, you should probably look at the :focus and :active pseudo selectors.
You may try this one also;
#koolbutton:active {
color: #fff; //when user click the button
}
#koolbutton{
color: #ccc; //normal display of button
}
Here is the working Live Demo.

CSS Inheritance - Why is a 'later' declaration being overwritten by an 'earlier' one?

I'm new to html and CSS but through the recent work I've been doing I thought I was getting a hold of how CSS works.. And it seemed to work kind of like scope in a language like Java.
My understanding was that, like Java, the declaration with the narrowest scope wins.. aka the most specific declaration would override its inherited versions, allowing you to, like I am trying to do, declare a set pattern for a group of objects and then if one of those needs a slightly different setting you can simply override the general rule for that one item.
However, I'm getting the feeling this is not the case, here I have a tabbed content box I'm working on;
The html:
<div id="feature-tabs">
<ul id="tabs">
<li>What We Do</li>
<li><a id="large" href="#What Makes Us Different">What Makes Us Different</a></li>
<li>Our Background</li>
<li>Why We Do It</li>
</ul>
</div>
And of course I labelled the one list-item as "large" so that I could force its width to be a little wider so it can fit on one line.
The CSS:
ul#tabs li a {
width: 144px; //TRYING TO OVERRIDE THIS DECLARATION
height: 33px;
color: #42454a;
background-color: #fff;
border-left: 1px solid #000;
border-right: 1px solid #000;
text-decoration: none;
display: block;
text-align: center;
border-radius: 3px;
}
a#large {
width: 155px; //WITH THIS ONE
display: block;
}
What is happening is that the width of a"large" is being overwritten by a. (144px not 155px)
So, two questions:
Is it possible to do what I am trying to do here-override an inherited trait?
Is it possible to simply vertically align each of the 4 tab's text to be centered? (This would make up for the ugly look I'm getting from the one button being two lines, where the rest are just one)
See Cascading. The order in which the CSS is encountered is only used as a final resort.
Both selectors have the same media type.
Both selectors have the same importance and origin.
The specificity of your selectors are different
ul#tabs li a a=0 b=1 c=0 d=3
a#large a=0 b=1 c=0 d=1
The top one is more specific, so it's the one that will get used.
But if you used ul#tabs li a#large, it would get selected because it has the highest specificity.
ul#tabs li a#large a=0 b=2 c=0 d=3
The CSS specifications define some 'rules of specificity' that determine which properties override others. This article covers the basics of it.
The selector ul#tabs li a is more specific than a#large and therefore the properties from a#large that are also in the other ruleset are ignored.
One workaround is to use !important:
a#large {
width: 155px !important; // !important gives this property precedence
display: block;
}

Why does the hover pseudo-class override the active pseudo-class

The title basically says it all.
Suppose I have an element which I want to change color on :hover, but while clicked, I want it to switch back to its original color. So, I've tried this:
a:link, a:visited, a:active {
background: red;
}
a:hover {
background: green;
}
As it turns out, this doesn't work. After a lot of head-scratching, I realized that the :hover state was overriding the :active state. This was easily solved by this:
a:link, a:visited {
background: green;
}
a:hover {
background: red;
}
a:active {
background: green;
}
(I could combine the 1st rule with the 3rd one).
Here's the fiddle: http://jsfiddle.net/V5FUy/
My question: is this the expected behavior? As far as I understand this, the :active state should always override the :hover state, since the :active state will almost always be accompanied with the :hover state.
yes this is expected behavior,
lets take a look at another example. just adding two classes,
<ul>
<li class="item first">item</li>
<li class="item">item</li>
<li class="item">item</li>
<li class="item">item</li>
<li class="item last">item</li>
</ul>
here the class first also comes together with the class item.
but if we declare our css in the wrong order that would not give the wanted behavior
.first { background: blue; }
.item { background: red; }
as you can see, the last matching selector will be used.
it is the same as your example, no mather what is more logic,
the 2 pseudo-classes are concidered equal, thus the same rules apply
the last matching defenition wins.
edit
pseudoclasses are equals, it is the one defined last that wins! here is a jsFiddle that proves my point :link defined after :hover, :link wins (test) so, your statement of :hover overriding :link is wrong, its just the same like with :active, its all about the order.
The active state must be declared after the hover state, in your CSS you're clumping together the active state before the active state so it's not being triggered.
If you state the proper order of operation it works, like below, it works fine.
a.noworks:link, a.noworks:visited {
background: red;
}
a.noworks:hover {
background: green;
}
a.noworks:active {
background: red;
}
So, to answer your question, yes this is the expected behavior.
Here is the order of operation:
a:link
a:visited
a:hover
a:active
Because in the first code you defined :hover after you defined :active, so :hover "overwrote" :active. In the second, it's the other way around, :active overwrites :hover.
EDIT:
Sorry, I misunderstand the question.
Basically when you are in active state (with a mouse pointer) you are actually in hover state too. So based on CSS rules it would read the last one in stylesheet.
When you hover over a link and hold down the mouse key It's like this if we take pseud classes as normal classes :
<a class="active hover"></a>
So if your css was
.active{color:green}
.hover{color:red}
it would apply red
but if your css was
.hover{color:red}
.active{color:green}
It would apply green
From W3C
a:link { color: red } /* unvisited links */
a:visited { color: blue } /* visited links */
a:hover { color: yellow } /* user hovers */
a:active { color: lime } /* active links */
Note that the A:hover must be placed after the A:link and A:visited
rules, since otherwise the cascading rules will hide the 'color'
property of the A:hover rule. Similarly, because A:active is placed
after A:hover, the active color (lime) will apply when the user both
activates and hovers over the A element.
This is how it works, and I'll try to explain why. As we know CSS will continue searching the document when applying styles and apply the style that is most specific to the element.
Example:
li.betterList { better list styling here }
Is more specific and will overwrite
li { list styling here }
And these Puesdo selectors are all considered the same specificity and thus the last line will overwrite the previous one. This is confirmed by the note on W3Schools
Note: :active MUST come after :hover (if present) in the CSS definition in order to be effective!
you can also throw this CSS on your jsfidle and watch it overwrite since they are the same specificity
.works {background: red}
.works {background: green}
This is the expected behavior in so far as most people always place the :hover pseudo-class at the end of the group of rules.
Order of declaration matters with pseudo-classes (see more here: http://reference.sitepoint.com/css/pseudoclasses), so the final rules get precedence, as with other rules in CSS.
For most people, I think the desired behavior:
a:link {
⋮ declarations
}
a:visited {
⋮ declarations
}
a:hover {
⋮ declarations
}
Since the :active is not so useful it is left out... or combined with a:link and a:visited... and then it is overridden by a:hover
W3C spells it out here:
Note that the A:hover must be placed after the A:link and A:visited
rules, since otherwise the cascading rules will hide the 'color'
property of the A:hover rule. Similarly, because A:active is placed
after A:hover, the active color (lime) will apply when the user both
activates and hovers over the A element.
http://www.w3.org/TR/CSS2/selector.html#dynamic-pseudo-classes
Even W3schools gets this one right:
Note: a:hover MUST come after a:link and a:visited in the CSS
definition in order to be effective!!
Note: a:active MUST come after a:hover in the CSS definition in order
to be effective!!
http://www.w3schools.com/css/css_pseudo_classes.asp
I think you should at least consider the flow of User Interaction on links (or buttons).
Usually,
:link has always been the default (untouched),
Then when a User points to the button, then that is where :hover comes into play.
Once a User points to the link or button, then he/she will click, that is where :active comes in.
That is the standard sequence of how we interact with links (or buttons). With the exception of :visited, where the result is only obvious when the User has previously pressed the link.
It would be really helpful if you keep in mind the mnemonic: ' L o V e H A t e ' when dealing on links (except for :visited, which doesn't work for buttons).
However, if you really want to do an override, say, you want to change the color of a link that was already visited on active state, you can do something like:
a:visited:active {
color: red;
}
But the bottom line is, avoid changing the standard sequence if it's not necessary.
You can have the :active pseudo-class override the :hover pseudo-class regardless of the order of declaration by using the :not() selector.
a:link, a:visited, a:active {
background: red;
}
a:hover:not(:active) {
background: green;
}
This way, the :hover selector is triggered only when the :active selector is not.

Set a:hover based on class

I have the following HTML:
<div class="menu">
<a class="main-nav-item" href="home">home</a>
<a class="main-nav-item-current" href="business">business</a>
<a class="main-nav-item" href="about-me">about me</a>
</div>
In CSS, I want to set the a:hover for these menu items to a particular color. So I write:
.menu a:hover
{
color:#DDD;
}
But, I want to set this a:hover color only for those <a> tags with the class main-nav-item and not the main-nav-item-current, because it has a different color and shouldn't change on hover. All <a> tags within the menu div should change color on hover except the one with the current class.
How can I do it using CSS?
I tried something like
.menu a:hover .main-nav-item
{
color:#DDD;
}
thinking that only ones with main-nav-item class will change color on hover, and not the current one. But it is not working.
Try this:
.menu a.main-nav-item:hover { }
In order to understand how this works it is important to read this the way the browser does. The a defines the element, the .main-nav-item qualifies the element to only those which have that class, and finally the psuedo-class :hover is applied to the qualified expression that comes before.
Basically it boils down to this:
Apply this hover rule to all anchor elements with the class main-nav-item that are a descendant child of any element with the class menu.
Cascading is biting you. Try this:
.menu > .main-nav-item:hover
{
color:#DDD;
}
This code says to grab all the links that have a class of main-nav-item AND are children of the class menu, and apply the color #DDD when they are hovered.
Set a:hover based on class you can simply try:
a.main-nav-item:hover { }
how about
.main-nav-item:hover
this keeps the specificity low
try this
.div
{
text-decoration:none;
font-size:16;
display:block;
padding:14px;
}
.div a:hover
{
background-color:#080808;
color:white;
}
lets say we have a anchor tag used in our code and class"div" is called in the main program. the a:hover will do the thing, it will give a vampire black color to the background and white color to the text when the mouse is moved over it that's what hover means.
I found if you add a !important, it works when previously it didn't.
a.main-nav-item:link {
color: blue !important;
}
a.main-nav-item:visited {
color: red !important;
}
a.main-nav-item:hover {
color: purple !important;
}
a.main-nav-item:focus {
color: green !important;
}
a.main-nav-item:active {
color: green !important;
}
Also, I've read somewhere that the order is important. The mnemonic "LoVe HaTe" helps you remember it: link -> visited -> hover -> active
One common error is leaving a space before the class names. Even if this was the correct syntax:
.menu a:hover .main-nav-item
it never would have worked.
Therefore, you would not write
.menu a .main-nav-item:hover
it would be
.menu a.main-nav-item:hover