Polymer setting custom CSS property on inner element without using "!important" - css

I have a custom element x-foo which I have defined a custom CSS property on to set the background-color called --xbg.
I use the element with elements of itself as children as so:
<x-foo class="outer">
Outer
<x-foo class="inner">
Inner 1
</x-foo>
</x-foo>
When I set --xbg on the outer, that value overrides the value of the inner element:
x-foo.outer {
--xbg: orange;
}
x-foo.outer x-foo {
--xbg: red;
/* Doesn't work, have to use !important?!?!*/
}
I've used the inspector in Chrome and can see that the child definition indeed is "lower" then the parent.
I have to "force" it to get higher with !important, which then has all sorts of other implications.
x-foo.outer x-foo {
--xbg: red !important;
/* Works */
}
Why is the child not overriding the parent property?
Here's a plunker for this with some more examples:
https://plnkr.co/edit/uZxg7G?p=preview (Only works in Chrome)
Simpler JSBin for other browsers:
http://jsbin.com/wuqobejeci/edit?html,output

the best way to solve this is to say the style only applies to the class contentwrapper from that host down
<style>
:host {
display: block;
}
:host > .contentwrapper {
padding: 1em;
background-color: var(--xbg, yellow);
}
</style>
Like that,
Here is a working Fiddle

The element has lower priority than the class. Try
x-foo.outer {
--xbg: orange;
}
x-foo.outer x-foo.inner {
--xbg: red;
}

Thought this was worth trying just based on Andrew's answer above -- just using the host style alone seems to work:
<style>
:host {
display: block;
padding: 1em;
background-color: var(--xbg, yellow);
}
</style>
https://jsfiddle.net/6tzoacxr/

Related

Unable to override storybook preview panel?

I found a way to override .sb-show-main by having a storybook.scss as below.
//.storybook/storybook.scss
.sb-show-main {
background-color: green;
padding: 16px;
margin: 20px;
}
Then simply import it into .storybook/preview.js
import "./storybook.scss";
The problem I'm facing and couldn't understand is that, background-color: green do have effect, but padding & margin seems to be ignored. Wondering if anyone ever modifying sb-show-main?
The default value for padding is 1rem, I would like to change it to 20px instead.
The styles you are trying to overwrite may be using the css !important directive, or may be more specific in their targeting of an element. I always try to be specific first, but otherwise I will use !important as a last resort.
.container header ul li p {
color: blue;
}
// OVERWRITE STYLES
p { /* this wont work, because it's not as specific as the original rule */
color: yellow;
}
.container header h1 ul li p { /* try this first */
color: purple;
}
p { /* otherwise use !important as last resort */
color: orange !important;
}
<div class="container">
<header>
<h1>Logo</h1>
<ul>
<li><p>One</p></li>
<li><p>Two</p></li>
<li><p>Three</p></li>
</ul>
</header>
</div

what is the way to child element not inherit parents property?

what is the way to child element not inherit parents property?
I know way to child element declare individually property.
I curious that people use another way.
You can either set some styles only for that element:
p{ color:red; }
or overwrite the default inherited styles (like margin in this case):
p{ margin: 0; }
or, in some contexts add a class or an id to add more weight to the selector (adding an id to the p):
div p{ color: blue; }
#myParagraph{ color: red; }
This could be a way
div{
padding:10px;
}
div *{
padding: 0px;
}
But its highly NOT RECOMMENDED for elements with many children

Apply a style on element A if element B contains a certain class

Is it possible to check the class of an element, see if it exists, and then apply the style for another class?
Example pseudo code:
if (.myClass .myBlock == true) {
.otherClass {
display:none
}
}
It's not possible in this context. But you can achieve a similar result with the cascading nature of CSS.
Apply a class to the body of your website:
.another-class {
display: none; // hides .another-class by default
}
body.special-class {
.another-class {
display: block; // shows if the body contains .special-class
}
}
Since the specificity of the generated output is higher at the second rule, the elements with .another-class will be visible.
Give the following row a class
Utilising the + selector enables us to display the row after the mentioned class. This way we can style dropdowns popups, given we have the following HTML:
.popup {
display: none;
}
.popup:hover {
display: block;
}
.container:hover + .popup {
display: block;
}
<div class="container">Hover me!</div>
<div class="popup">This is a popup!</div>
I'm afraid that's all that is possible with CSS.

