does the order of styles matter? - css

below is my markup. when i move the mouse over the hyperlinks they get underlined and turn red. but if i swap the order of the last two rules, the hyperlinks still get underlined, but their color changes to black rather than red. is this by design? if so, how are the rules applied?
thanks!
konstantin
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>
<style type="text/css" media="all">
.menu a
{
text-decoration: none;
}
.menu li:hover a
{
color: black;
}
.menu li a:hover
{
color: red;
text-decoration: underline;
}
</style>
</head>
<body>
<div class="menu">
<ul>
<li>item0</li>
<li>item1</li>
</ul>
</div>
</body>
</html>

If the rules are equal in specificity (in this case they are), individual rules get overridden in the order they're defined in the CSS, so in your example red wins because it comes later in the CSS definitions. The same rule applies in other cases as well, for example:
<div class="red green">
Which of these wins?
.green { color: green; }
.red { color: red; }
.red wins here, it doesn't matter the order in the class attribute, all that matters is the order the styles are defined in the CSS itself.

Consider the following HTML.
<div class="red">
Some red text...
</div>
And this CSS..
.red {color: red}
.red {color: blue}
.red {color: yellow}
You guessed it, the text will be yellow!

Yes the order matters, and in this case it is not really the order which is why you are having the same result regardless of the order.
The .menu li:hover a is applied to the li, which is a parent of the a and the hover is not applied to the a it is applied to the li.
The .menu li a:hover is applied to the a.
Regardless of the order the .menu li a:hover style will be applied to the a.
The better way to handle that is to have the hover pseudo selector applied to only the a element and make set display: block on it, with height and width set to 100%. This will fill the entire LI
Hope this clarifies things.

Yes, it does. The last point of the cascading order reads:
Finally, sort by order specified: if two declarations have the same weight, origin and specificity, the latter specified wins. Declarations in imported style sheets are considered to be before any declarations in the style sheet itself.

CSS rules are applied in order if they have the same specificity. In your case, they do, so order matters.
With the order you have in your question, the rules apply text-decoration: none. The second and third rules causes hovering the mouse over the link to modify those two styles in order because the a tag is inside the li tag. First, the color turns black; then, the color turns red and the underline appears.
Reverse the order of the last two rules like so:
.menu a
{
text-decoration: none;
}
.menu li a:hover
{
color: red;
text-decoration: underline;
}
.menu li:hover a
{
color: black;
}
Now, the text-decoration: none gets applied as before. Then, upon mouse-over, the first rule changes the color to red and adds an underline, followed by the color changing to black.

Related

Overwriting default bootstrap css with custom CSS only works with !important rule

