!important overriden by a class of child element - html

I have a very bad CSS rule (high specifity, use of !important) which sets color of text in a paragraph:
#wrapper .article .text {
color: green !important;
}
Then I put a simple span element in that paragraph and set color of the span text via simple class:
.black {
font-weight: bold;
color: black;
}
How come, that this simple class with low specifity and no !important flag overrides the parent rule?
Full snippet on codepen.io here: http://codepen.io/Jarino/pen/oXYeQZ?editors=110

This is simply because there is no more specific rule for that <span> than what you have declared in .black. Even though it is a child element of the <p> that has an important! flagged rule, it only inherits the color from it if it can find no more specific other color definition. Inheritance from a parent context is the least specific "rule" possible. Also, the !important part of a rule is not inherited, afaik.
If this were not the case, you would be very commonly forced to either use !importantwhenever an element takes a style that it already inherited from the parent, or you would have to constantly use very long selectors to make sure your child element selector does not have a lower specificity than the definition it inherits.
Also, compare what Mozilla says on the subject:
Styles for a directly targeted element will always take precedence
over inherited styles, regardless of the specificity of the inherited
rule.
https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity#directly-targeted-elements

The high-specificity rule applies only to the parent class. When it comes to it's children, the high-specificity of the parent class mellows down to a parent style that is inherited by the child.
And, when it comes to styling the child, all CSS rules specifically targeting it get precedence over the high-specificity rule of the parent.
If you do 'Inspect Element' for this child span tag in the Developer Console of your browser, you'll see how preference is given to CSS rules targeting that particular element that overrides all the parent styling that appears way down the list.

if you don't want your .black class to override the parent rule you can simply remove the color property from your .black class, the class mentioned in span will always have high specificity regardless of parent rule.

Because !important applies only for current element style not for child elements with specified same property.

How come, that this simple class with low specifity and no !important
flag overrides the parent rule?
Well, because they are two different rules.
You have your text class which is pretty strictly called but only a class without selector.
After you addded a span with a different class it will not be overwritten, because it's another rule. It gets applied to the span. And .text get applied to the paragraph.

Related

How is css specificity determined for elements with the same selector? [duplicate]

