Using SASS variables in JavaScript: A guide

My JavaScript file contains a list of color variables as an Object.

export const colors = [
{
    colorVariable: "$ui-background"
},
{
    colorVariable: "$ui-01"
},
{
    colorVariable: "$ui-02"
},
...
]

The Object above is derived from a scss file which holds 50 colors. I named the objects in line with the scss variables so I can easily use them in my React component.

$carbon--theme: (
    ui-background: #ffffff,
    ui-01: #f3f3f3,
    ui-02: #ffffff,
    ...
)

I have imported these colors to my jsx file from a color.js file.

import { colors } from './theme';

Now, I am trying to set the background of a div using one of those color variables. However, the usual approach is not working for me.

component.jsx

Code:

Object.keys(colors).map(key => {
        return (
        <div style={{ background: colors[key].colorVariable }} className={'theme-color')} />
        )
})

I have tried different methods but none seem to be effective. Any assistance on this matter would be highly appreciated. (It would be preferable if I could also apply the variable in a css file within the theme-color class. If not possible, that's okay too).

I am currently utilizing react 16. Your help and guidance would be greatly valued.

Answer №1

Initially, it's important to note that SASS variables are not available during runtime but only at compilation time. The resulting CSS file does not contain any SASS variables as it replaces them with their raw values.

To work around this limitation, you can create CSS variables based on your SCSS counterparts and then use these CSS variables in your code.

:root { 
  --ui-background: #{map-get($carbon--theme, "ui-background")};
  --ui-01: #{map-get($carbon--theme, "ui-01")};
  --ui-02: #{map-get($carbon--theme, "ui-02")};
}

Simply create an additional SASS/SCSS file with the provided snippet above and adjust the values in the colors variable accordingly.

This method works seamlessly during runtime.

As a bonus tip, if you need to iterate over every color in the theme map, you can utilize SASS's @each flow-control rule like shown below:

:root {
  @each $name, $color in $carbon--theme {
    --#{$name}: #{$color};
  }
}

In addition, the colors variable is structured as an array, eliminating the need to extract keys for iteration.

One potential issue to watch out for is: className={'theme-color')} - there appears to be an extra closing parenthesis here. For string values, simply pass the value directly in quotes without using JSX placeholders.

colors.map(
  (item) => <div key={item.colorVariable} style={{ background: item.colorVariable }} className="theme-color"/>
);

If the colors array consists solely of color values, you can simplify it by replacing it with an array of strings like: ['--ui01', '--ui02', ...]

With this approach, the mapping becomes even more straightforward:

colors.map(
  (color) => <div key={color} style={{ background: color }} className="theme-color"/>
);

Lastly, if you prefer not to use CSS variables, another option is to utilize a library such as scss-to-json which extracts SCSS variables and outputs them as JSON. This will require an additional build step and importing/merging the JSON into your codebase.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Accessing the AppContext in Next.js within the _document file is the

My challenge with using next js is the occurrence of Content-Security-Policy issues due to the inline styles it utilizes. If 'unsafe-inline' is not added to the style-src, you will encounter the error message 'Refused to apply inline style ...

Dynamic starting point iteration in javascript

I'm currently working on a logic that involves looping and logging custom starting point indexes based on specific conditions. For instance, if the current index is not 0, the count will increment. Here is a sample array data: const data = [ { ...

The Bootstrap navbar collapse fails to expand in the appropriate location

Whenever I try to expand the navigation on mobile mode by clicking the button, it doesn't push the content downwards. Instead, it just opens a small menu next to the button. Did I make a mistake in my code? <div class = "container"> ...

Using kebab-case in CSS properties within objects is not applicable. Perhaps you intended to use MozAppearance instead?

