Any reason why this isn't working?
:root {
--color-white: 0 0% 100%;
}
color: hsla(var(--color-white) 1);
I'm getting:
SCSS processing failed: file "_page.scss", line 5, col 16: Function hsla is missing argument $saturation.
I also tried
color: #{hsla(var(--color-white) 1)};
which still does not work.
Try like below. You need comma with hsla() using the old syntax
:root {
--color-white: 0, 0%, 100%;
}
.box {
color: hsla(#{var(--color-white), 1});
}
Or use the new syntax where you need / before the alpha
:root {
--color-white: 0 0% 100%;
}
.box {
color: hsl(#{var(--color-white) / 100%});
}
Reference: https://www.w3.org/TR/css-color-4/#the-hsl-notation
SASS attempts to compile the styles with a SASS-specific hsla() function. However, hsla() is also a native CSS function, so you can use string interpolation to bypass the SASS function.
:root {
--color-white: 0 0% 100%;
}
div {
/* This is valid CSS, but will fail in a scss compilation */
color: hsla(var(--color-white) 1);
/* This is valid scss, and will generate the CSS above */
color: #{'hsla(var(--color-white) 1)'};
}
Taken from this answer on SO.
hsla() takes four inputs and the punctuation needs to be accurate or none of it will work. No hash tags are needed:
--color: 0, 100%, 50%;
color: hsla(var(--color), 1);
This 100% works (pun intended).
Please, add commas between --color-white's percentages and after passing the var (before '1' in color).
This solution should work:
:root {
--color-white: 0, 0%, 100%;
}
color: hsla(var(--color-white), 1);
It looks like rgb() works without commas, but hsla() needs commas.
See here: http://codepen.io/Aleksgrunwald/pen/abpQQrr
Related
I"m trying to use CSS custom properties in a rgba value. I am able to get the desired result in pure css, but when I test this out in codepen.io or my IDE that are both using scss, I am getting an error of: overloaded function `rgba` given wrong number of arguments . How can I incorporate this in SCSS
Here is a codepen that shows the error: https://codepen.io/tmocodes/pen/xxVdMEq?editors=1100
The below snippet works because it is not using SCSS.
:root {
--color-primary: 29 4 247;
--lighten: 10%;
}
#element {
background-color: rgba(var(--color-primary) / var(--lighten));
color: rgb(var(--color-primary));
}
<h1 id="element">Using CSS Custom Properities with opacity</h1>
To incorporate modern comma-free CSS color syntax with SCSS, I've used this workaround.
The reason this doesn't work is that it conflicts with the Sass rgb/rgba function. You can uppercase one or more letters to make Sass ignore it (being case sensitive). CodePen demo.
$color-primary: 29 4 247;
$color-secondary: 247 4 4;
$lighten: 10%;
#element {
background-color: Rgba($color-primary / $lighten);
color: Rgb($color-primary);
}
#element-2 {
background-color: Rgba($color-secondary / $lighten);
color: Rgb($color-secondary);
}
SCSS preprocessor has to computed the vales before it can be assigned to the css variables.
Following approach might give you hint to approach the solution you are looking for.
rgba require 4 parameters
rgb require 3 parameters.
$blue: rgb(29, 4, 247);
$red: rgb(29, 4, 247);
$lighten: 10%;
:root {
--color-primary: #{blue};
--color-secondary: #{red};
--lighten: #{lighten};
}
#element {
background-color: lighten($blue, $lighten);
color: $blue;
}
#element-2 {
background-color: lighten($red, $lighten);
color: $red;
}
I created the following CodePen, that gives the idea of how to combine scss with css variables.
I have used scss variables in all of my code, like this:
$primary: royalblue;
body {
background: $primary;
color: black;
}
.list-item {
// some code
span, a {
background: black;
color: $primary;
}
}
now, I want to create an animation for body background color:
#keyframes bganimation {
from {
$primary: royalblue;
}
to {
$primary: tomato;
}
}
but I know scss is a language that compiles to css... is there any other way to do that?
I can't rewrite the code, help please.
I guess you first have to understand how SCSS Variables actually work:
When compiling SCSS to CSS the variables are replaced with the actual current value of the variable so in the end there won't be any variables anymore.
That said your keyframes block will simply be an empty block in the end.
If you want to have real variables, you would have to use actual CSS Variables
--some-variable: red;
(Notice that this won't work out of the box in "browsers" like IE)
There are more things you should fix in your code:
- There is no animation set for any of the elements (via animation attribute)
- In the keyframes block you have to define which attribute should animate and what value they should take while animation
eg:
#keyframes bganimation {
from {
background-color: red;
}
to {
background-color: blue;
}
}
So you would have to rewrite the code at least a bit for it to work.
You have to animate the background-color property, so it should be:
#keyframes bganimation {
from {
background-color: $primary;
}
to {
background-color: tomato;
}
}
I add css variable to root because i want to change it dynamically by using JS
#root {
--primary-color: #4c5b73;
}
$primary-color: var(--primary-color) !default;
.my-component {
background-color: transparentize($primary-color, 0.85);
}
I want to use the Basic scss function transparentize
or lighter or darker
But i got this error
Argument `$color` of `transparentize($color, $amount)` must be a color
How can i tell that this is a color type?
Update
I should do this more earlier
https://codepen.io/colton123/pen/bGVbRjP
Instead of declaring the : root variable first, makes the code like this one.
Your code flow is not right. It may gonna help you. You should study this article
$primary-color: #4c5b73;
: root{
--primary-color: #{$primary-color};
}
.my-component {
background-color: transparentize($primary-color, 0.85);
}
You could just add the alpha channel in regular CSS if you define the color using decimal RGB values instead of a hex code:
:root {
--primary-color: 76, 91, 7;
}
body {
background-color: white;
}
.my-component {
background-color: rgba(var(--primary-color), 0.15);
}
<div class="my-component">
Test
</div>
You would use getComputedStyle and getPropertyValue
this solution should get you what you need. :)
Say you have the CSS custom property for a color:
--color: 255,0,0
And you want to mix it specially every time with rgb or rgba as the need requires. This is valid CSS:
rgba(var(--color), .3)
...but Sass explodes. I've been trying to see if I could write a mixin or something but I can't figure out how to get around Sass's insistence on using it's own color functions even when they are not necessary.
Got it! This is a bit hacky but this allows you to create a custom function that utilizes the rgba() function with CSS custom properties (as allowed in the spec):
#function swatch($swatch-color, $swatch-alpha:1) {
#return unquote("rgba(var(--#{$swatch-color}), #{$swatch-alpha})");
}
:root {
--green: 0,255,0;
}
.green { color: swatch(green, .1); }
Found the key to the solution in a Sass bug report. This only works because the unquoting and interpolation bypass the default rgba() function.
Perhaps using interpolation rgba(#{--color}, .3)?
Another temporary workaround for this is to use RGB values only in your variables like you are already:
--color: 255, 255, 255;
Then if you use the RGB or RGBA function with capitals, SASS will ignore it and plain CSS is able to parse it. You can then adjust the opacity!
RGB(var(--color));
RGBA(var(--color), .3);
rgba(var(--color), .3) is not valid:
div {
width: 50px;
height: 20px;
outline: 1px dashed black;
}
:root {
--color: red;
}
#correct {
background: var(--color);
}
#incorrect {
background: rgba(var(--color), .3);
}
<div id="correct"></div>
<div id="incorrect"></div>
Using CSS, LESS, or Sass can you assign the same value to 2 css properties at once?
Just like:
.c1, c2 {sameValue}
But instead like this:
.c2 { background-color:, color: sameValue}
You can't do this with CSS.
The easiest way to do this is use a variable. Here's how you'd do that in LESS
#color: red;
.demo {
background-color: #color;
color: #color;
}
and the same thing in Sass
$color: red;
.demo {
background-color: $color;
color: $color;
}
But you can also achieve the power you want. Here's one way you could do it in LESS:
.properties(#properties, #value, #i: 0) when (#i < length(#properties)) {
#property: extract(#properties, #i + 1); // get the property
#{property}: #value; // write the style
.properties(#properties, #value, (#i + 1)) // loop
}
.demo {
#props: background-color, color;
.properties(#props, red)
}
will compile to your desired
.demo {
background-color: red;
color: red;
}
How's it work?
.demo calls the .properties parametric LESS mixin, passing a list (sometimes called an array in other SO questions about CSS/etc) of properties (.properties's #properties parameter; in this example, #props) and the value to assign to all of them (.properties's #value parameter; in this example, red).
note that .properties has a counter parameter #i with a default value of 0.
.properties has a LESS CSS guard that checks to see if #i is less than the number of properties it was passed (held in #properties). It is! (#i is 0, and the properties' list is certain to be at least 1) Okay, so we're allowed past the guard.
Get the name of the property: use LESS's extract() on the first item in the list (we need to say #i + 1 because we started the #i counter at 0. we could have also started #i at 1, and guarded with when (#i < (length(#properties) + 1)) but that's harder to read)
At last: write the style. interpolate the variable holding the property name (#property) as a string (#{property}), and give it the value we originally passed to .properties in .demo (#value)
LESS loop! Run .properties again, but advance the counter #i one: .properties(staysTheSame, staysTheSame, (#i + 1))
.properties will run until it's looped through all the items in its #properties list. After that, #i will equal length(#properties), so we won't pass the when (#i < length(#properties)) guard.
Note that #props could be defined within .test, as above, or anywhere where .test will have access to it, and same for the value. You might end up with
#props: background-color, color;
#val: red;
#val2: green;
.properties {...}
.demo {
border-color: #val2;
.properties(#props, #val)
}
.demo2 {
.properties(#props, #val2)
}
If your browser supports Custom Properties (AKA CSS Variables) you can define a custom property for reuse:
.foo {
--example: red;
background-color: var(--example);
color: var(--example);
}
Otherwise you'll need to rely on a preprocessor such as LESS:
.foo {
#example: red;
background-color: #example;
color: #example;
}
or Sass:
.foo {
$example: red;
background-color: $example;
color: $example;
}
As far as being able to chain properties, I'm not aware of any preprocessor or specification that allows for that syntax.
I don't think you can in the way you described, you would need to use a variable. However you can achieve something similar with properties that share the same namespace.
.funky {
font: {
family: fantasy;
size: 30em;
weight: bold;
}
}
http://sass-lang.com/documentation/file.SASS_REFERENCE.html#nested_properties
In Stylus is possible to do the Property lookup, which allows you to use properties in the current or closest parent ancestor and use it for calculations.
For you specific case you could write:
.demo
color: red
background-color: #color
which produces this CSS:
.demo {
color: red;
background-color: red;
}
It is a feature asked also for LESS but currently there are not plans to develop it. Currently in LESS (and in SASS) you must use one of already suggested solutions, passing by an additional variable.
With Stylus you can do this way using iteration and interpollation :
.modal
position : absolute
for bord in top bottom left right
{bord}: 1em
for larg in width min-width height min-height
{larg}: auto
for maxl in max-width max-height
{maxl}: none