basically I have already solved my problem, but I would like to understand why I needed to do it how I did it. Therefore I created a short example, available at https://jsfiddle.net/herbert_hinterberger/9x22u934/
Now I wanted to ask why I need to use the !important rule inside
.navbar-brand {
color: #eae8e8 !important;
}
to change the color of .navbar-brand? As of my understanding the custom CSS should overwrite the bootstrap default css rules. But for any reason the bootstrap default CSS rules are applied before the custom CSS rules if I do not use the !important rule. See
Can anybody please explain why I need to use here the !important rule?
Best regards,
Herbert
You don't need to use the !important every time.
The rule is, whatever css comes later is taken. So, if you have
.aClass {
color:red;
}
in red.css
and
.aClass {
color:blue;
}
in blue.css,
and you include blue.css after red.css, the text having aClass will be blue.
You only use !important when you want one rule to override everything else.
Edit: After the OP's comment, the actual answer to this question is this.
In the bootstrap.css file, we have something like:
.navbar-default .navbar-brand {
color: #hashtag;
}
therefore, when you do:
.navbar-brand {
color: #newHashtag;
}
it doesn't change the color of .navbar-brand that is invoked by .navbar-default (You use this class through .navbar-default in your HTML). Here, .navbar-brand is a descendant of .navbar-default. But, when you put in the !important, it tells all .navbar-brands to change color.
So, if you do want to change the color of your .navbar-brand, try something like:
.navbar-default .navbar-brand {
color: #newHashtag;
}
For more information, read up on descendant selector combinators in CSS.
When you want to overwrite bootstrap CSS with your own, you need to include your custom CSS after bootstrap.
<head>
<link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="css/custom.css">
</head>
This is because the css selector bootstrap is using '.navbar-header .navbar-brand' has more specificity than yours '.navbar-brand'
see this http://www.smashingmagazine.com/2007/07/27/css-specificity-things-you-should-know/
and try this
.navbar-header .navbar-brand {
color: #eae8e8;
}
Here is the best explanation for your Question
CASE: 1
<!-- HTML -->
<div class="blue box"></div>
/*CSS*/
div {
height: 200px;
width: 200px;
}
/*The Battle*/
.blue {
background-color: blue;
}
.box {
background-color: red;
}
In the Battle how wins? obviously last one i.e
.box {
background-color: red;
}
Background color red applied to div
Other Anwsers explain this case, writing custom css file after the bootstrap.css, it override bootstrap Styles
CASE: 2
ID vs. Class
<!-- HTML -->
<div class="box" id="box"></div>
/*CSS*/
div {
height: 200px;
width: 200px;
}
/*The Battle*/
#box {
background-color: blue;
}
.box {
background-color: red;
}
How Wins? obviously id Win, Id is declared as winner according to Rules of Specificity
Scores of elements according to specificity
inline-style = 1000 points (decided by css Specificity)
ID’s are worth a 100 points.
Classes are worth 10 points.
Elements are worth 1 point.
Example:
#content .sidebar .module li a{}
Score is :
#content =100; .sidebar, .module = 10 +10; li, a = 1+1
Total: 122
If we add one id at front as below We can overrides above mentioned style because the score of below mentioned style is 222
#main-container #content .sidebar .module li a{}

Understanding link pseudo class inheritence

I have a simple setup with a:link, a:visited a:hover and a:active all defined at the top of my style sheet. I also have a div where I've defined an a:link color for anchors inside of it. When I do this those links do not inherit the remaining pseudo classes for hover and active.... until I click that div's link and it has thus been "visited", at which point the pseudo classes start working. Why is this?
the CSS...
a:link {
color: blue;
}
a:visited {
color: purple
}
a:hover {
color: red;
}
a:active {
color: pink;
}
#theDiv a:link {
color: green;
}
the HTML...
The First Link
<div id="theDiv">
The Second Link
</div>
http://jsfiddle.net/ZKztj/7/
#theDiv a:link has a higher specificity than all your other selectors and is overriding them until the link no longer matches the :link selector, at which point it matches the :visited selector.
All browsers set a default style for anchor elements.
You need a more specific selector to override:
#theDiv a:hover {color:red}

Why CSS selectors on links are tricky with underline with hover?

