Is it possible to apply certain CSS to any element, except descendants of a certain class?
Here's a fiddle: http://jsfiddle.net/68jgdthm
As you can see I want everything on the page to be dark except elements which are descendants of the light class. The trick here is that one can't know if the element is a direct descendant, e.g. it might be this:
<div class="light">
<p>Element</p>
</div>
but it might also be this:
<div class="light">
<div>
<div>
<p>Element</p>
</div>
</div>
</div>
The dark class is almost always added to the body element and will always be a parent of any light classes.
One might say:
Just make the body "light" and add dark classes to any elements you need. - But I actually need the opposite, I need everything to be dark and certain elements to be light.
Then add "light" styles and add the light class to elements you need. - I already have the dark styles, so I'm looking for an easier "excluding" solution (I'm using LESS, so prefixing etc. is quite easy).
You will not be able to exclude descendants this way without writing a separate selector. You won't be able to do this even using :not(), for the reasons stated here.
Fortunately, the fact that .light elements will only ever occur within the context of a .dark element and not vice versa makes this a little easier. Since you have a body CSS rule already, just add .light p to that rule, and move the entire ruleset underneath .dark p so .light p will take precedence:
.dark p {
color: #000;
}
body, .light p {
color: #ccc;
}
Updated fiddle
Alternatively if you want to keep the body rule on top, you could bump up the specificity of .light p to ensure it will take precedence:
body, body .light p {
color: #ccc;
}
.dark p {
color: #000;
}
Color is an inherited property. Therefore just by declaring .dark and .light to have the wanted color is a good thing. You can make a default by assigning it to the body. I think atomic design like this is a good practice, as you don't add too much specificity in your CSS.
You could do this:
body {
color: #ccc;
}
.dark {
color: #000;
}
.light {
color: #fff;
}
Demo: http://jsfiddle.net/68jgdthm/1/
Related
Imagine that I've been creating a website for 2-3 weeks now and suddenly I decide that I don't like the default black color of all text elements which don't have any CSS applied to them and that I want to change their color to something like #333333 which is a less black black.
Is adding color: #333333; to the body tag the correct way to do it? Could that have any negative effects on other elements that I have custom styling?
CSS prioritises the code lower down, for example, this:
<style>
p {
color: blue;
}
p {
color: green;
}
</style>
<p>Hello</p>
Would result in the color of the paragraph element becoming green.
So to answer your question, anything above your CSS properties for body would be overridden.
Also, id and class attributes take priority over position, so if you wanted to give the elements that you don't want to get changed a class and keep it as black that would work also.
Hope it helped.
I don't think it'll have any negative affects on any elements, however i would just reference the tags specifically to be sure like
p, h1, h2, h3, h4, h5, h6 {
color: #333333
}
But like the comment, give it a try and see how it turns out.
This is enough, as it allows for the color to be 'passed down' through the cascade. Place this at the start of your stylesheet:
body {
color: #333;
}
Avoid using inline styles:
<body style="color: #333"> <!-- Don't to this -->
Inline styles have a different specificity than CSS selectors, and it's a whole chapter in itself. Plus, it's easier to separate concerns and have you layout separate from your stylesheets. And have everything grouped together within your styles.
The most simple way to do so is by CSS the following way:
* {
color: #333333;
}
Changing color in HTML with the style attribute is actually never the best practice.
Link to site in question.
In the footer, just above the copyright notice, I have a small block of Schema microdata. Business name, address, phone number. I want that text to be write, matching the copyright notice below it.
I've tried to do it like this:
<div class="schema_footer"> Schema block here</div>
And in my css file:
.schema_footer {color: #ffffff;}
Why doesn't this work?
Try this, the HTML is more complex than the example you have provided as shown in the screenshot. There may also be more specific CSS that you can't override unless your CSS is at least as specific:
.footer .schema_footer div,
.footer .schema_footer span
{
color: #fff;
}
It is not good practice, but you could also add the important rule color: #fff !important; to try and override the previous styles that have been set.
That is because there are more specific rules that overrides the rule mentioed in the .schema_footer like the one below:
....
.footer span, .footer a {
color: #666;
}
So you need to make your rule even more specific like.
.footer .schema_footer span, .footer .schema_footer a {
color: #fff;
}
or override the .footer style later in the stylesheet (or with multiple style sheets load this one later)
.footer span, .footer a {
color: #fff;
}
No matter how bug the html is, You can always use the web inspector to inspect the styles applied and overridden. Here is how it looks after overriding and you can see the second arrow showing the actual rule applied before.
here is a simple solution
.footer {color: #fff;}
I have something like this
<div class="text-holder">
<h2>this is text-holder</h2>
<p>this is text</p>
</div>
<a href="#" class="ignore">
<div class="text-holder">
<h2>this is text-holder</h2>
<p>this is text</p>
</div>
</a>
<a href="#">
<div class="text-holder">
<h2>this is text-holder</h2>
<p>this is text</p>
</div>
</a>
And CSS that does this
.text-holder {
color: green;
}
a {
color: red;
other css
}
.ignore {
other css
}
Is there a way that the link can ignore the css style for the global a style, and just use the ignore? I don't want to use !important because there will be other instances of text-holder that will want to use the global a style.
EDIT
Thanks for all the replies, but let me be a little more clear so hopefully you understand better. (Not the best at explaining)
The problem is text-holder has it's text styling from global p, h2 and etc. Which are above a in the hierarchy of the stylesheet. so p, h2, a, .ignore, .text-holder etc
a has a lot of info on it, hover, visited, focus, color, font-weight and etc. Now for all the divs I wanted to ignore this info I was looking to see if there was a simpler way of just creating an ignore rule, rather than for all the divs I want to ignore it to overwrite them with all the rewritten information.
CSS doesn't support "ignoring", but part of its nature (the Cascading part of Cascading Style Sheets) supports "overwriting"; Newer CSS properties will overwrite older CSS properties of the same name, so you just need to give .ignore a different color value than your previous a selector's color value.
Is there a way that the link can ignore the css style for the global a style, and just use the ignore?
No. If a selector matches then all applicable rules in it will be applied.
.ignore is at least as specific as all preceding rules, so you just need to set the properties you want to override to the desired value.
Yes, basically what you're trying to do is already how CSS works.
The key to understand is the concept of specificity.
CSS rules applied through the style="" attribute have a weight of 1000.
Rules applied against an #id selector have a weight of 100.
Rules applied against a .class selector have a weight of 10.
And rules applied against an element tag name or :pseudo-selector get a weight of 1.
So for example, if you have...
a { color: red; }
.ignore { color: black; }
The weight of the red links is 1, while the weight of black text is 10, so the black has higher specificity and would win.
The important concept is that .ignore doesn't tell it to ignore its old assignment, it is instead a way to override the assignment.
EDIT
I should also add that cascading rules have no weight, so any definition in a child element will override them.
For example:
a { color: red; }
.ignore { color: black; }
div { color: blue; }
<a class="ignore"><div>hello world</div></a>
The text will be blue, not black, because the div tag has a rule applied to it which overrides the cascading black from the .ignore class.
You can try:
:not(.ignore) .text-holder {
color: green;
}
Or if you move your ignore class to .text-holder element
.text-holder:not(.ignore) {
color: green;
}
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 }.
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).