Error encountered at InputBase (webpack-internal:///../../node_modules/@mui/material/InputBase/InputBase.js:299:83) It is not recommended to use kebab-case for css properties in objects. Perhaps you intended to use MozAppearance instead? Incorrect usage ...

Using Selenium Webdrivers to Browse Pages with Minimal Resource Loading

I'm attempting to restrict Javascript from altering the source code of the site while testing with Selenium. Disabling Javascript completely in the Webdriver is not an option as I require it for testing purposes. Below is my approach for the Firefox W ...

Troubleshooting encoding problems with Google Cloud's Speech-to-Text API using Node.js

I'm currently working on a project that involves capturing audio from a user's microphone and sending it to a server for translation using Google's Speech-to-Text API. I am utilizing navigator.mediaDevices.getUserMedia() to access the audio, ...

Having trouble installing npx create-react-app with yarn?

When setting up my React app, I initially used npx create-react-app <app-name> with npm, even though I have yarn installed on my computer. The React app was previously installed using yarn. npm version: 8.3.0 node version: 17.3.0 yarn version: 1.22.1 ...

Using GSAP to create a staggered animation with a negative delay

Seeking a Solution: I am curious if there is a method to incorporate a negative delay into the staggerFrom / staggerTo functions within greensock? Issue at Hand: The current animation I have in place is extending longer than desired. It would be benefic ...

Having trouble getting the timer function to execute upon page load in JavaScript

My goal is to have my basic timer function activate when the page loads. However, I'm encountering issues with it not working as intended. I suspect there may be an error in the if else loop, possibly here: setTimeout(function(tag, sec), 1000);. How c ...

Is there a way to upload numerous images from my local disk onto a canvas using Fabric.js?

I'm currently working on an innovative Image Collage application using the power of HTML5 canvas and Fabric.js. One of the key features I want to implement is the ability for users to simply drag and drop files into the designated 'File Drag and ...

Showing nested JSON data in ng-repeat

Currently, I'm struggling to understand how to access nested JSON and show it on a page using Angular. For instance, consider the JSON structure below where I want to display connectivity products under portfolio using ng-repeat... { "addons": [ ...

Tips for integrating new channels and categories using a Discord bot

Hey there! I'm trying to add channels and categories, but I can't seem to get the function ".createChannel" working. The console keeps telling me that the function doesn't exist. I've been referencing the documentation at https://discor ...

Exploring the World of JSON Nested Arrays with Unknown Titles and Organizing Them for Storage

Apologies if this question has already been addressed elsewhere, but I couldn't find it. I have a JSON object with dynamic keys: { "main": [ { "Example1": [ { "Example1_Var02": "5", ...

The AngularJS Navbar is Bootstrapped

I'm currently working on a project where I need to make a bootstrap navbar show and hide html elements based on data retrieved from an angular controller. Below is the jade code snippet: div.navbar.navbar-fixed-top div.navbar-inner div.c ...

Having trouble choosing elements with angular.element within ng-repeat loop

In my HTML code, I am using an ngRepeat element: <ol id="animationFrame"> <li ng-repeat="animationImage in animationImages" ng-repeat-listener> <img ng-src="{{animationImage.src}}" id="{{animationImage.id}}"> </li> </ol& ...

Cease the continuous scrolling of the display element now

I'm having trouble with my progressbar animation when scrolling. It seems to run multiple times instead of just once. I apologize if there's an error in my code. Could someone please assist me? This is the code I am using: <div class="demo- ...

Navigate to the correct page when the Button is clicked in a ReactJS/Django project

Embarking on my web development journey, I opted for django/Reactjs to build a social network platform. I created several API methods like account/view_user/ to retrieve a list of users and account/view_user/ for specific user attributes. In React, I cra ...

Issue with React-Native FlatList's scrolling functionality

Struggling with implementing a scrolling FlatList in React Native. Despite trying various solutions found on Stack Overflow, such as adjusting flex properties and wrapping elements in views, the list still refuses to scroll. Snippet of code (issue is with ...

How can one eliminate the white space surrounding the data that Vue is binding?

Working with Vue, I've noticed a gap on the screen following the data binding. Instead of using Vanilla JavaScript's trim() function, is there a way to remove leading and trailing whitespace? Let me provide you with the code for the data binding ...

How can I effectively refresh the provider_token / access token for Discord in NextJS with Supabase Auth?

Currently, I have encountered an issue with my NextJs project using Supabase Auth for authentication. I am currently utilizing the Discord provider and everything works fine initially. However, after a few minutes, the session object gets updated and the p ...