Is there a way to directly assign a CSS value to a SASS variable, like this:
$var:padding: 20px/1440px * 100%;
I know that I can to this:
$padding: 20px/1440px * 100%;
padding: $padding;
But is there a way to directly assign a value in CSS to a variable? Basically to have it on a same line.
not possible to use a variable directly, you could use a mixin instead:
#mixin pad{padding: 20px/1440px * 100%;}
.div-with-padding{#include pad;}
http://jsfiddle.net/gTsG9/
no its not possible to assign directly from the variable. you have to use mixin for that.
sample :
#mixin ur_padding
{
padding:20px/1440px * 100%
}
.ur_div_here
{
#include ur_padding;
}
You could assign a css value like a string:
$var:"padding: 20px/1440px * 100%";
But I really don't know how is this going to help you. Mixin is the best way.
Related
this is my first question here, so please be patient if I am doing something wrong :)
I have some weird problem and I still haven't found a solution, even though I've spent a few hours searching on Google.
So I have a CSS custom property called --vh that I set up dynamically with JavaScript.
In order to make life easier and not write all this long syntax with the var every time, I wanted to create the Sass variable called $vh and use it wherever I need it:
$vh: var(--vh, 1vh);
$m-distance: $vh * 2;
$input-height: $m-distance * 1.6;
$sm-distance: $m-distance * 0.5;
$l-distance: $m-distance * 1.6;
$xl-distance: $m-distance * 2;
// And there are dosens of places in my app where I later use these variables...
But when I do that right away in the next line I get an error:
SassError: Undefined operation: "var(--vh, 1vh) times 2".
on line 21 of src/styles/setup/_variables.scss
from line 4 of /home/joisadler/github/fymdaily/client/src/styles/global.scss
>> $m-distance: $vh * 2;
-------------^
And if for example instead of $vh: var(--vh, 1vh); I write just $vh: 1vh;, everything passes successfully. But this is not what I want because I need my vh to be rather dynamic.
I have found lots of explanations for the reverse case when I want to use the Sass variable within the custom property definition. But I need to do the exact opposite and use custom property within the definition of the Sass variable.
Does anyone have any idea how to do such things?
Thanks in advance!
I have now come up with a pretty simple solution on how to do what I wanted, I checked and it really works great.
First of all I defined all my variables as custom properties:
// _base.scss
:root {
// --vh property itself defined dynamically by JavaScript
--m-distance: calc(var(--vh, 1vh) * 2.5);
--input-height: calc(var(--m-distance) * 1.6);
--sm-distance: calc(var(--m-distance) * 0.5);
--l-distance: calc(var(--m-distance) * 1.6);
--xl-distance: calc(var(--m-distance) * 2);
}
And after that I just defined sass variables with the same names:
// _variables.scss
$m-distance: var(--m-distance);
$input-height: var(--input-height);
$sm-distance: var(--sm-distance);
$l-distance: var(--l-distance);
$xl-distance: var(--xl-distance);
And now I enjoy two worlds: also get the --vh property dynamically from JavaScript and can also use Sass variables with shorter and nicer syntax in all the other files in my app.
I've tested the following on https://www.sassmeister.com/ and it seems to work.
Input
:root {
--vh: 10vh;
}
$var: var(--vh, 1vh);
body {
height:$var;
}
Output
:root {
--vh: 10vh;
}
body {
height: var(--vh, 1vh);
}
Have you tried declaring a default value for --vh inside the Sass file so the compiler recognises it and doesn't produce an error?
Yes, but not to calculate with SASS functions
Why assign a SASS variable to the value of a CSS custom property? For calculations (as in your question) and useful built-in functions like color.scale(). You won't be able to use these tools with values derived from CSS custom properties.
#use "sass:color";
:root {
--basic_color: #FF0000; // Red
}
$sassy_color: var(--basic_color, #00FF00); // Red with green fallback
$pure_color: #FF0000; // Red
body {
background-color: $sassy_color; // ✅ Red background
color: color.scale($pure_color, $lightness: +90%); // ✅ Red text, or
color: color.scale($sassy_color, $lightness: +90%); // 👎 Error: not a color
}
As Josh Bonnick shows, you can put a CSS custom property insertion statement into a SASS variable, as in background-color: $sassy-color, but that's not very useful; it might as well be a custom property insertion. Unfortunately, this is only a string, and SASS won't evaluate the var() function call.
Let's say we want to change the lightness of the color, as in color: color.scale(). If our SASS variable uses a color primitive ($pure_color), it works as intended, but if we use a variable that represents an CSS custom property ($sassy_color), it fails, because it can't do math on the string var(--basic_color, #00FF00);.
So why do it? Organization
In a beautiful SASS architecture proposal, Felippe Regazio lays out a method for making CSS custom properties his styling modules using SASS functions as getters and setters. This is essentially all string manipulation, and it shows how useful it can be to access CSS custom properties with SASS variables even if you're not going to use them for calculations.
/**
* Retrieve a css variable value with prefix
*
* Usage
*
* .selector {
* color: get(primary-color);
* }
*
* Will result in
*
* .selector {
* color: var(--prefix-primary-color);
* }
*/
#function get($name, $prefix: pm) {
#return var(--#{$prefix}-#{$name});
}
/**
* Update a css variable value
*
* Instead of
*
* .selector {
* --#{$prefix}-button-height: 56px;
* }
*
* Usage
*
* .selector {
* #include set(button-height, 56px);
* }
*/
#mixin set ($name, $value: '', $prefix: pm) {
--#{$prefix}-#{$name}: #{$value};
}
Read the article for more details.
Let's say I use bootstrap and what to override the padding-top of jumbotron class of a percentage using less and mixin
Is it possible to do something like this?
// this is my style.less file loaded *after* bootstrap.css
.jumbotron {
padding-top: _original_padding-top_ * 0.5
}
See https://github.com/twbs/bootstrap/blob/v3.3.7/less/jumbotron.less
So you simply do something like:
#import "bootstrap/variables.less";
.jumbotron {
padding-top: #jumbotron-padding * .5;
}
}
The percentage mixin only accepts one parameter, so what you propose is not possible.
See here. It's always good to check the reference documentation.
You will have to create your own mixin to do that.
I'm trying to create a dynamic css property using SASS by using mixins.
#mixin setProperty($property,$value,$unit:null){
#{$property} :$value$unit;
}
.class{
#include setProperty(position,relative);
}
This creates an output
.class {
position: relative;
}
I'm fine with this. But when i create some property for margin or padding we should include PX. So i tried something like this
.class{
#include setProperty(margin,10,px);
}
which creates output with a space in the middle as follows. How do i get rid of these space.
.class{
margin: 10 px
}
You should use interpolation to concatenate the values instead of adding, you can try this:
#mixin setProperty($property,$value,$unit:null){
#{$property} :#{$value}$unit;
}
When two distinct values are next to one another, Sass always adds a whitespace between them. With the interpolation it does not happen, Sass try to parse everything as an unquoted string.
I've been looking for the answers, but either it's not what I am really looking for, or I am not searching up properly. I want to dynamically generate the class name. Since, I use margin-top quite frequently, I have multiple classes defined with a set of rules, and I want to achieve with LESS.
I don't think is possible to create dynamic generated classes, as far as I did my research. Here is my code:
.margin-top-(#value)px {
margin-top: #value;
}
Desired Output
.margin-top-20px {
margin-top: 20px;
}
.margin-top-100px {
margin-top: 100px;
}
Just an example of what I am expecting.
Try to use mixin to achieve this.
//define the mixin
.margin-top(#value) {
.margin-top-#{value}{
margin-top:#value;
}
}
//use the mixin like this
.margin-top(20px);
U can try it here: http://winless.org/online-less-compiler
I am converting LESS to CSS, there I want to run the LESS function below:
.myPL( #val ) {
.pL #val{
padding-left:#val;
}
}
Function Call:
.myPL( 20px );
Expected result:
.pL20px{padding-left:20px}
But actual result is Syntax Error.
Please help me to concatenate the strings in class name in LESS.
What you are looking for is called selector interpolation ... you can find it here: http://lesscss.org/#-selector-interpolation
Your mixin would need to look like this for it to work:
.myPL( #val ) {
.pL#{val} {
padding-left: #val;
}
}
What you are trying to achieve does not work in LESS:
You could do:
.myPL( #val ) {
padding-left: #val;
}
Why on earth would you manually define each possible variant of padding left with the classname itself? That's not what LESS was designed for, and doesn't really make much sense with the context you've given.
The idea of mixins is to make them reusable, but I can't understand why you'd call a classname in the middle of that mixin. Use LESS mixins properly, and do the following:
.pl(#val) {
padding-left: #val;
}