Is it possible to have a CSS rule which basically "undoes" a prior rule?
An example:
<blockquote>
some text <em>more text</em> other text
</blockquote>
and let's say there's this CSS:
blockquote {
color: red;
}
...but I want the <em> to remain the normal text color (which you may not necessarily know).
Basically, would there be a way to do something like this?
blockquote em {
color: inherit-from-blockquote's-parent
}
Edit: The code I'm actually trying to get this to work on is actually a bit more complicated. Maybe this would explain it better:
This text should be *some unknown colour*
<ul>
<li>This text should be BLUE
<ul>
<li>Same as outside the UL</li>
<li>Same as outside the UL</li>
</ul>
</li>
</ul>
ul {
color: blue;
}
ul ul {
color: ???;
}
With CSS alone, you can't refer to a parent's parent.
The thing you can do is try a mix of specific CSS selectors and markup so that the desired effect appears.
<td>
This is the enclosing element.
<ul>
<li>This is the first level UL, direct child of TD
<ul>
<li>This is the second level UL</li>
<li>Same as outside the UL</li>
</ul>
</li>
</ul>
</td>
CSS:
td > ul
color: blue; /* this affects the "direct child" UL only */
}
You would limit the depth of style inheritance to one level, consequently the inner UL is unstyled in regard to color and gets its setup from the enclosing text.
Read more on the CSS Child Selector, and be aware that older browsers may have their quirks with them.
EDIT
For Internet Explorer 6, the child selector can be faked to some extend. Be sure to fasten seat belts (conditional comments or the like) before using this:
td ul {
color: expression(/TD/.test(this.parentNode.tagName)? "blue" : "black");
}
This assumes "black" as the outer color. If this color value is subject to change, your are out of luck, I'm afraid. Unless you can define an expression() that is able to get the color value from the context (e.g. checking some other properties of parent elements). Or you give up and use a JS framework, as someone else has already suggested.
The wimpy solution without having to use JS would of course be:
td ul.first {
color: blue;
}
But I can see why you want to avoid that.
Use this to make sure the inherit overrides whatever else might have been setting the color:
blockquote em {
color: inherit !important;
}
Give up and use a snippet of javascript to detect the style of the parent and set it? :)
Rather than trying to force a selector to inherit font colour from its grandparent, I would suggest that you give the selector and its grandparent a shared declaration for the font colour.
Taking the blockquote example, assuming that body is the grandparent:
body, blockquote em {
color:[whatever];
}
blockquote {
color:red;
}
And in the case of the unordered lists, it would be:
body, ul ul {
color:[whatever];
}
ul {
color:blue;
}
My CSS is a bit rusty, but this should work:
blockquote {
color: red;
}
blockquote em {
color: inherit;
}
You are setting blockquotes to red, but all <em>'s that are contained in a blockquote should inherit... hmmm, should they inherit from the surrounding text, or from the blockquote?
If the above does not work as you want, then there is no way to do it with the current markup, I think. You would have to work with additional markup, or set the colour explicitltly, e.g.
blockquote em {
color: Purple;
}
Ok, the additional text with example clarifies the question a lot. And I'm affraid that what you want is not possible.
If you know the "unknown colour" you can of course repeat the color. But I think CSS needs some mechanism to add variables or references.
So you have to stick to the cumbersome:
ul {
color: blue;
}
li ul {
color: sameenvironment; /* Sorry but you have to add the specific colour here */
}
If you can change your html you could try
<li><span>This text should be BLUE</span>
<ul>
<li>Same as outside the UL</li>
<li>Same as outside the UL</li>
</ul>
</li>
and the style
li span{
color: blue;
}
EDIT
another way to accomplish this without the extra span tag:
If we assume that we have a style class (or any other selector) that defines to parent of the outer ul. We can modify the css like this:
.parentStyle,
.parentStyle li li{
color:red;
}
li{
color:blue;
}
I too had this question but after I glanced at the other answers it hit me,
body {
color : initial;
}
IE doesn't support this currently and Gecko requires a -moz-initial I believe..
body {
color : unset;
}
This one isn't quite as supported right now. I just thought I'd share my answer to this for anyone else who thinks about this.
Related
I am making a navbar for a website made via GatsbyJS. I am attempting to style the links in the navbar such that they do not have an underline.
I have already set the link to not have any text decoration--when I inspect the element in my browser, it even shows the "text-decoration: none" property. I have also confirmed that my CSS is influencing the object--I can change the color of the text, for example, it is only the text-decoration which I cannot influence.
CSS:
.nav {
background: #fd8;
}
.nav ul {
text-align: center;
border: 1px solid #000;
}
.nav ul li {
display: inline-block;
padding: 8px 10px;
margin: 0;
}
.nav ul li a {
color: #221;
text-decoration: none;
}
html + js:
...
import { Link } from "gatsby"
import styles from "./navbar.module.css"
...
<nav className={styles.nav}>
<ul>
<li>
<Link style={{ textDecoration: 'none' }} to="/about">
About
</Link>
</li>
EDIT: the inline styling with textDecoration was a product of some fiddling I was doing prior to posting this question and was not present until recently. Removing it has no effect on the issue.
Rendered HTML by request:
<nav class="navbar-module--nav--25Dcz">
<ul>
<li>
About
</li>
...
</ul>
</nav>
I have discovered that the errant underline was actually a 1px box-shadow, probably from some global style I can't find associated with the Gatsby Typography plugin.
When you say .nav you want to select a class by that. And as I see, in your html,
nav (<nav...) is a tag with a class navbar-module--nav--25Dcz
So if you change your CSS to:
(Remove the period character . from .nav)
nav {...}
nav ul {...}
nav ul li {...}
nav ul li a {...}
It should work fine.
Also, take a look at Styled Components: https://www.styled-components.com/ which let you write CSS in JS and use similar features from preprocessors like Less and SASS.
Hope this helps!
Your issue is that you're using a class selector (.nav) when you should be using a tag name selector instead. Changing to nav ul li a{text-decoration:none} should fix your issue. If that doesn't work, then you probably have some CSS with higher precedence somewhere that is overriding it.
So for those still searching for an answer. It's really a BUG. At least with <ul>, <li> tags and their nesting. There's just one bypass, and even that has a bit of a limitation. So here's a sample with a fixed (removed) underline and it contains notes also on what to add, what to avoid.
https://stackblitz.com/edit/keep-remove-underline-from-nested-li-item?file=index.html [working text decoration removal]
the solution is:
need to use inline-block for <ul>, set vertical top align and 100% width
avoid to use white-space nowrap
I tried everything to remove it, then after reading this I remembered that I added what in the link https://www.gatsbyjs.org/docs/typography-js/
Icones was underlined, anything that will be was underlined
nothing worked until I removed that.
I can't explain why, but when I referenced a class that was LESS specific I was able to get the text decoration to go away with text-decoration none. So if you have a less specific wrapper class try targeting the links with that
.wrapper a {
text-decoration:none;
}
You can select the global a tag or be specific, and after text decoration, add !important. That will override any default styling that gatsby is imposing.
.nav ul li a {
color: #221;
text-decoration: none !important;
}
How do you change styles of another element based on whether the first element is empty.
<ul></ul>
<ul>
<li>....</li>
<li>....</li>
<li>....</li>
</ul>
In the above code, I want to give a style for the second ul { color:red } (to be more exact the ul that follows) ONLY if the first ul is empty.
Is there a pure CSS solution for this?
You can do this, but only if the element in question is completely empty- yes, not even a whitespace.
http://jsfiddle.net/NicoO/uTJ4N/
ul:empty + ul
{
color: red;
}
To be more accurate, this is the selector you need for the first empty <ul> of the body and the exact following <ul>:
body > ul:first-of-type:empty + ul
{
color: red;
}
http://jsfiddle.net/NicoO/uTJ4N/1/
Try this code:
ul > li {
color: red;
}
Its selects the ul which has a li as child element. And those can be colored red then.
http://jsfiddle.net/keypaul/KfaQv/1/
ul:not(:empty) {
color:red;
}
I dont think a pure css solution is the way to go, but you can use a pre-processor as they allow you to pass conditional statements.
Here are two examples based on this HTML.
<a href="#">
<div class="foo">
hello
<span class="bar">world</span>
</div>
</a>
In the first one, I make the link not underline on hover, then make a sub-portion of the link underline, and that works fine:
a {
text-decoration:none;
}
a:hover {
text-decoration: none;
}
a:hover .bar {
text-decoration: underline;
}
http://jsfiddle.net/3qPyX/1/
In the second, I now reverse the selectors so that the second word should be un-underlined. However, now something strange happens. The entire link remains underlined even though the selectors seem like they should remove underline from the second word. <-- (this is the question. why does this happen?)
a {
text-decoration:none;
}
a:hover {
text-decoration: underline;
}
a:hover .bar {
text-decoration: none;
}
http://jsfiddle.net/EAmwt/
Can someone explain what's going wrong in the second example? Inspecting with Chrome shows the span.bar has a computed style of text-decoration:none.
Update: a few answers explaining how to get around the problem, which is great except that's not really my question. What I want to know is why is this behavior different than, say, bold? For instance, if I try the 2nd example with bold, I get the expected results: http://jsfiddle.net/3qPyX/4/
Explanation:
The problem is that some properties (like text-decoration) get drawn to the whole parent inline element, whereas others - like font styling (that get inherited) - get overriden by the children properties.
Just for illustration: simmilarly, if you set a background color to a parent element it will paint the background of the parent ... and you would have to set another color to a child to lay it over (default - transparent - will still show the parent style through), but if you set font-weight at a child it will apply to the text inside the child element and override the parent settings.
You can find more detailed stuff on the text-decoration property in the CSS Level 2 and Level 3 Specifications.
A simple solution
withot changing the markup, you could just display .bar as inline-block.
Like so:
a {
text-decoration:none;
}
a:hover {
text-decoration: underline;
}
a:hover .bar {
display:inline-block;
}
And the inline-block breaks out of the inline/text styling of the parent anchor element =) And you can then style it independently:
DEMO
When you do the text-decoration it is applied to the entire line at once. So the a:hover .bar doesn't cause any effect, because the underline is not being applied in the .bar but on the a.
Here is the specification: http://www.w3.org/TR/CSS21/text.html#lining-striking-props
UPDATE! (As #Cam suggested) :
You need the add in separate elements the parts of your text: http://jsfiddle.net/3qPyX/5/
The CSS:
.foo, a:hover .bar, a {
text-decoration:none;
}
a:hover .foo {
text-decoration: underline;
}
Is it possible with CSS to change the style of the number in an <ol> without changing the entire text in the <li> without adding extra markup around the li content?
You can disable the original <ol> style, then use :before selector with counters to add whatever style you want. Like here:
ol {
counter-reset: i 0;
}
ol li:before {
content: counter(i);
counter-increment: i;
padding-right: 0.5em;
color: red;
}
If you wish, you can even override some styles for particular elements of the list with nth-child selector (JS Fiddle):
ol li:nth-child(3):before {
color: violet;
}
... as cascading rules are still applied here. Note, though, that nth-child is not supported by IE8.
I want to simulate tabs such that the first word in a list entry always gets a fixed width. I do it like this:
<style>
.tabbed { float: left; width: 5em; }
</style>
<ul>
<li><span class='tabbed'>first</span> entry in my list</li>
<li><span class='tabbed'>second</span> list entry</li>
</ul>
the approach works relatively well except that if I want to do:
li { color: blue }
it applies the color (not surprisingly) to the <li> but not to the <span>. this means that I would have to:
.tabbed { color: blue }
which is not very DRY. In my case I've got a whole bunch of declarations for different classes of the list items so it's cumbersome and ugly.
how does one deal with this?
By default the the span should be colored blue if the li is colored blue.
See http://jsfiddle.net/Q2UGE/ for an example
I think you must have some other CSS overriding it
In case you do have something else overriding it that you cant change, you can also enforce li .tabbed to inherit from it parent
li .tabbed { color: inherit }
See http://jsfiddle.net/Q2UGE/1/ for an example of that
You can't really. Best you could do is...
li,
.tabbed {
color: blue
}
li, .tabbed { color: blue }
thats a little more dry.
Like this :
li, .tabber { color: blue }