I'm trying to figure out why one of my css classes seems to override the other (and not the other way around)
Here I have two css classes
.smallbox {
background-color: white;
height: 75px;
width: 150px;
font-size:20px;
box-shadow: 0 0 10px #ccc;
font-family: inherit;
}
.smallbox-paysummary {
#extend .smallbox;
font-size:10px;
}
and in my view I call
<pre class = "span12 pre-scrollable smallbox-paysummary smallbox ">
The font (The overlapping element) shows up as 10px instead of 20 - could someone explain why this is the case?
There are several rules ( applied in this order ) :
inline css ( html style attribute ) overrides css rules in style tag and css file
a more specific selector takes precedence over a less specific one
rules that appear later in the code override earlier rules if both have the same specificity.
A css rule with !important always takes precedence.
In your case its rule 3 that applies.
Specificity for single selectors from highest to lowest:
ids (example: #main selects <div id="main">)
classes (ex.: .myclass), attribute selectors (ex.: [href=^https:]) and pseudo-classes (ex.: :hover)
elements (ex.: div) and pseudo-elements (ex.: ::before)
To compare the specificity of two combined selectors, compare the number of occurences of single selectors of each of the specificity groups above.
Example: compare #nav ul li a:hover to #nav ul li.active a::after
count the number of id selectors: there is one for each (#nav)
count the number of class selectors: there is one for each (:hover and .active)
count the number of element selectors: there are 3 (ul li a) for the first and 4 for the second (ul li a ::after), thus the second combined selector is more specific.
A good article about css selector specificity.
Here's a compilation of CSS styling order in a diagram, on which CSS rules has higher priority and take precedence over the rest:
Disclaimer: My team and I worked this piece out together with a blog post (https://vecta.io/blog/definitive-guide-to-css-styling-order) which I think will come in handy to all front-end developers.
What we are looking at here is called specificity as stated by Mozilla:
Specificity is the means by which browsers decide which CSS property
values are the most relevant to an element and, therefore, will be
applied. Specificity is based on the matching rules which are composed
of different sorts of CSS selectors.
Specificity is a weight that is applied to a given CSS declaration,
determined by the number of each selector type in the matching
selector. When multiple declarations have equal specificity, the last
declaration found in the CSS is applied to the element. Specificity
only applies when the same element is targeted by multiple
declarations. As per CSS rules, directly targeted elements will always
take precedence over rules which an element inherits from its
ancestor.
I like the 0-0-0 explanation at https://specifishity.com:
Quite descriptive the picture of the !important directive! But sometimes it's the only way to override the inline style attribute. So it's a best practice trying to avoid both.
The order in which the classes appear in the html element does not matter, what counts is the order in which the blocks appear in the style sheet.
In your case .smallbox-paysummary is defined after .smallbox hence the 10px precedence.
First of all, based on your #extend directive, it seems you're not using pure CSS, but a preprocessor such as SASS os Stylus.
Now, when we talk about "order of precedence" in CSS, there is a general rule involved: whatever rules set after other rules (in a top-down fashion) are applied. In your case, just by specifying .smallbox after .smallbox-paysummary you would be able to change the precedence of your rules.
However, if you wanna go a bit further, I suggest this reading: CSS cascade W3C specification. You will find that the precedence of a rule is based on:
The current media type;
Importance;
Origin;
Specificity of the selector, and finally our well-known rule:
Which one is latter specified.
Also important to note is that when you have two styles on an HTML element with equal precedence, the browser will give precedence to the styles that were written to the DOM last ... so if in the DOM:
<html>
<head>
<style>.container-ext { width: 100%; }</style>
<style>.container { width: 50px; }</style>
</head>
<body>
<div class="container container-ext">Hello World</div>
</body>
...the width of the div will be 50px
AS is state in W3:
W3 Cascade CSS
the orden that different style sheet are applied is the following (quote from W3 cascading section):
user agent declarations
user normal declarations
author normal declarations
author important declarations
user important declarations
More information about this in the referred W3 document
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)
Inline css ( html style attribute ) overrides css rules in style tag and css file
A more specific selector takes precedence over a less specific one.
Rules that appear later in the code override earlier rules if both have the same specificity.
In a simple and short way, one should keep in mind the two things below:
Inline CSS has a higher priority than embedded and external CSS.
So final Order is: Value defined as Important > Inline > id nesting > id > class nesting > class > tag nesting > tag

Css class with multiple html elements

I am new to front end development, especially the styling.
I find css classes written like shown below:
.Header-bar p {
font-size: 18px;
}
.Header-bar p span {
font-weight: bold;
}
.Header-bar p span span {
font-weight: normal;
}
I understand that this means to apply font-weight: normal; to the span element which is inside another span element which is in p under div where the class is mentioned.
This doesn't seem like a good practice. I want to create re-usable classes that I can use in my code.
How should I be changing this style to better align to my needs.
When we are talking about styling and CSS I think it's important to keep in mind the specificity levels of a CSS selector.
What is Specifcity ?
It's what defines how broad the scope of your stylying rule is.
Simply put :
The less specfific a rule is - the more abstract it is - and the more elements it will capture.
The more specific a rule is -less abstract it is - and less elements will capture.
More specific rules overwrite/replace less specficic rules.
In your example you have chosen a a rule style , which is applied to a very specific element , in this case .Header-bar p span span {font-weight: normal;} and ONLY that element.
However , if you had only written .Header-bar{font-weight: normal;} it would work aswell , except you would be applying that style to not ONLY that element but also ALL the other elements which are contained in that class.
When you want to be more specific and not write all the path to get to that element, you can simply give the HTML element an ID and use it then on CSS , like this , for example :
<footer>
<div>
<div>
<p id="IDsomething"></p>
</div>
</footer>
</div>
Then select on CSS :
#IDsomething { font-weight :
normal;
}
There are four categories which define the specificity level of a selector:
Inline styles - An inline style is attached directly to the element to be styled. Example: <h1 style="color: #ffffff;">.
IDs - An ID is a unique identifier for the page elements, such as #navbar.
Classes, attributes and pseudo-classes - This category includes .classes, [attributes] and pseudo-classes such as :hover, :focus etc.
Elements and pseudo-elements - This category includes element names and pseudo-elements, such as h1, div, :before and :after.
You can easily create a particular unique class that's going to be for a particular styling or set of styling. For example creating a class called "normal" and then adding the font-size property of normal, it'll be easily re-usable that way i.e you can add it to any part of your code if you want the font-weight styling of that particular element to be normal.
Just apply a class to the span which you want to style, then create a CSS rule for that class. Selectors like .Header-bar p span span are rather used when you can't change the HTML code (or at least the structure) yourself.
Concerning reuseability of classes: That class can be used on as many elements as you like, and those elements can be divs, spans, headings or whatever.

different css on same element by id, class etc

There is one <p> tag with class .eleclass and id #eleid and i have specified 3 css to the <p> tag one specified with class second with id and third with just p declared.
p#eleid{
color:yellow;
}
p.eleclass{
color:blue;
}
p{
color:red;
}
<p id="eleid" class="eleclass">
hello para.
</p>
Now i wonder why the rule applied to p#eleid is working when css runs from top to bottom nature and at bottom color red is specified so <p> should be red in color.
Is there any css rules hidden behind it??
This problem inclues use of id not only class.
It comes down to CSS specificity.
From MDN:
Specificity is the means by which browsers decide which CSS property values are the most relevant to an element and, therefore, will be applied.
As it happens, an ID based selector has higher priority than a tag based selector. This is because an ID is more specific than a tag. In other words, the tag selector applies to all p elements, while the ID will only apply to the p with the ID.
There are ways around specificity, such as the !important keyword - however, I mostly recommend against working around specificity, as it can lead to bugs.

