问题
Is there a way to use CSS variables with Sass functions e.g. lighten? Something like this:
:root {
--color: #ff00ff;
}
.div {
background-color: lighten(var(--color), 32%);
}
I'm getting an error message that "Argument $color
of lighten($color, $amount)
must be a color".
I'm using CSS (not Sass) variables, because I need to use them in js.
回答1:
UPDATE:
I just read that Sass 3.5.0 now should support CSS Custom Properties with native CSS functions. I tried this with node-sass but as yet libsass doesn't support this feature of Ruby Sass 3.5
For native CSS functions I think sass replaces them with its own implementation, as I had to use string interpolation in Sass to get my css to compile:
--Primary: #{"hsl(var(--P-h), var(--P-s), var(--P-l))"};
For Sass functions, the closest thing I came up with pure CSS for lightness (won't work with IE, obviously), is to separate the colour values into hue, saturation and lightness to use inside hsl(). This could also be used with rgba(), but hsl() can be used to control shades more easily for the theme of the application:
:root {
--P-h: 203;
--P-s: 82%;
--P-l: 41%;
--Primary: hsl(var(--P-h), var(--P-s), var(--P-l));
}
Then the shades for active, hover, accents etc. can use an altered lightness by using calc to calculate a percentage of the original lightness:
:root {
--Primary-20: hsl(var(--P-h), var(--P-s), calc(var(--P-l) * 0.8));
}
This could go the other way to lighten also, but this won't work for every scenario. It's also pretty messy and you end up with a bit of pollution in the variable scope.
回答2:
CSS variables are not supported in IE.
Also, lighten
is a function of CSS pre-processors and so if you add it to CSS in its un-compiled form it will just break your code as CSS wouldn't know what it is
I suggest pseudo-elements
See this example
div>div {
height: 150px;
width: 150px;
margin: .5em auto;
display: inline-block;
}
.red {
background-color: red
}
.blue {
background-color: blue
}
.green {
background-color: green
}
.lighten,
.darken {
position: relative;
}
.lighten::after,
.darken:after {
content: "";
display: block;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.lighten::after {
background-color: rgba(255, 255, 255, .4);
}
.darken::after {
background-color: rgba(0, 0, 0, .4);
}
<div>
<div class="red lighten"></div>
<div class="red"></div>
<div class="red darken"></div>
</div>
<div>
<div class="blue lighten"></div>
<div class="blue"></div>
<div class="blue darken"></div>
</div>
<div>
<div class="green lighten"></div>
<div class="green"></div>
<div class="green darken"></div>
</div>
For reference only
Since you already mentioned that this is for JS, There are probably more effifecnt ways of doing this.
For example... this example from CSS-Trick
Usage summery:
// Lighten
var NewColor = LightenDarkenColor("#F06D06", 20);
// Darken
var NewColor = LightenDarkenColor("#F06D06", -20);
$.cssHooks.backgroundColor = {
get: function(elem) {
if (elem.currentStyle) var bg = elem.currentStyle["backgroundColor"];
else if (window.getComputedStyle) var bg = document.defaultView.getComputedStyle(elem, null).getPropertyValue("background-color");
if (bg.search("rgb") == -1) return bg;
else {
bg = bg.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
function hex(x) {
return ("0" + parseInt(x).toString(16)).slice(-2);
}
return "#" + hex(bg[1]) + hex(bg[2]) + hex(bg[3]);
}
}
}
function LightenDarkenColor(col, amt) {
var usePound = false;
if (col[0] == "#") {
col = col.slice(1);
usePound = true;
}
var num = parseInt(col, 16);
var r = (num >> 16) + amt;
if (r > 255) r = 255;
else if (r < 0) r = 0;
var b = ((num >> 8) & 0x00FF) + amt;
if (b > 255) b = 255;
else if (b < 0) b = 0;
var g = (num & 0x0000FF) + amt;
if (g > 255) g = 255;
else if (g < 0) g = 0;
return (usePound ? "#" : "") + (g | (b << 8) | (r << 16)).toString(16);
}
$("div > div:first-child").each(function() {
var randColor = '#' + '0123456789abcdef'.split('').map(function(v, i, a) {
return i > 5 ? null : a[Math.floor(Math.random() * 16)]
}).join('');
$(this).css("background", randColor);
});
$("body > div").each(function(i, el) {
var interval = 0;
var masterColor = $(el).find("div:first-child").css("background-color");
$(el).find("div").each(function(i, el) {
var adjustedColor = LightenDarkenColor(masterColor, interval);
$(el).css("background-color", adjustedColor);
interval += 20;
});
});
body>div {
width: 10%;
float: left;
}
body>div>div {
height: 50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
来源:https://stackoverflow.com/questions/45496360/using-css-variables-as-sass-function-arguments