Change style of content depending on another css property value - html

Say, I want to change the background color of all the content in a paragraph that does not have any text-decoration (like bold, underline, etc.). Is it possible to do it just using CSS with a some kind of syntax like this?
p[text-decoration=none] {
background-color: yellow;
}
A sample HTML content that this CSS should be applied will be something like this:
<p class="special">Yellow background <b>default background for paragraph</b> yellow
again <i>default</i> once again yellow.</p>
Requirements for the above to work:
Do not add style and/or class attributes to the paragraph contents, i.e., to <b>, <i>, etc.
Do not change the styles for <b>, <i>, etc.
Background-color should be specified for any content (HTML or CSS-style based) that does not have any text-decoration.
The parent of <p> may have a custom background-color, so elements like <b> or <i> should assume that color.

It is impossible to make the absolutely correct decision according to your requirements with the help of CSS. But you can apply a little trick, which is to use the CSS variables declared inside :root.
The principle is to use the same background color for the background of the main parent and the background of tags b and i. You need to declare a variable like this:
:root {
--backColor: yellowgreen;
}
Next, using function var(), assign the declared variable for rules background-color, body tags (parent), b and i:
background-color: var(--backColor);
In pseudo-class :is(), you need to specify tags (b and i) for which the background color of the variable will be assigned.
:root {
--backColor: yellowgreen;
}
body {
background-color: var(--backColor);
}
p {
background-color: yellow;
display: inline-block;
}
p * {
display: inherit;
}
p *:is(b, i) {
background-color: var(--backColor);
}
<p class="special">Yellow background <b>default background for paragraph</b> yellow again <i>default</i> once again yellow.</p>

Related

CSS :not selector being ignored

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.

How do CSS custom properties cascade?

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.

How to ignore body element style when there is a class at element inside

Look, i have the html below:
<body style="color:red;">
text inside 1
<p>
text inside p
...
</p>
<div class="divable1">
text inside div 1
</div>
</body>
and i want only "text inside 1" and "text inside p" to have color red BUT "text inside div 1" i want to ignore the style of the body element.
How is this possible with CSS?
Thank you in advance!
There is no way to ignore rules in CSS, only to override them. Write a ruleset with:
A selector that matches the div (such as .divable1)
A rule that changes the color property so it has a value other than the default, which is inherit, such as color: black.
This is basic CSS hierarchy, you can't ignore the rules, but you can easily overwrite them:
body {
color: red;
}
.divable1 {
color: green;
}
http://jsfiddle.net/vLtqjjpk/
I'm aware that this question was asked a very long time ago, but it could possibly be done by unsetting one or all properties:
body {
color: red;
}
.divable1 {
all: unset; /* resets everything */
color: unset; /* resets specific property */
}

css inherit child propeties

I want to give border-bottom to header.the border color should be same as its child font color.please find the html code and suggest me to proceed further.
<header>
<div class="cblt-panel">
<header>
<a href="HomePage;jsessionid=9Z1DRLtK8FfgmVDhysv4fk8LKjj1rTpSpJcS99dvcbffT4KTZ9tN!91184445">
<div class="header-wrapper header">
<h1 class="dealer-name">Airport Chevrolet Cadillac</h1>
</div>
</a>
</header>
</div>
</header>
in the above markup, i want to set the border-bottom-color for outer header tag same as the font color of child h1 tag. is it possible ?
I don't think you can achieve it through pure CSS. If you are able to use jQuery, it's quite simple:
var h1Color = $('.dealer-name').css('color');
$('header:eq(0)').css('border-bottom-color', h1Color);
Demo: http://jsfiddle.net/S9svs/
No, it is not possible: in CSS, parents never inherit from their children.
You can just make an element’s border color the same as its own content color (text color), namely by not setting the border color at all. But to use a color set on a child, you need JavaScript.
A better strategy is to combine the settings so that you simply set the color of a heading element and the color of an enclosing element to the same value. These settings need to be done in separate rules, though, e.g. header { border-color: #060; } h1 { color: #060; }.
If you surely want to do it dynamically then you have to use a css preprocessor language for it...
Like Less CSS
Here you make dynamically define the css and use it like you do in javascript...
For example,
#color:#000;
header { border-bottom-color:#color; }
header h1 { color:#color; }
The funny thing is that border-color, if not set, uses the color property to define it's color, so in some occasions you may be able to do the opposite. eg:
header {
color:red;
border-bottom: 2px solid;
}
header a,header h1 {
color:inherit;
}
DEMO: http://jsfiddle.net/brTTT/
In the demo, hover to see the color change by just changeing the header color property.

Difference in applying CSS to html, body, and the universal selector *?

How are these three rules different when applied to the same HTML document?
html {
color: black;
background-color: white;
}
body {
color: black;
background-color: white;
}
* {
color: black;
background-color: white;
}
html {
color: black;
background-color: white;
}
This rule applies the colors to the html element. All descendants of the html element inherit its color (but not background-color), including body. The body element has no default background color, meaning it's transparent, so html's background will show through until and unless you set a background for body.
Although the background of html is painted over the entire viewport, the html element itself does not span the entire height of the viewport automatically; the background is simply propagated to the viewport. See this answer for details.
body {
color: black;
background-color: white;
}
This rule applies the colors to the body element. All descendants of the body element inherit its color.
Similarly to how the background of html is propagated to the viewport automatically, the background of body will be propagated to html automatically, until and unless you set a background for html as well. See this answer for an explanation. Because of this, if you only need one background (in usual circumstances), whether you use the first rule or the second rule won't make any real difference.
You can, however, combine background styles for html and body with other tricks to get some nifty background effects, like I've done here. See the above linked answer for how.
* {
color: black;
background-color: white;
}
This rule applies the colors to every element, so neither of the two properties is implicitly inherited. But you can easily override this rule with anything else, including either of the above two rules, as * has literally no significance in selector specificity.
Because this breaks the inheritance chain completely for any property that is normally inherited such as color, setting those properties in a * rule is considered bad practice unless you have a very good reason to break inheritance this way (most use cases that involve breaking inheritance require you to do it for just one element, not all of them).