Accessing global variable in css - css

:root {
--color: blue;
}
div {
--color: green;
color: var(--color)
}
#alert {
--color: red;
color: var(--color)
}
<p>What's my color?</p>
<div>and me?</div>
<div id='alert'>
What's my color too?
<p>color?</p>
</div>
In the above code, how can I access the global value of --color in div with id='alert'?
Or in other words is there any way in CSS to access the global variable like the :: (scope resolution operator) in c++??

You Can't do that with CSS.
If You'll repeat the declaration of the same variable, it'll use the locally declared variable.
See this-
:root { --color: blue; }
div { --color: green; }
#alert { --color: red; }
* { color: var(--color); }
<p>I inherited blue from the root element!</p>
<div>I got green set directly on me!</div>
<div id='alert'>
While I got red set directly on me!
<p>I’m red too, because of inheritance!</p>
</div>
Source: Example 5 CSSWG

This is a possibility
:root {
--color: blue;
}
div {
color: var(--color);
}
#alert {
color: var(--color);
}
<p>What's my color?</p>
<div style="--color:green">and me?</div>
<div id="alert" style="--color:red">
What's my color too?
<p>color?</p>
</div>
Or:
:root {
--color: blue;
}
div {
--color: green;
color: var(--color);
}
#alert {
--color: red;
color: var(--color);
}
<p>What's my color?</p>
<div>and me?</div>
<div id="alert">
What's my color too?
<p>color?</p>
</div>

CSS Custom variables are inheritable, that means when you define a variable in :root, it is applicable to all elements.
When you applied it to div it changed for all div and everything inside the div.
And because they have been inherited, their parent's/root's value can't be accessed.
Check out this pen for some trials.
One method hack to do is to make a copy of the variable and use it.
:root {
--color: blue;
--colorRoot: var(--color);
color: var(--color);
}
div {
--color: green;
color: var(--color);
}
#inside {
color: var(--colorRoot);
}
<div> I am inside a div.<br><span id="inside">I am inside</span></div>
I am ouuuuuutside
Pretty sure that's not you would like to do.

Related

Can I assign a CSS variable to another?

Can I assign one globally defined CSS variable to another locally define variable?
For example, the variable --dark has been globally defined as black.
Then, I want to be able to do:
:root {
--background-color: --dark
}
.light {
--background-color: white
}
div {
background-color: --background-color
}
So that by default, my div will have a black background. And when the class light is added to it, it will have a white background.
I need the 'default' --dark variable here because it is a theme variable.
You should assign as var(--dark)
:root {
--dark : black;
--background-color: var(--dark);
}
.light {
--background-color: white;
}
div {
height: 100px;
width: 100px;
background-color: var(--background-color);
}
<div class="light"></div>
<div></div>

Sass variable change to css variable?

How i can do this?
// style.scss
$primary-color: #dc4545;
div{
background : $primary-color;
}
Try to do this:
div{
background : var(--primary-color)
}
Is this possible in any way?
You can define global variables on the :root:
:root {
--primary-color: #dc4545;
}
div {
background: var(--primary-color);
}
Edit: Or were you trying to mix and match?
$primary-color: #dc4545;
:root {
--primary-color: #{$primary-color};
}
div {
background: var(--primary-color);
}
First of all :root and html selector basically same thing but :root with higher specificity than html selector
html {
}
/*****exactly :root and html selector are same but with higher specifity(:root)*****/
:root {
--color-primary-light: #FF3366;
--color-primary-dark: #BA265D;
--bakcground-color: #fff;
--default-font-size: 16px;
--color: blue;
}
/****************How to implement***************/
.root-selector {
background-color: var(--background-color);
font-size: var(--default-font-size);
color: var(--color);
}
<div class="root-selector">
Thank you buddy
</div>

Revert css value to value before pseudo classes

