Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the industry standard way to pass SASS variable to javascript?

I have looked around and I've seen one solution where in your html, you'd have a tag dedicated to pass sass variables to javascript. I'm talking about the second answer from

Is there a way to import variables from javascript to sass or vice versa?

I also tried using html

<div class="selector"></div>

with css

.selector { content: "stuff"; }

but looking at the dom in the developer tools, it doesn't get added even though we can see it on the rendered page, so I cannot pick it up with javascript

$('.selector').text()

How does everyone do it?

like image 378
BringMeAnother Avatar asked Aug 27 '13 04:08

BringMeAnother


People also ask

Can I use SASS variables in JS?

Sass variables and JavaScript. Sass is a pre-processing language, meaning it's turned into CSS before it ever is a part of a website. For that reason, accessing them from JavaScript in the same way as CSS custom properties — which are accessible in the DOM as computed styles — is not possible.

How do you globally access Sass SCSS variables in react?

Each import of SCSS file in JS file is treated as an isolated SASS env, therefore, there is no such thing "global variables" while using SCSS in React. This behavior requires us to import the variables. scss file into each SCSS file that uses one of the variables. @import "variables.

Can I use SASS variables in HTML?

Sass variables that are initialized outside the scope of a selector, is part of the global scope and can be used anywhere in the document. Sass variables that are initialized inside the scope of a selector can only be used within that selector. The local variable $col-text is only available to be used inside html .


2 Answers

Not sure about "industry standard", but it's a very handy technique and not too difficult. The content of pseudo elements is not available via text() though, you have to use getComputedStyle.

Example using body:after:

Sass (using the compass breakpoint extension):

body:after {
  display: none;

  @include breakpoint($bp-wide) {
    content: "wide";
  }

  @include breakpoint($bp-medium) {
    content: "medium";
  }

  @include breakpoint($bp-small) {
    content: "small";
  }
}

JavaScript:

if (window.getComputedStyle) {
  var mq = window.getComputedStyle(document.body,':after').getPropertyValue('content');
}

if (mq.indexOf('small') !== -1) {
  // do something
}

Credit: I first saw this technique here: https://coderwall.com/p/_ldtkg

like image 144
steveax Avatar answered Sep 17 '22 13:09

steveax


I believe that injecting SASS variables via CSS content property is a very hackish way to do things.

Instead, you can store the variables in a separate location and have them read both by SASS and JS.

First, store a list of breakpoints in a breakpoints.json file:

["0", "300px", "500px", "700px", "900px", "1100px"]

Then use Ruby to read this JSON file and make its contents available as a SASS list via a SASS function. Put this into your Compass config.rb:

sass_options = { :custom => {'breakpoint_file' => 'breakpoints.json'} }

# This creates a SASS function debug() that returns $debug into SASS
module Sass::Script::Functions
  def breakpoints

    # Reading an array of breakpoints into a file
    unless breakpoints_array_raw = JSON.load( IO.read( options[:custom]['breakpoint_file'] ))
      raise Sass::SyntaxError.new("Error: Breakpoints file '#{options[:custom]['breakpoint_file']}' does not exist.")
    end

    # Converting strings in the array to SASS String literals
    breakpoints_array_sassy = breakpoints_array_raw.map { |s| Sass::Script::String.new(s) }

    # Returning the list into SASS
    Sass::Script::List.new( breakpoints_array_sassy, :space )
  end
end

In your SASS code, read breakpoints like this:

$breakpoints: breakpoints()

In JS, use jQuery's .get method to request the JSON file like this:

var
  breakpoints = [],
  requestBreakpoints = $.get('breakpoints.json');

requestBreakpoints.done(function (response, textStatus, jqXHR){
    breakpoints = response; // You might want to remove "px" here
});

When i was assembling this setup, I found an existing solution here, but i decided to reimplement it using my favorite SASS tools: Singularity and Breakpoint Slicer.

For your convenience, i've built a proof-of-concept GitHub project with everything set up nicely, featuring some ugly JS code. :)

And here's a live demo!

like image 21
Andrey Mikhaylov - lolmaus Avatar answered Sep 20 '22 13:09

Andrey Mikhaylov - lolmaus