Here are two examples based on this HTML.
<a href="#">
<div class="foo">
hello
<span class="bar">world</span>
</div>
</a>
In the first one, I make the link not underline on hover, then make a sub-portion of the link underline, and that works fine:
a {
text-decoration:none;
}
a:hover {
text-decoration: none;
}
a:hover .bar {
text-decoration: underline;
}
http://jsfiddle.net/3qPyX/1/
In the second, I now reverse the selectors so that the second word should be un-underlined. However, now something strange happens. The entire link remains underlined even though the selectors seem like they should remove underline from the second word. <-- (this is the question. why does this happen?)
a {
text-decoration:none;
}
a:hover {
text-decoration: underline;
}
a:hover .bar {
text-decoration: none;
}
http://jsfiddle.net/EAmwt/
Can someone explain what's going wrong in the second example? Inspecting with Chrome shows the span.bar has a computed style of text-decoration:none.
Update: a few answers explaining how to get around the problem, which is great except that's not really my question. What I want to know is why is this behavior different than, say, bold? For instance, if I try the 2nd example with bold, I get the expected results: http://jsfiddle.net/3qPyX/4/
Explanation:
The problem is that some properties (like text-decoration) get drawn to the whole parent inline element, whereas others - like font styling (that get inherited) - get overriden by the children properties.
Just for illustration: simmilarly, if you set a background color to a parent element it will paint the background of the parent ... and you would have to set another color to a child to lay it over (default - transparent - will still show the parent style through), but if you set font-weight at a child it will apply to the text inside the child element and override the parent settings.
You can find more detailed stuff on the text-decoration property in the CSS Level 2 and Level 3 Specifications.
A simple solution
withot changing the markup, you could just display .bar as inline-block.
Like so:
a {
text-decoration:none;
}
a:hover {
text-decoration: underline;
}
a:hover .bar {
display:inline-block;
}
And the inline-block breaks out of the inline/text styling of the parent anchor element =) And you can then style it independently:
DEMO
When you do the text-decoration it is applied to the entire line at once. So the a:hover .bar doesn't cause any effect, because the underline is not being applied in the .bar but on the a.
Here is the specification: http://www.w3.org/TR/CSS21/text.html#lining-striking-props
UPDATE! (As #Cam suggested) :
You need the add in separate elements the parts of your text: http://jsfiddle.net/3qPyX/5/
The CSS:
.foo, a:hover .bar, a {
text-decoration:none;
}
a:hover .foo {
text-decoration: underline;
}

CSS block level link color overrides to default in Chrome

I have block level links, which contain other block level elements with a different color.
The problem I have is that once you visited that link Google Chrome shows the a:visited color, and not the specific colors of his children.
I've made a jsfiddle as example: http://jsfiddle.net/yvesvanbroekhoven/UTwgU
You can see the difference in Firefox & Google Chrome. Click on the link and then it the colors of the title & text should be red/green, but in Chrome they become purple.
Any ideas?
This is invalid HTML. You can't havr a block level element within an inline one. Put links inside the other tags:
<h1>
Title
</h1>
<p>
Intro text
</p>
CSS
h1 a {
color: red;
}
p a {
color: green;
}
To style a visited link, use:
p a:visited{
color: green;
}
h1 a:visited {
color: red;
}
Demo here.
It is red/green in my chrome (v 14.0.835.202)!
Anyway you can set the colors as you want:
a:visited p{
color: green;
}
a:visited h1{
color: red;
}
seems to work as expected in Chrome 17.
If a link styles aren’t inheriting to child block-level elements, try using inherit, eg:
<header>
<style scoped>
a {background-color: #f9fda2;} /* highlight */
/* without inherit h1 won’t get the link’s background-color */
a h1 {background-color: inherit;}
</style>
<a href="/">
<h1>Title</h1>
<p>meta</p>
</a>
</header>

css and underline

Why is the link using the underline?
<html>
<head>
<style type="text/css">
body{
text-decoration: underline;
}
#text{
text-decoration: none;
}
</style>
</head>
<body>
Text text text <br/>
<div id = "text">
link
</div>
</body>
</html>
Because this is the default (user agent css have this rule, to apply underline in every tag a). The default isn't inherit, so even if parent tag has underline, the child won't get it.
EDIT 1:
For example, firefox have this rule:
*|*:-moz-any-link {
text-decoration:underline;
}
Default would be:
*|*:-moz-any-link {
text-decoration:inherit;
}
Then, in your example, the tag a would inherit div text-decoration.
EDIT 2:
You can overwrite default behavior with:
a {
text-decoration: inherit;
}
It's the default behavior of the a tag. It doesn't match the #text style.
I think you want to replace this...
#text{
text-decoration: none;
}
with this...
#text a:link{
text-decoration:none;
}
this tells the rule to apply to all anchors that are children of the tag who's id is 'text'
It's included in the default browser CSS. It's just as if this was included prior to your style tag:
a{
text-decoration: underline;
}
Sure, the link also matches #text, but since a is more specific, it wins. Any attributes not explicitly specified by the browser's a (such as font-size) will be inherited.

Resources