In Shadow DOM, override CSS body * - css

I have the following scenario:
Printscreen of my problem
I have a CSS in the project (which I can't change) defining the following:
body * {
font-family: 'x'
}
And this CSS is influencing my shadow DOM, because of that, I can't use the font-family property without using !important. Only with !Important works:
::slotted(span), ::slotted(p){
font-family: arial !important;
}
Does anyone know what to do in this case?

Most of the information needed to answer this can be found in this related answer. In summary: A document-wide style without !important will always override a shadow dom style without !important, if they apply to the same element.
(And in this case, they do apply to the same element: slotted elements exist outside the shadow dom, so * rules in the document stylesheet can find them.)
You've already found two workarounds to this. I'll list them here for completeness:
Use !important:
This is ugly, but it does work. Not only does !important override any and all non-!important rules, but it also overrides any !important rules coming from the document-wide stylesheet!
Reduce the body * rule to just body:
This way, the rule won't apply directly to every element - it will only apply directly to body, and affect every other element via inheritance. Inherited rules can be overridden by anything, since they're only a fallback in case nothing else applies.

Related

Why is the user agent stylesheet overriding my html{} style?

I have the following style on my html element:
html {
font-size: 16px;
font-family: "Harmonia Sans Regular" !important;
}
But even with !important, my font styling is still being overriden in things like inputs.
Why? I thought inherited styles trumped user agent styling?
Nope. If you want your styles to have precedence, they need to apply to the same element. Which, in our case, is input.
You have applied styles to the html element, not to input.
Now, if you changed your selector to html *, to html input, to input or to *, it would be a different story... The two selectors would get compared and yours would have precedence.
The only difference between your selectors and the ones in the default browser stylesheet is yours are loading later, hence, provided you have the same specificity, yours apply. So the minimum selector for yours to apply would be input {}.
But the important bit here is: html {} only styles inheritable input properties which are not defined (not set) at element level. If they are set inheritance does not happen (there's no need to inherit, because the property resolves). The input set value applies, regardless of values and specificity on any of the parents. In fact, if what you're expecting would happen, designing web would be a lot more difficult and a lot less flexible (IMHO).
Which is a reaaaaaly long way of saying: change
html {/* globals here*/}
into:
* {/* globals here */}
... and they'll probably work as intended. But be warned: it will apply to all elements, and you will soon understand why the way inheritance works is, in fact, quite smart (and helpful).

css - Strictly set style?

In my CSS, I have this:
b {
color: Red;
}
And in my body:
<b>Hello world!</b>
As a result, I get "Hello world!" text that is red in color.
However, as I add more classes:
.myClass {
color: Blue;
}
.green {
color: Green;
}
And I modify my body:
<b>H<a class="myClass">ell</a><a class="green">o</a> wo<a style="color: Black;">rl</a>d
I will not get the same result as earlier.
Is there a way to strictly set a CSS style? Which means that with the above code I wish to get "Hello world!" text that is red.
Thanks
This is a question of CSS Specificicty
The concept: Specificity is the means by which a browser decides which
property values are the most relevant to an element and gets to be
applied. Specificity is only based on the matching rules which are
composed of selectors of different sorts.
Inline styles override external CSS, and class selectors override element level selectors.
The following list of selectors is by increasing specificity:
Universal selectors
Type selectors <--- your b CSS
Class selectors <---- your .xyz CSS
Attributes selectors
Pseudo-classes
ID selectors
Inline style <--- your style=''
If you wish to override specificity, you can use !important after the rule in question, e.g.:
b {
color: Red !important;
}
However, this is not recommended, instead you should write 'better' rules (more specific) to target your HTML as appropriate. This ensures you end up with better structured code, the issue with !important being it can lead to unforeseen circumstances where rules aren't working because you may have forgot you had previously overridden them.
Again, from MDN:
The !important exception
When an !important rule is used on a style declaration, this
declaration overrides any other declaration made in the CSS, wherever
it is in the declaration list. Although, !important has nothing to do
with specificity. Using !important is bad practice because it makes
debugging hard since you break the natural cascading in your
stylesheets.
Some rules of thumb
Never use !important on site-wide css. Only use !important on
page-specific css that overrides site-wide or foreign css (from ExtJs
or YUI for example). Never use !important when you're writing a
plugin/mashup. Always look for a way to use specificity before even
considering !important
With the markup that you provided, no. Otherwise, maybe
The inline style has priority over the stylesheet so part of the text will be black no matter what. You might be able to create a rule that has enough specificity that it will take precendence over any other rules.
b, b .myClass, b .green {
color: red;
}
Though this can get troublesome to maintain. And there is still a chance that a different css rule will get higher precedence later on. I am not completely sure that even specifying all the children with * will do it.
You seem to be asking whether you can set a property (color in the example) on an element in a manner that will not be overridden by settings on inner elements.
You cannot do that with settings on the element itself. But you can set a property on an element and all of its descendants:
b, b * {
color: Red !important;
}
This will override any normal settings for color on inner elements. But it is ineffective against, say, .green { color: Green !important; }. To defeat that, you would need a more specific selector, such as b .green, for your rule—so there is no general way to achieve that (i.e., a way that is independent of the specific markup used inside the element).

Remove all the styling from elements which have inline styling using CSS

Suppose I have some html like this -:
<div style="blah...blah">Hey Nice</div>
<a style="blah...blah">Great</a>
How do I remove all the inline styling applied to the above elements in my stylesheet considering I don't know what all inline styling exists.
Currently I am trying this, but in vain -:
div[style], a[style]{ !important }
You must reset all css properties for elements that have style attribute:
[style] {
position: static !important;
float: none !important;
border: 0 none !important;
margin: 0 !important;
padding: 0 !important;
outline: 0 none !important;
// and so on
}
There are several determining factors determining which CSS property prevails in any situation. In order, these are:
Whether the property value has the !important flag or not.
If the style declaration is applied inline via the style attribute.
The strength of the CSS rule selector
If the rule has any ID clauses, and if so how many
If the rule has class, attribute or pseudo-class clauses, and if so how many
If the rule has any tagname clauses, and if so how many
If the property is parsed later in the source than another property with a rule of the same strength
So the only way to override the properties is to make sure that all the properties applied via style are applied elsewhere in your stylesheet, and have the !important declaration. The most rational way to do this is still very awkward — it would involve applying a very specific reset stylesheet, and including !important on every property on every rule.
But even if this is done, you still couldn't override inline style declarations that have !important themselves.
You've told Mojtaba that there should be a better solution, but that better solution would involve designing CSS to break its own rules. Imagine if there was a simpler solution for overriding inline styles from stylesheets designed into the language of CSS — should there also be another solution for simply overriding the override from inline styles? Where does the cycle end? All in all, I'd recommend using Javascript or giving up. Or describing your specific problem in more detail — there may be another solution!
If you're not happy with using !important overwrites in the CSS (as suggested by others on here), the only way would be to use JavaScript to remove the styles.
This is really easy in jQuery (better if you're able to assign a class name to the elements to select it with):
$('.selector').attr('style', '');
This will simply replace the element's 'style' attribute with nothing, thus removing the inline styles.
This isn't ideal though since it will rely on the visitor having JavaScript enabled, and may well result in the visitor seeing a style 'flash' as the page loads: the styles assigned in-line to the element before the JS kicks in and removes it.

What does !important mean in CSS?

What does !important mean in CSS?
Is it available in CSS 2? CSS 3?
Where is it supported? All modern browsers?
It means, essentially, what it says; that 'this is important, ignore subsequent rules, and any usual specificity issues, apply this rule!'
In normal use a rule defined in an external stylesheet is overruled by a style defined in the head of the document, which, in turn, is overruled by an in-line style within the element itself (assuming equal specificity of the selectors). Defining a rule with the !important 'attribute' (?) discards the normal concerns as regards the 'later' rule overriding the 'earlier' ones.
Also, ordinarily, a more specific rule will override a less-specific rule. So:
a {
/* css */
}
Is normally overruled by:
body div #elementID ul li a {
/* css */
}
As the latter selector is more specific (and it doesn't, normally, matter where the more-specific selector is found (in the head or the external stylesheet) it will still override the less-specific selector (in-line style attributes will always override the 'more-', or the 'less-', specific selector as it's always more specific.
If, however, you add !important to the less-specific selector's CSS declaration, it will have priority.
Using !important has its purposes (though I struggle to think of them), but it's much like using a nuclear explosion to stop the foxes killing your chickens; yes, the foxes will be killed, but so will the chickens. And the neighbourhood.
It also makes debugging your CSS a nightmare (from personal, empirical, experience).
The !important rule is a way to make your CSS cascade but also have
the rules you feel are most crucial always be applied. A rule that has
the !important property will always be applied no matter where that
rule appears in the CSS document.
So, if you have the following:
.class {
color: red !important;
}
.outerClass .class {
color: blue;
}
the rule with the important will be the one applied (not counting specificity)
I believe !important appeared in CSS1 so every browser supports it (IE4 to IE6 with a partial implementation, IE7+ full)
Also, it's something that you don't want to use pretty often, because if you're working with other people you can override other properties.
!important is a part of CSS1.
Browsers supporting it: IE5.5+, Firefox 1+, Safari 3+, Chrome 1+.
It means, something like:
Use me, if there is nothing important else around!
Cant say it better.
It is used to influence sorting in the CSS cascade when sorting by origin is done.
It has nothing to do with specificity like stated here in other answers.
Here is the priority from lowest to highest:
browser styles
user style sheet declarations (without !important)
author style sheet declarations (without !important)
!important author style sheets
!important user style sheets
After that specificity takes place for the rules still having a finger in the pie.
References:
http://www.w3.org/TR/CSS2/cascade.html#cascade
https://russmaxdesign.github.io/maxdesign-slides/02-css/207-css-cascade.html
It changes the rules for override priority of css cascades. See the CSS2 spec.

CSS inheritance issue

I have one stylesheet (layout.css) that imports the following CSS at the top of the style sheet:
#import "reset.css";
#import "typography.css";
#import "forms.css";
#import "fonts/fonts.css";
#import "tablecloth.css";
Everything seems to be in order apart from that blasted typography style sheet. What I mean by that is when I apply a style to, say, a paragraph, the only styles applied to it are taken from the tyopgraphy style sheet.
Example:
Applied in layout.css:
#three-col-container #right-col.filter p.more { color: #ff0000; font-size: 1.2em; }
What Inspector is telling me is applied (these styles are included in the typography style sheet):
p { font-size: 1em; color: #444; }
I've never came across this sort of inheritance issue. The other style sheets are working as expected.
Any suggestions welcome.
Thanks.
You could try using the !important flag on the end of the rule you want to override, before the semicolon.
This will make sure it's always applied, and so should override the inherited rule.
#three-col-container #right-col.filter p.more means:
Apply this style to paragraphs (p) which have the more class that are descendants of something which has the id right-col and class filter that is descendant of something with id three-col-container.
Is this right?
Are you sure that in the typography stylesheet the style rules don't have the !important flag at the end? Are you that the URL of that stylesheet is correct?
It might be a specificity issue??
I found this awhile ago that's helpful when trying to determine css inheritance rules:
Add 1 for each element (ex p and a) and pseudo-element (ex :before and :after);
add 10 for each attribute (ex [type=”text”]),
class and pseudo-class (ex :link or :hover;
And add 100 for each ID;
and add 1000 for an inline style.
So #three-col-container #right-col.filter p.more has 2 ID's, 2 classes and 1 element, so it has a weight of 221.
Is it possible that there might be another rule that has a higher weight that's overriding your rule? Are there any other styles being applied other than those two? (Or even javascript applying inline rules?)
I try and use either Firebug or the Chrome/Safari Developer tools to try and figure out what rules are coming from where. Typically it'll give you the name of the css and the line the rule is on, the overridden rules will have a strikethrough. Once I figure out what rules are taking precedence I can raise or lower the weight of the rule to make it inherit properly.
Hopefully that helps!

Resources