Why Doesn't My Child Element Inherit Color from Its Parent When Parent Has More Specific Selector

Why doesn't my child element inherit color from its parent when parent has more specific selector?

See: w3c: 6 Assigning property values, Cascading, and Inheritance - 6.2 Inheritance

An inherited value takes effect for an element only if no other style declaration has been applied directly to the element.

This style applies to an element with id="my_id":

#my_id {
color: red;
}

... and will apply (inherit) to an element nested within having class="my_class" only if its color property is otherwise unspecified.

...which no longer is the case once you declare:

.my_class {
color: blue;
}

CSS inheritance -- color property

Why would you expect a property specified on a parent to override one specified on a child?

Specificity refers to a way to prioritize rules selecting the same element. The specificity of a rule on a parent (.hero) has no relevance to the specificity of a rule on its children (a).

In this case, the default color on the a element is inherit. However, you explicitly specified a different color. No amount of specificity or !important on the parent can cause it to override an explicit color specified on the child.

My class selector is being overriden by the element selector

That is true when the class selector is in h3 tag.

h3{
color: red
}
.purpleHeader{
color: purple
}
<h3 class="purpleHeader">La la la la...</h3>

To achive your goal you have write a more specific rule.

.purpleHeader h3 {
color: red
}
.purpleHeader {
color: purple
}

Now it is red /p>

inherit value doesn't inherit from :visited parent

Unfortunately, Extra Mark-up Appears to be Needed

This was tested in FF22, IE9+ (IE8 for the CSS2 version), and Chrome28.

The only way I have found (and probably the only way it will work at all given the security features) to get the color differentiation you desire based off inherited control from the a and a:visited states is by some extra mark-up in the html.

Specifically, all the text outside the .bar needs to be wrapped in its own span (or two span elements, if text also followed .bar), and then the .bar text needs a double wrapping. I assume this works because it is using the normal default inheriting of the color value for .bar (which also controls the default border-color), and so it allows the :visited text color state to pass to .bar.

Here's the code (I made new lines for the html display just to make the extra mark-up more visible):

UPDATED for unvisited bottom border color control.

See the fiddle.

HTML

<a href="http://google.com">
<span>foo </span>
<span class="bar">
<span>bar</span>
</span>
</a>

CSS (CSS3 version)

a {
text-decoration:none;
color: green; /* controls unvisited border color */
border-bottom-width: 0px;
border-bottom-style: solid;
}

a span:not(.bar) {
color: blue; /* sets text color of unvisited links */
}

a:visited {
color: yellow; /*sets border color of visited links */
}

a:visited span:not(.bar) {
color: red; /* sets text color of visited links */
}

a:hover span:nth-child(n) {
/* nth-child(n) selects all, but is needed to override specificity of
:not(.bar) in the previous selector. NOTE: because all the text must be
wrapped in a child span, there is no need to define just the a:hover
selector without the following span, unless other links will use this
without a .bar nesting
*/
color: gray; /* sets text and border color when hovered */
/* eliminated unneeded border-color property */
}

.bar {
border-bottom-width: 1px;
border-bottom-style: inherit;
/* border-color uses color property of <a> in whatever state it is in */
}

CSS2 (if IE8 browser support is needed)

You must conditionally feed a different set of css for the various a element states to IE8 (the base a code is the same). This cannot be combined with the above in any way, else it will mess up the working needed for Chrome.

See the fiddle.

a span {
color: blue;
}

a:visited {
color: yellow;
}

a:visited span {
color: red;
}

a:visited span.bar {
color: inherit;
}

a:hover span,
a:hover span.bar {
color: gray;
}

Child div doesn't override Parent

It's because opacity works for whole element of x. So if you have multiple nested elements, then it's opacity is added up. Means x set opacity for itself, then y sets opacity to itself and so on, it's not inherited by child elements:

span {
background-color: red;
}

div {
opacity: 0.9;
}
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<span>SPAN TEXT with 8 parents</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

<div>
<span>SPAN TEXT with 1 parent</span>
</div>

Why doesn't border-color propagate to child elements?

There's no default value for border color.
You need to manually tell it to take its value from its parent with border-color: inherit;



Related Topics



Leave a reply



Submit