42

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?

rink.attendant.6
  • 44,500
  • 61
  • 101
  • 156
JA9
  • 1,708
  • 3
  • 14
  • 18

9 Answers9

29

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

GJK
  • 37,023
  • 8
  • 55
  • 74
  • 5
    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. – JA9 Jul 23 '13 at 09:01
  • 2
    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. – GJK Jul 23 '13 at 12:21
21

CSS

:root {
  subTitleLeftMargin: 1.5vw;
}

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

JS or TS

document.documentElement.style.setProperty("--subTitleLeftMargin", "6vw");
Skandix
  • 1,916
  • 6
  • 27
  • 36
Krull
  • 259
  • 2
  • 6
10

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.

Ziarno
  • 7,366
  • 5
  • 34
  • 40
  • 1
    will not work with shadow dom or shadow dom emulation (like component style encapsulation in angular) – Yuriy Kravets Jun 25 '18 at 06:33
  • @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. – SpaceNinja Mar 22 '22 at 14:22
6
  • 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)
Michael Cleary
  • 164
  • 1
  • 4
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';
Tudor Morar
  • 3,720
  • 2
  • 27
  • 25
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.

Sam Borick
  • 935
  • 2
  • 10
  • 31
KatieK
  • 13,586
  • 17
  • 76
  • 90
  • Thanks katiek. but i heard that with the help ok node.js we can do this. [link]https://npmjs.org/package/node-sass – JA9 Jul 23 '13 at 09:03
  • Hi @Ankit sir, is it really possible with this tool, please tell us how ?, now days in react official site recommend this. – Nikhil Patil Apr 29 '19 at 11:56
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.

Shannon Hochkins
  • 11,763
  • 15
  • 62
  • 95
1

Share data between Sass and JavaScript using JSON.

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

Community
  • 1
  • 1
Chase Oliphant
  • 379
  • 2
  • 5
1

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');