Sometimes when I declare a value for something, and later I want to override it with different value it doesn't work.
For example (sass styling):
.wrapper-breadcrumbs {
h1.breadcrumb-title {
font-size: 46px;
}
}
And just below I put this...
#media (max-width: 768px) {
h1.breadcrumb-title {
font-size: 32px;
}
}
... it won't work, and I see in Chrome element inspection that the first one actually overrode the second value, even though the second statement is below first.
But if I repeat parent class names like this...
#media (max-width: 768px) {
.wrapper-breadcrumbs h1.breadcrumb-title {
font-size: 32px;
}
}
Then it works! For me it seems strange... is there any rule for this? Am I missing something? Why do I have to write parent class name?
It's because the first rule has higher specificity (2 classes and 1 element) vs 1 class and 1 element for the second rule.
The second rule needs to have same or higher specificity to override the first one. I recommend to take a look at Specifics on Specificity article on CSS tricks for more details.
As mentioned in the comments, you can also put !important after the font-size in the second rule, however that is typically a very bad practice and you should modify your CSS rule to have higher specificity instead, which is cleaner and will help you avoid headaches when debugging your CSS :)
It is due to first selector has higher precedent than second selector. Like Id selector has higher precedent than class selector. So if you apply any style using id selector and later own try to override it with class selector than it won't work.
.wrapper-breadcrumbs {
h1.breadcrumb-title {
font-size: 46px;
}
}
In this case you have two class and one attribute selector so its precedent is following.
precedent = (inline, id, class, element/ pseudo)
precedent = (0,0,2,1) //Left element has more precedent than right element.
#media (max-width: 768px) {
h1.breadcrumb-title {
font-size: 32px;
}
}
precedent = (0,0,1,1)
You can clearly see that first has more precedence than second selector so it will never work.
#media (max-width: 768px) {
.wrapper-breadcrumbs h1.breadcrumb-title {
font-size: 32px;
}
}
precedent = (0,0,2,1)
In this case it has same precedence as first element so it will overwrite the previous style and will work on this data.
You can use following link to calculate precedence of CSS selectors.
http://specificity.keegan.st/
Always try to overcome this problem by managing of the precedence of the selector instead of placing !important with CSS styling as it will override default precedence of selectors and in case of huge CSS make it difficult to debug it.
Related
https://codepen.io/everybodysfeelingwonderland/full/OjyRpM/
Somehow I can't change the color of my Nav links for a smaller screen size in my media query. It should turn white, but it just stays gray as for the bigger screens.
#media all and (max-width: 580px) {
nav li a,
nav ul li {
color: white;
text-align: right;
display: block;
}
}
nav li a {
text-decoration: none;
color: #666666;
font-size: 20px;
}
Media queries do not add specificity to a selector. They just control if the code inside is ignored or not.
Which means that...
#media (condition) {
a selector {
some value
}
}
a selector {
another value
}
...will always apply "another value", because it's placed later and has same specificity. You need to invert them and they will work as intended:
a selector {
another value
}
#media (condition) {
a selector {
some value
}
}
The media queries should be in the lowest section of the CSS.
If I first define the media queries; and define regular CSS below, the lower matches override the once defined before.
It's quite common to put media queries to the bottom part of the CSS.
Your media query rule should be after/below the regular rule. In your current code, the media query rule for nav li a is at line 104, the general rule is at line 162, i.e. after the media query rule - so it's overwriting the previous rule.
Just move your media queries to the bottom (or at leat below the according general rules if you wirte them one by one), this will fix your problem.
Making responsive website,
I wrote this, it doesn't work.
#media (max-width: 767px) {
#nav { display:block; }
}
but, I wrote this, it works!
#media (max-width: 767px) {
#nav { display:block !important; }
}
Why? :(
Check your css code , something with higher specificity is changing your #nav element.
This is a little concept:
!important after the style attribute gives high priority to that style. That is why your css is working then.
!important override the existing stylesheet attribute defined in same context.
!important will override any inline style, or more specific style that may be taking precedence on your page.
For example, you can override the style on this element...
<div style='background-color:white'></div>
by adding this in your stylesheet...
div { background-color: black !important }
But!, if you add !important to the inline style, it will then take precedence, for example...
<div style='background-color:white !important'></div>
here is a good stackoverflow answer explaining the concept in a bit more detail.
I'm trying to hide my menu by default in screens less than 760px wide. For some reason though, my display:none rule is not taking effect. It's being overridden by a previous rule, as follows:
media="all"
#mainmenu {
display:inline-block;
}
#media screen and (max-width: 760px)
.btncontent {
display:none;
}
It's also worth noting that I have a button that jQuery reveals the menu by adding an inline style. The above code is before the button is pressed though, with no inline styles.
I'm sure I'm missing something really simple here but not sure what. Thanks in advance.
EDIT: I've solved this issue by adding the ID selector to the Media Query but I'm going to leave this question open as I don't really understand why it worked.
Are #mainmenu and .btncontent the same element? If so, then the reason is simply because the ID selector is more specific than the class selector.
#media rules do not influence rule precedence in any way; they are transparent to the cascade, so style resolution takes place as if the enclosing #media rule wasn't there. In your example, when the media query is fulfilled, browsers see this, which makes it clear that the rule with the ID should take precedence:
#mainmenu {
display:inline-block;
}
.btncontent {
display:none;
}
Depending on how you added the ID selector to the second rule, you either balance or tip the specificity, allowing it to override as expected:
/* More specific */
#mainmenu.btncontent {
display:none;
}
/* Equally specific */
#mainmenu, .btncontent {
display:none;
}
Because the id is important.
Right way:
media="all"
#mainmenu {
display:inline-block;
}
#media screen and (max-width: 760px)
#mainmenu {
display:none;
}
If I add a style like:
* {
font-size: 14px;
}
and later I define for an element:
#myElement {
font-size: 18px;
}
The fist one will override the second one.
Is there a way to define the first one, such as the second one will override it, and the 14px size will be applied to all the elements that don't define a size?
(I would like alternatives to the use of classes)
The element #myElement will override the first rule as it is more specific. If #myElement has children then the children will match the global selector. Try setting the rule on body.
Use !important
#myElement {
font-size: 18px !important;
}
It's worth noting that in your example if you specifcally set a style on that element, be it a class or id, it will inherit properties but any specific styles it will overwrite. So doing the above is pretty pointless. This can be demostrated like so:
<style type="text/css">
* {
font-size: 60px;
}
#blah2 {
font-size: 14px;
}
</style>
<span id="blah1">i'm default size</span>
<br/>
<span id="blah2">i'm specially 14px</span>
fiddle: http://jsfiddle.net/garreh/3YuLD/
No, the first one will not override the second one. A selector with an id is more specific than a selector with an element, so the second will override the first one.
To override a rule you just have to make a rule that is more specific. Just count the number of id, class and element specifiers in the selector, where id is most specific.
You can read more about selector specificity here:
css.maxdesign.com.au/selectutorial/advanced_conflict.htm
The second rule should override the first one. Make sure your element has id="myElement". Use an inspector (such as Firebug or Chrome's Web Dev Tools) to see what styles are applied to your element an which are overridden.
In the linked code for the blueprint CSS framework, there is a style defined for a div.class selector and just the .class selector. Isn't this redundant? Or is there a more subtle reason for defining the class with two selectors?
https://github.com/joshuaclayton/blueprint-css/blob/master/blueprint/src/grid.css (lines 229-235)
/* In case you need to add a gutter above/below an element */
div.prepend-top, .prepend-top {
margin-top:1.5em;
}
div.append-bottom, .append-bottom {
margin-bottom:1.5em;
}
Interesting question. I've not used Blueprint, but then if you choose to override either div.prepend-top or .prepend-top, only that selector's styles will be overridden.
That means doing this:
.prepend-top { margin-top: 1em; }
Will leave the styles for <div>s with that class unaffected (still a 1.5-em top margin), because div.prepend-top is a more specific selector and so will take precedence for <div> elements.
And doing this:
div.prepend-top { margin-top: 1em; }
Will leave the styles for other elements with that class unaffected, because of the div type selector. Likewise for the append-bottom class.
Again I've not used Blueprint, but I think it has something to do with how it expects your HTML to be structured.