How to clear the parent css

Say you had a Css style defined below .
div
{
background: url(themes/default/images/backgrounds/lh-navigation.png) repeat-x;
}
.child
{
backgroud-color:#FFFFFF;
}
<Div id="tempDiv" class="child"></Div>
I don't want the backgroud style applied to element tempDiv. How can i remove the parent style for the a specified div element. Is there any way to make it ?thanks
In CSS children inherit properties from parents. You'll have to override the style of the parent in your child style declarations. In this case, since it is a background you are trying to override your .child style declaration will look like this:
.child {
background-image: none;
background-color: #FFFFFF;
}
As the others above have pointed out you could also expand on the selector and write a new rule for the id attribute on the element:
#tempDiv {
background: none;
}
try:
.child#tempDiv{
background: none;
}
note the absense of whitespace between the id and class since it is on the same element.

SASS Replicating nested selector

I'm using SASS for a project and so far I'm pretty satisfied with it.
However I have some code that should only be presented for IE 7 and below, using the class name .ie-lt8 for that. But when i extend that selector in SASS, with a nested selector i create multiple selectors.
Example (extending a display: inline-block code for IE):
SASS
/* My extension code */
.ie-lt8 %ie-inline-block {
display: inline;
zoom: 1;
}
/* I want the li to be inline-block */
#my-ul li {
display: inline-block;
#extend %ie-inline-block;
}
CSS produced
/* My extension code */
.ie-lt8 #my-ul, #my-ul .ie-lt8 li {
display: inline;
zoom: 1;
}
/* I want the li to be inline-block */
#my-ul li {
display: inline-block;
}
Generally this is just fine, but the #my-ul .ie-lt8 li worries me a little. In this example it's ok as the code works fine with both selector (the mentioned selector just doesn't exists). But what if i have another code where the selector DOES matter, then this would cause a problem.
A thought example:
SASS
/* I want the div to get a red border,
but the div inside .container to have a green border */
#myid .container div { border: 5px dotted green; }
#myid div {
#extend %red-border;
}
/* My extension code */
.container %red-border {
border: 1px solid red;
}
CSS it would produce
/* I want the div to get a red border,
but the div inside .container to have a green border */
#myid .container div { border: 5px dotted green; }
/* My extension code */
.container #myid div, #myid .container div {
border: 1px solid red; /* [OVERRIDE OF THE BORDER] */
}
My question is then; is there a way to make SASS only take the initial selector, without creating multiple selectors from a nested selector (a lot of selectors in one sentence)?
I tried gooling for this issue, but i find it hard to find any articles/blogs/etc. regarding this issue.
UPDATE
I'm aware of various workarounds, such as using #mixin's instead. I was just wondering whether there was something i missed regardig SASS, or if someone could tell me why this is? Cause it seems to me like it's kind of a bug.
My answer is in SCSS - not SASS so you'll have to convert...
For browser targeting like this, I would recommend using mixins, and furthermore - #content within a #mixin to achieve your desired results. It also sets up a much more understandable set of rules with context.
For your specific example, it's as simple as moving your inline-block fix into a mixin instead of declaring only as a class.
#mixin ie7-inline-block {
display: inline;
zoom: 1;
}
#my-ul li {
display: inline-block;
.ie-lt8 & {
#include ie7-inline-block;
}
}
Even better than that though, by using #content, you can always ensure that your style is prefixed with .ie-lt8 by making a mixin like so:
#mixin ie7 {
.ie-lt8 & {
#content;
}
}
#my-ul li {
display: inline-block;
#include ie7 {
display: inline;
zoom: 1;
}
}
Which will output the same css, but allows your IE7-Specific styles to be wrapped each time in some context that makes sense to anyone who reads your code.

Resources