So I have a div with class='content' and inside that, another div with attribute style='background-color:#FF0000' so my code looks like the following:
<div class='content'>
Here is some text outside the red background div
<div style='background-color:#FF0000'>
Here is some text inside the red background div
</div>
</div>
And in my stylesheet I have the following:
[style^='background'] {
color:#00FF00
}
This works and I get green text inside the red background. However:
:not([style^='background']) {
color:#00FF00
}
This still makes the red background text green, along with everything else in the document. I have tried the following:
div:not([style^='background']) {
color:#00FF00
}
.content :not([style^='background']) {
color:#00FF00
}
:not([style]) {
color:#00FF00
}
Yet all of these make the red-background text green, when clearly I have the :not selector.
However, I have elsewhere:
.content div:not([style^='text-align']) {
color:#1f1f1f;
}
.content div :not(span[style^='font-size: 150%']) {
color:#EEE;
}
And these work just fine.
So I don't understand why the red background div won't work at all and is selected by the :not selector?
Example:
:not(.content) {
color:#FF0000
}
<div class='content'>
Here is some text that shouldn't be red
</div>
color is an inherited property. So if your element has no color set, it inherits the color from the next ancestor element that has a color defined. In your example,
:not(.content) { color: #F00; }
this also targets the body element, so your div.content inherits color: #F00;.
To avoid this, specify inherited properties on the elements you don't want inheritance on.
.content { color: green; }
:not(.content) {
color: red;
}
<div class="content">
Here is some text that shouldn't be red
</div>
Quirks, tricks, and unexpected results of :not
:not(.foo) will match anything that isn't .foo, including <html> and <body>.
You need to increase specificity to avoid this, e.g. div:not(.content).
In addition:
div:not([style^='background']) {
/* also targets parent divs */
color: #00FF00;
}
.content :not([style^='background']) {
/* You have a space here - this targets _children_ of .content
that are :not([style^='background']. Is this what you want? */
color: #00FF00;
}
Remember that the "C" in "CSS" stands for cascading, and one aspect of that is inherited styles. Many styles (such as color) affect children of matched elements too, not just the element itself.
Related
This question already has answers here:
How to affect other elements when one element is hovered
(9 answers)
Closed 1 year ago.
My scenario is I want the hover effects of the parent element to be applied to the child elements, effectively over-riding styling settings of the children, and I want to this to be strictly CSS. I can do it easily enough with javascript, but is there a pure CSS approach? Thanks for any suggestions.
div {
}
div:hover {
background-color: red;
/*change contained span backgound-color to red as well*/
}
span {
background-color: yellow;
}
<div>When I mouse over this div, I want the <span>the contained span background</span> to take on the hover settings of the parent div.</div>
If I understand your question correctly, then add another hover specifying all-child elements as *, applying the inheritance rule.
div:hover * {
background-color: inherit;
}
Snippet:
div {
}
div:hover {
background-color: red;
/*change contained span backgound-color to red as well*/
}
div:hover * {
background-color: inherit;
}
span {
background-color: yellow;
}
<div>When I mouse over this div, I want the <span>the contained span background</span> to take on the hover settings of the parent div.</div>
div {
}
span {
background-color: yellow;
}
div:hover span {
background-color: red;
/*change contained span backgound-color to red as well*/
color:#fff;
}
<div>When I mouse over this div, I want the <span>the contained span background</span> to take on the hover settings of the parent div.</div>
I need to override the children color when its parent has specific class.
.parent {
width: 100%;
}
.parent>.child {
color: black;
}
.parent>.child.blue {
color: blue;
}
.parent.error {
color: red !important;
}
.parent.error>.child {
color: red !important;
}
<div class="parent">
<div class="child">Child #1</div>
<div class="child blue">Child #2</div>
</div>
When the parent class is added with "error" using jquery $('.parent').addClass('error'), only Child #1 color changes to red. Child #2 (which has extra blue in its class) <div class="child blue">Child #2</div> stays blue.
The question is, how to force Child #2 to change its color to red without specifying .parent.error > .child.blue for error class.
/*If this style is added, it will work*/
.parent.error > .child.blue {
color: red !important;
}
Thanks...
without deeper brainstorming, my first reaction is:
CSS basic principle says - the more closer a definition is made, the more precedence it gets.
Thus the !important part is necessary to make things work.
Alternatively you could re-think the CSS definitions to the opposite ones.
The '.blue' take effect only when the parent's class does not contain .error.
A fast shot clue - something like this for the non-errorous case:
.parent:not(.error) > .child.blue {
color: blue;
}
Let's say I have following CSS :
:root { --color: blue; }
div { --color: green; }
#alert { --color: red; }
* { color: var(--color); }
and my markup is :
<p>I inherited blue from the root element!</p>
<div>I got green set directly on me!</div>
<div id="alert">
While I got red set directly on me!
<p>I’m red too, because of inheritance!</p>
</div>
My question is Does the CSS above translate to :
body {
color: blue;
}
div {
color: green;
}
#alert{
color: red;
}
or is there an additional
* {
color: red;
}
Without variables the universal selector applies the same CSS on all elements. Does this change and the styling becomes dependent on elements?
One more question I have is if :root translates to body in CSS.
Here is a CodePen demo : http://codepen.io/anon/pen/RrvLJQ
As you've correctly stated in your title, custom properties cascade. In fact, this is why the module is called CSS Custom Properties for Cascading Variables. That means your custom property --color is evaluated as-is per element, just as with any other CSS property. In terms of the actual styles that are applied to your elements, what you really only have is:
* {
color: var(--color);
}
The var(--color) value is then evaluated for each element based on how the --color property cascades. So it follows that:
The body element has a blue foreground.
Any div elements have a green foreground.
The element whose ID is "alert" has a red foreground.
Because you don't have a --color definition for *, it's inherited by default. Therefore all other elements inherit --color from their parent element: body > p inherits from body, becoming blue, and #alert > p inherits from #alert, becoming red.
If you really do want to express the cascaded values in terms of CSS, you could say that it translates to the following:
:root {
color: blue;
}
div {
color: green;
}
#alert {
color: red;
}
* {
color: inherit;
}
But only because the original CSS contains an explicit * { color: var(--color); } definition which ensures that every element's color maps to --color.
Note also that the code that you have comes from an example within the spec, which itself is described as follows:
If a custom property is declared multiple times, the standard cascade rules help resolve it. Variables always draw from the computed value of the associated custom property on the same element
One more question I have is if :root translates to body in CSS.
:root doesn't translate to any element in CSS, because CSS is document language-agnostic.
:root doesn't translate to body in HTML; it corresponds to html.
For example, given these two rules
p { color: red; background: yellow }
p { color: green }
paragraphs would appear in green text. They would also have a yellow background however, because the first rule is not completely negated. Its value for the color property is overridden by the second rule but its background-color is not in conflict, so it still applies.
So Is there anyway to stop applying background color property?
I am requiring such method because first rule may have n no. of attributes which i don't know beforehand.
looking forward for positive reply.
That's why you can define classes in CSS.
The style defined for the same element will be always overwritten if there are duplicated properties and inherited from the previous definition for the same element.
Try:
CSS
p.red { color: red; background: yellow }
p.green { color: green }
HTML
<p class="green">Some text</p>
<p class="red">Another text</p>
Define a class to each <p> element. Set CSS style for each defined class.
HTML File (index file)
<p class="content-1">This is content 1</p>
<p class="content-2">This is content 2</p>
CSS file (style.css)
p.content-1 {
color: red; background: yellow;
}
p.content-2 {
color: green;
}
JSFiddle: http://jsfiddle.net/SCLP8/
You can add the background property to your own CSS like this:
p { color: red; background: yellow; }
p { color: green; background: none; }
There won't be a yellow background.
I have a case where I have a .menu within a #header and when I accessed .menu's children via a css selector like .menu a, it is using the #header a instead.
I was expecting the .menu a to override the #header a as it is closer to the a element. Why isn't this happening? I'm assuming it has with it being a class compared to an id based on the example below.
In the example, is there a good way override #red span css within .blue span without otherwise restricting the parent style?
By "good way" I suppose I mean flexible. For example .blue could be an element created by a php framework that is used in many places (possibly not within an id styled parent element, or possibly within a parent styled on a different id).
Here is an example. All except #green will still be red:
HTML:
<div id="red">
<span>red</span>
<div class="blue">
<span>blue(class) - should be blue</span>
</div>
<div id="green">
<span>green(id) - should be green</span>
</div>
<div class="green">
<span>green(class) - should be green</span>
</div>
<div>
<span>no child div style - should still be red</span>
</div>
</div>
CSS:
#red span {
color: red;
}
.blue span {
color: blue;
}
.green, #green span {
color: green;
}
The priority of applying a CSS rule (without !important) is:
Number of IDs in the selector. If draw,
Number of attributes and classes. If draw,
names or pseudo-elements. If draw,
last declaration on the CSS file. This, of course, never draws.
Since #red span has an ID, and .green doesn't have any, #red span applies.
For further explanation of which CSS rule is apply first, check this nice article on smashing magazine
To work around, you can use a more specific rule. This way it gets tie on number one, but since it have extra classes, your rule wins due the number two.
Selector specificity dictates that id had priority over class. Even though the blue class is after red in the Cascade, red takes priority because of specificity. You can use the Selector #red .blue span if needed
the simplest and cleanest:
http://jsfiddle.net/f4ke2/7/
#red {
color: red;
}
.blue span {
color: blue;
}
.green, #green span {
color: green;
}
OR What if you do this? :)
#red > span {
color: red;
}
OR
#red .blue span {color: blue;}
OR
.blue span {
color: blue !important;
}
OR for "flexibility"
#red .blue span, .blue span, #someotherID .blue span {color: blue;}
OR something as horrid as this
var id = $("#red");
id.addClass(id.attr("id")).removeAttr("id");
If you are using style sheets (in a framework or otherwise) that assign properties to elements by class, i.e. using class selectors, you simply have to take this into account when writing other CSS rules. So this is a matter of disciplined coding (HTML and CSS), not about using some trick to get rid of normal CSS principles.
Basically, set properties only on those elements that you want to have affected, without using selectors with too wide coverage. Say, if you want to set the text inside some element red, set color: red on that element only, not on its descendants, unless you really want to override whatever settings they might have.
For example, if there is a style sheet with .foo { color: blue }, then this will affect any element in class foo, unless overridden by another rule, as per the CSS cascade. So if you don’t want it to be overridden in a situation like <div id=xxx>...<span class=foo>...</span>...</div>, you just can’t set #xxx span { color: red }, because then you would override the rule, by virtue of a more specific selector. Using #xxx { color: red } would be safe in this sense, since the span (having its color set) will not inherit its parent’s color.
Using !important as in .foo { color: blue !important } might seem to solve the problem, but !important makes style sheets difficult to manage and maintain. It also creates problems when you need a tool for overriding the effect of specificity but can’t, because you’ve already fired the weapon. The rule .foo { color: blue !important } is not effective against #xxx span { color: red !important }.