Exclude Span From Global CSS Span Styles Inline

Lets say you have a global CSS of:
span {color: purple;}
Now take this line of code:
<h1><span>Hi</span></h1>
Is there a way to INLINE exclude it?
I obviously can do this through stylesheets or jquery, but my particular use case would need to basically say, I am just a regular tag, don't apply any global css span style to me.
Is that even possible?
I'm quiet sure that there's no way exclude that element based on its parent, however you could override the applied color - for instance - by using inherit value (or any other value you want):
Example Here
h1 span { color: inherit; }
So that the nested <span> inherits the color from its parent, the <h1>. It is supposed to work on IE 8+.
6.2.1 The 'inherit' value
Each property may also have a cascaded value of 'inherit', which means
that, for a given element, the property takes the same specified value
as the property for the element's parent. The 'inherit' value can be
used to enforce inheritance of values, and it can also be used on
properties that are not normally inherited.

Do CSS / HTML children override parents?

Given the following code:
<div id="bla">
<p class="blubber">Johnny Bananas</p>
</div>
and the style in head of that html doc:
<style>
div#bla{background:yellow}
p.blubber{background:purple}
</style>
Why is it that the child will be coloured purple and overlay its parent?
The background property is not inherited by children by default. Therefore, the background style of div#bla does not apply to p.blubber, and p.blubber can specify its own background color independently of its parent and regardless of specificity.
And since background isn't being inherited, no overriding actually takes place.
When multiple style sheets are used, the style sheets may fight over control of a particular selector. In these situations, there must be rules as to which style sheet's rule will win out. The following characteristics will determine the outcome of contradictory style sheets.
check out the section on cascading order - http://htmlhelp.com/reference/css/structure.html
Because the specificity is the same, so the rule will apply to the p element. If you remove the p and just have .blubber, it wouldn't work.
Also, children can't override parents, so if there were more content, you'd see yellow around the p (add padding to the div).
Background color is not and inherited attribute in CSS.