<style>
div {
color: red;
}
button {
color: yellow;
}
button:hover {
color: green;
}
button:disabled {
color: inherit; /* This sets the color to red but I want yellow */
/* could do this but it's less flexible */
color: yellow;
}
</style>
<div>
<button disabled>Yo</button>
</div>
Above explains the problem that I have. I've tried using inherit, unset, initial but none of them achieve what I want. "inherit" is close but is uses the parent color. I would like to revert the color back to the original cover when an item is disabled even when its hovered without having to explicitly declare the color in the disabled pseudoclass.
You can use CSS variable to define your colors and avoid the change inside the pseudo class:
:root {
--main-color: yellow;
}
div {
color: red;
}
button {
color: var(--main-color);
}
button:hover {
color: green;
}
button:disabled {
color: var(--main-color);
}
<div>
<button disabled>Yoooooo</button>
</div>
Or make some changes to your selectors. Avoid the hover to be applied to the disabled button and this one will by default keep the initial color:
div {
color: red;
}
button {
color: yellow;
}
button:not([disabled]):hover {
color: green;
}
<div>
<button disabled>Yoooooo</button>
</div>
<div>
<button >Yoooooo yooo</button>
</div>
Why not using this?
The :not() CSS pseudo-class represents elements that do not match a list of selectors.
button, button:disabled {
color: yellow;
}
button:not(:disabled):hover {
color: green;
}
Or
button {
color: yellow;
}
button:not(:disabled):hover {
color: green;
}
https://codepen.io/anon/pen/XZepyB
div {
color: red;
}
button,
button:disabled {
/* assign the default colors together */
color: yellow;
}
button:hover {
color: green;
}
button:disabled:hover {
/* then override the disable state separately as needed */
color: #cc00cc;
}
Not sure if I understand you correctly, but this basic CSS mechanism would be:
div {
color: red;
}
button, button:hover:disabled {
color: yellow;
}
button:hover {
color: green;
}
<div>
<button>Yo</button>
</div>
<div>
<button disabled>Yo</button>
</div>
<div>
<button disabled>Yo</button>
</div>
Just add ":disabled:hover" to the "button" selector and remove the ":disabled" one:
button,
button:hover:disabled {
color: yellow;
}

Is it possible to pass a class as parameter to a mixin in Stylus?

I’m trying to reduce some Stylus code using its mixins.
In some particular cases I need a class as a parameter. Let’s we’ve got:
.parent:hover .child
color: lighten(red, -25%)
.child
color red
I’d like to have a mixin which gets both classes as parameters.
I can’t find a way from the docs. ((
You can achieve this with interpolation: http://stylus-lang.com/docs/interpolation.html
Here's an example codepen: https://codepen.io/webdevdani/pen/POVLpr
Code example from codepen:
/* Stylus */
.box {
height: 2rem;
width: #height;
background-color: blue;
padding: 1rem;
}
.red-box {
background-color: red;
}
$blockColor(parentClass, childClass) {
{parentClass} {
background-color: green;
{childClass} {
background-color: yellow;
}
}
}
$blockColor('.box', '.red-box');
<div class="box">
<div class="box red-box"></div>
</div>

css variables - declare variable if not already defined

I have a project which is split up into the parent app, and several reusable child components in separate repositories. I'd like to define default CSS variables in these child components, which can be overridden by the parent app, however I can't find the right syntax for this. Here's what I've tried:
/* parent */
:root {
--color: blue;
}
/* child */
:root {
--color: var(--color, green);
}
.test {
width: 200px;
height: 200px;
background: var(--color, red);
}
https://codepen.io/daviestar/pen/brModx
The color should be blue, but when the child :root is defined, the color is actually red, at least in Chrome.
Is there a correct approach for this? In SASS you can add a !default flag to your child variables which basically means 'declare if it's not already declared'.
CSS stands for cascading style sheets,
so you cannot override anything by a parent...
The only way is to create a stronger rule.
look at .c1 and .p1
.parent {
--background: red;
}
.child {
--size: 30px;
--background: green; /* this wins */
background-color: var(--background);
width: var(--size);
height: var(--size);
}
.p1 .c1 {
--background: red; /* this wins */
}
.c1 {
--size: 30px;
--background: green;
background-color: var(--background);
width: var(--size);
height: var(--size);
}
<div class="parent">
<div class="child"></div>
</div>
<hr />
<div class="p1">
<div class="c1"></div>
</div>
Thanks to #Hitmands hint I have a neat solution:
/* parent */
html:root { /* <--- be more specific than :root in your parent app */
--color: blue;
}
/* child */
:root {
--color: green;
}
.test {
width: 200px;
height: 200px;
background: var(--color);
}
I would suggest an approach by aliasing the variables in the component and using "parent" or root variables as main value while local value is by !default.
.parent {
--background: red;
}
.child {
--child_size: var(--size, 30px); /* !default with alias */
--child_background: var(--background, green); /* !default with alias */
background-color: var(--child_background);
width: var(--child_size);
height: var(--child_size);
}
<div class="parent">
<div class="child"></div>
</div>
<hr>
<div class="child"></div>

Resources