44

I have a Sass file which is generating a CSS file. I have used many variables in my sass file for background color, font-size, now I want to control my all variables through JavaScript.

For example, in style.sass we have

$bg : #000;
$font-size: 12px;

How can I change these values from JavaScript?

10 Answers 10

30

You can't. SASS is a CSS preprocessor, which means that all SASS specific information disapears when you compile it to CSS.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks GJK.but i want to change my variables before css generation. like some is doing in bootstrap themeroller, in the same way i wanted to theme my web page.
Well, I can tell you that there's certainly no Javascript library pre-made to manipulate SASS files. You're going to have to do it server-side (via Node.js if you want to use Javascript) using plain old file IO.
24

CSS

:root {
  subTitleLeftMargin: 1.5vw;
}

.element {
  margin-left: var(--subTitleLeftMargin);
}

JS or TS

document.documentElement.style.setProperty("--subTitleLeftMargin", "6vw");

3 Comments

document.documentElement.style would not work server-side right?
I don't think so.
this changed a variable value but chnaged not effect anywhere @Krull
11

I also needed this functionality, here's what worked for me:

With JS you can set a class to body, ex. .blue or .default Now create a set of rules to extend from, which you'd like to set:

.default .themeColor {
  color: 'red';
}
.blue .themeColor {
  color: 'blue';
}

Now instead of having color: $someColor in your scss file, use it like this:

.someClass {
   @extend .themeColor;
 }

Now, if your body will have the default class, the color inside someClass will be red, and if body will have the blue class the color will be blue.

2 Comments

will not work with shadow dom or shadow dom emulation (like component style encapsulation in angular)
@Ziarno that is true, so in the case of Angular, you can put these classes in the main src/styles.scss file, which is defined in angular.json to be loaded into all components. Then they will be available everywhere.
9
  • Use Sass, or any other variables to set initial values

  • JavaScript sets CSS custom properties of the same name to update those values as needed (same name is just a preference).

You do not need to define CSS root properties because the Sass variable is the fallback and will be used initially. This allows you to do whatever you want server-side with Sass or any other style processor, and update the values client-side.

Here is an example of a color picker controlling the background-color.

see Codepen demo here.

scss

$selectedColor: #000;

body {
  background: var(--selectedColor, $selectedColor);
}

html

<input type="color">

js

const colorInput = document.querySelector('[type=color]')

// Set the CSS custom property --selectedColor on the root element
// Now JavaScript controls this variable and everywhere you used Sass variables if you follow this pattern
const handleColorInput = e => document.documentElement.style.setProperty("--selectedColor", e.target.value)
    
colorInput.addEventListener('input', handleColorInput)

Comments

3

I find sass-extract-loader especially helpful for using with Create-React-App.

You can use it like:

_variables.scss

$theme-colors: (
  "primary": #00695F,
  "info": #00A59B
);

component.tsx

 const style = require('sass-extract-loader!./_variables.scss');
 const brandInfo = style.global['$theme-colors'].value.primary.value.hex; // '#00695F';

Comments

1

If you're looking to do what bootstrap do (ie editing fields to download a theme).

You'd have to:

  1. Have the files on hand that you want to edit
  2. Store these variables as a string, and use .replace() to search and replace variables
  3. Output this string and compile it to a file and or zip it up for download.

I'd personally do this with php.

Comments

1

Share data between Sass and JavaScript using JSON.

See related question https://stackoverflow.com/a/26507880/4127132

Comments

1

JavaScript runs client-side (in the web browser), while Sass is generated server-side, so you have to find some way to bridge that gap. One way to do this would be to set up some AJAX-style listening to send JavaScript events over to your server, and then have the server edit and re-compile your style.sass file.

2 Comments

Thanks katiek. but i heard that with the help ok node.js we can do this. [link]npmjs.org/package/node-sass
Hi @Ankit sir, is it really possible with this tool, please tell us how ?, now days in react official site recommend this.
0

variable in style

:root {

  --bg: #000;
  --font-size:12px;

}

change variable value by javascript

root.style.setProperty('--bg', '#fff');
root.style.setProperty('--font-size', '14px');

1 Comment

That will change a css variable not a scss variable
0

I have used many variables in my sass file for background color, font-size

I think you might be trying to solve the wrong problem. Managing the variables in javascript will just move the problem from point A to point B

What I imagine you're doing and its a natural mistake many people make:

$bg-color: rgb( 255, 0, 0 );
$bg-color-alt: rgb( 128, 0, 0 );
$link-color: rgb( 255, 0, 0 );
$link-color-hover: rgb( 128, 0, 0 );

You define your colors based on how you're using them within the design

What you should be doing is defining your palette and having the colors be relative within that.

$red-100: rgb( 255, 0, 0 ); // #f00
$red-200: rgb( from $red-100 calc( r / 2 ) g b ); // #800000
$red-300: rgb( from $red-200 calc( r / 2 ) g b ); // #400000
  1. prevents you from redundant definition of values because of how something is used (i.e. red is defined once, regardless of where you're using it)
  2. it saves you from meaningless variable names (i.e. red, darkRed, darkerRed, darkestRed, darkerThanDarkestRed)
  3. makes it easier for other people to jump into your work (no one has to guess what you meant by darkerRed)
  4. saves you from making a mistake with your palette since the colors are all relative

This methodology obviously doesn't only apply to colors, but fonts too.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.