Overriding :root CSS variables from inner scopes
This is a scoping issue. The way you're doing it, you're inheriting --orange
from the :root
, and --orange
in the :root
has a lightness of 68%.
In order to change it, you'll want to re-scope the --orange
variable to an element that will look up the new --lightness
value. There's a few ways to pull this off:
Option 1: duplicate the --orange
variable on the element:
:root { --lightness: 68%; --orange: hsl(255, 72%, var(--lightness));}.card { background: var(--orange); --orange: hsl(255, 72%, var(--lightness));}.card:hover {
--lightness: 45%;}
<div class="card"> Hello world</div>
Can I use a custom property with fallback to define part of a custom property
CSS variables don't work in the way that you are trying to use them. Variables that are defined with other variables only take variables on the same level or levels above them.
A nice "hack" that I found was, instead of using the :root
selector, use the universal selector *
to define the varibales on all levels. That way, since you define the color variables on the same level, changing the opacity variable works. Keep in mind that this might cause some unwanted results, and if you want to consider other solutions, these might help you:
CSS scoped custom property ignored when used to calculate variable in outer scope
Overriding :root CSS variables from inner scopes
* {
--opacity: 50;
--clr-900: hsla(36, 83%, 0%, var(--opacity, 1));
--clr-700: hsla(36, 83%, 30%, var(--opacity, 1));
--clr-300: hsla(36, 83%, 70%, var(--opacity, 1));
--clr-200: hsla(36, 83%, 85%, var(--opacity, 1));
--clr-100: hsla(36, 83%, 100%, var(--opacity, 1));
}
.test1 {
background-color: var(--clr-900);
}
.test2 {
--opacity: 0.65;
background-color: var(--clr-900);
}
<p class="test1">hello world</p>
<p class="test2">hello world</p>
Overriding css class variables with LESS
Let's think about the way LESS compiles for a second. If you want, you can try to run any of this in the https://fiddlesalad.com/less editor.
Here in this example, I've just included some arbitrary colors and a 'background' property to make it easier to understand. In your example when you import base.less, you are really just putting some LESS rules before the ones in your file. So, just to clarify, if we "expand" your import, the file might look like this before its compiled to CSS:
.some-css-class{
@color1: red;
background: @color1;
}
.some-css-class {
@color1: purple;
}
What does this output?
.some-css-class {
background: red;
}
Why? You might say "I've redeclared the color variable so shouldn't it recompile the rules?". However, this is fundamentally not how LESS is designed--its backwards compatible with CSS, so a rule must happen later to override a previous rule. Take this example instead:
.some-css-class{
@color1: red;
background: @color1;
}
.some-css-class {
@color1: purple;
background: @color1;
}
Here is the output you get now:
.some-css-class {
background: red;
}
.some-css-class {
background: purple;
}
The rules are split into two outputs, and because the second rule happens later in the cascade, it has a higher precedence--barring this class existing nowhere else, the 'purple' rule will take precedence.
In LESS, you "lazy load" variables -- it will always take the last value found, starting from the inner scope. Thus:
.some-css-class {
@color1: purple;
background: @color1;
@color1: blue;
}
Will output:
.some-css-class {
background: blue;
}
The unfortunate thing though, however, is if we try to extend your previous rule as a mixin, it resolves the values from each class before pulling them into your new class:
.some-css-class{
@color1: red;
background: @color1;
}
.some-css-class {
@color1: purple;
background: @color1;
@color1: blue;
}
.another-css-class {
.some-css-class();
@color1: orange;
}
Outputs:
.some-css-class {
background: red;
}
.some-css-class {
background: blue;
}
.another-css-class {
background: red;
background: blue;
}
The ideal way to "override" these values then, is to turn the original ruleset into a parametric mixin:
.some-css-class(@color1, @color2) {
background: @color1;
color: @color2;
}
.another-css-class {
.some-css-class(red, blue);
}
Finally, your output will look like this:
.another-css-class {
background: red;
color: blue;
}
EDIT: Ultimately I recommend, you copy the original rule out of the file (without modifying that file) and alter it to be a mixin in your version. Ultimately you'll end up with the same net amount of CSS as you would if you could extend and override the variables for your new class.
Related Topics
Differencebetween Bootstrap.CSS and Bootstrap-Theme.Css
Position a Div Container on the Right Side
Force Visible Scrollbar in Firefox on MAC Os X
Change the Icon Size of Angularjs Material Icons
Clicking Safari 5.1 Select Menu Refreshes Page
Changing the Order of Grid Item Stacking in Material-Ui
Using Grunt Grunt-Contrib-Less) for Compiling Bootstrap 3.1 Less in Visual Studio 2013
Printing Background-Color in Firefox and Ie
CSS (Perhaps with Compass): Cross-Browser Gradient
CSS Multiple Classes Property Override
How to Emulate CSS Scroll Snap Points in Chrome
ASP.NET MVC CSSrewriteurltransform Multiple Arguments
How to Avoid Webkit Contenteditable Copy-Paste Resulting in Unwanted CSS
How to Make Font-Size Relative to Parent Div
How to Vertically Align Text Next to a Floated Image
Google Chrome "Failed Parsing Sourcemap":Css.Map (Web Essential)