Changing CSS module variables through JavaScript programming

I'm currently utilizing an older version of react-boilerplate that includes CSS Modules, allowing for the creation of variables and the ability to import them into other CSS files.

Below is my colors.css file:

:root {
  /* Status colors */
  --error: #842A2B;
  --success: #657C59;
  --pending: #666;
  --warning: #7E6939;
}

To import this file, all I need to do is include the following at the top of my .css file:

@import 'components/App/colors.css';

I am interested in implementing two themes on my website and am seeking a way to dynamically update these variables using JavaScript. What would be the most effective approach for achieving this?

Edit: I am hoping there's a solution that allows me to update the colors.css file without needing to apply conditional imports throughout all components that may use either of the two possible CSS files. If such a method exists, please let me know so I can change the accepted answer. Thank you to everyone who provided responses!

Answer №1

To easily switch between default and alternate theme colors, you can first define the default color variables on the element (such as body), then create another class for the alternate theme colors. Finally, use JavaScript to toggle between these classes. Here is a demonstration of how this can be achieved.

$("button").on("click", function() {
  $("body").toggleClass("foo");
});
body {
  --red: red;
  --blue: blue;
  --yellow: yellow;
  background: #ccc;
  text-align: center;
  font-size: 5em;
}

.foo {
  --red: #ce1126;
  --blue: #68bfe5;
  --yellow: #ffd100;
}

.red {
  color: var(--red);
}

.blue {
  color: var(--blue);
}

.yellow {
  color: var(--yellow);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="red">RED</span> <span class="blue">BLUE</span> <span class="yellow">YELLOW</span>
<br>
<button>click me</button>

Answer №2

If I were to have two different sets of styles, I could switch between them based on certain conditions:

primaryColours.scss

:root {
  /* Primary colors */
  --main-color: #FF5733;
  --secondary-color: #33FF57;
  --tertiary-color: #3357FF;
  --accent-color: #FF33EE;
}

alternateColours.scss

:root {
  /* Alternate colors */
  --main-color: #3366AA;
  --secondary-color: #AA3366;
  --tertiary-color: #66AA33;
  --accent-color: #AA6633;
}

Then, within the React code, I can import these styles and dynamically apply them according to the need:

import primaryStyles from 'primaryColours.scss';
import alternateStyles from 'alternateColours.scss';

...

{this.props.isPrimaryStyle ? primaryStyles.myClass : alternateStyles.myClass}

Answer №3

Are you interested in this content?

      // Retrieving the inputs
      const inputs = [].slice.call(document.querySelectorAll('.controls input'));

      // Listening for changes
      inputs.forEach(input => input.addEventListener('change', handleUpdate));
      inputs.forEach(input => input.addEventListener('mousemove', handleUpdate));

      function handleUpdate(e) {
        // Adding 'px' at the end of spacing and blur variables
        const suffix = (this.id === 'base' ? '' : 'px');
        document.documentElement.style.setProperty(`--${this.id}`, this.value + suffix);
      }
:root {
  --base: #ffc600;
  --spacing: 10px;
  --blur: 10px;
}

body {
  text-align: center;
}

img {
  padding: var(--spacing);
  background: var(--base);
  -webkit-filter: blur(var(--blur));
  /* 👴 */
  filter: blur(var(--blur));
}

.hl {
  color: var(--base);
}

/*
        Miscellaneous styles not related to CSS variables
      */

body {
  background: #193549;
  color: white;
  font-family: 'helvetica neue', sans-serif;
  font-weight: 100;
  font-size: 50px;
}

.controls {
  margin-bottom: 50px;
}

a {
  color: var(--base);
  text-decoration: none;
}

input {
  width:100px;
}
<h2>Update CSS Variables with <span class='hl'>JS</span></h2>
<div class="controls">
  <label>Spacing:</label>
  <input type="range" id="spacing" min="10" max="200" value="10">

  <label>Blur:</label>
  <input type="range" id="blur" min="0" max="25" value="10">

  <label>Base Color</label>
  <input type="color" id="base" value="#ffc600">
</div>

<img src="http://unsplash.it/800/500?image=899">

<p class="love">😘</p>

<p class="love">Works on Chrome 49+ and Firefox 31+</p>

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

CSS - Ignoring Padding Causes Unexpected White Space to Appear

I am encountering a simple error, and the following address will direct you to where the issue can be seen. Why is certain parts of the header appearing white instead of the light shade of green it is set to be? It should be positioned right at the top un ...

What is preventing images from displaying in my slider within baguetteBox?

Currently, I am in the process of incorporating a slider into my website using the baguetteBox library. After consulting the documentation, I successfully implemented an example that is functioning smoothly without any issues. In order to display a series ...

A plethora of color choices in a Multi-select Box

Hi there! I am facing an issue with dynamically adding multiple select boxes. Currently, I have 4 color-coded options under the selection boxes, which work fine when there is only one box. However, when I add more than one select box, the color coding doe ...

Trouble encountered when attempting to override styles in Material UI's TableRow

I am attempting to customize Material UI's default styles in order to create a margin between each TableRow. Despite my efforts, it appears that the override is not being reflected in the user interface. ...

What are the steps to reveal the second element once the first one has vanished?

Is there a way to delay the appearance of the second square until after the first square has disappeared? For example, I want the first square to appear after 3 seconds and then disappear, followed by the second square becoming visible after 11 seconds. ...

What is the best way to vertically align two divs on the left and right?

Having trouble aligning my dropdown list vertically with my textarea on the left. It seems like they are clashing together for some reason. UPDATE: Thank you for the assistance, I was able to make the necessary adjustments. JSP: .ExeDropdown{ float: ...

The number of contents determines the dynamic CSS border style

Could you please assist me in identifying what this design element is called? I have tried searching on Google, but had no luck finding exactly what I am looking for. Here is an example of the look I am aiming for: https://i.sstatic.net/AXUvq.jpg Can so ...

What is the best way to position the menu along the right side of the container?

Apologies if this question seems trivial, but I have been struggling to find a solution for positioning my navigation bar on the right side of the container (prior to the order button). Despite hours of searching, I still haven't come across a viable ...

Steps for revealing all the information from a database when clicking on the 'Read More' button

I recently set up a database called Magazine, featuring a table named social_media. This table consists of 5 columns: ID, Headline, Author, Content Short, Content. The Content Short column contains condensed versions of the articles which are displayed on ...

Adjust the height of a <div> element to fit the remaining space in the viewport or window automatically

I am working with the following HTML code: <html> <BODY> <DIV ID="holder"> <DIV ID="head_area">HEAD CONTENT GOES HERE....</DIV> <DIV ID="main_area">BODY CONTENT GOES HERE</DIV> ...

Guidelines for pinpointing local directories

Recently, I obtained a source code for a website navigation that includes a unique set of icons known as "Typicon." The HTML in the source code contains the following: <link rel="stylesheet" type="text/css" href="css/component.css" /> Within the C ...

The flickering problem with HTML5 DOM

I created a HTML5 game using canvas and DOM elements, but I'm facing an issue with flickering DOM elements while playing. The problem seems to be more prevalent in mobile browsers, particularly Chrome. My game includes a full screen canvas with vario ...

What is the best way to position two divs side by side while maintaining their individual padding?

When I remove the padding as shown, the website functions correctly with two div columns next to each other. However, upon adding padding, the #right div shifts downwards. How can I ensure it works as intended with padding included? HTML: Two divs direct ...

Result of mixing CSS colors

Is there a way to retrieve the result of blending two colors using the color-mix function? In cases where the color-mix feature is not supported, is it possible to set a fixed value instead? ...

Incorporate a platform-specific button in a user interface with React Native

I need to display a button that is only shown on iOS, not on android. I have tried using the following style, but it doesn't seem to be working. ...Platform.select({ android: { display:'none', }, The code for my button is: <Bu ...

Unable to make boxes responsive to size changes in CSS when layered over video background

I am struggling to position my boxes on top of a video background in HTML/CSS. Despite my efforts, the boxes only appear at the bottom and do not move with any CSS adjustments I make. Is there something I am missing or doing wrong in my approach? I want to ...

Merge ReactCssTransitionGroup with React-route's Link to create smooth page transitions

React.js I'm facing an issue with the React.js code provided below. My goal is to set up the animation before transitioning to a new page using "React-router.Link" and ReactCSSTransitionGroup. Version: react: '15.2.1' react-addons-css-trans ...

Comparison of getComputedStyle() and cssText functionality between Internet Explorer and Firefox

Take a look at this example to see the issue in action. I'm attempting to access the cssText property of a <div> using window.getComputedStyle(element) (which provides a CSSStyleDeclaration object). While this works smoothly in Chrome, it' ...

Maintain the fixed position of the Google Map <div> while allowing background <div>s to scroll

I'm having trouble keeping a Google Map div fixed on the screen while allowing my background, consisting of multiple scrolling divs with content inside, to scroll as normal. My attempt to wrap the map div in another fixed div resulted in the map disa ...

Strange behaviors when using setinterval with classes

Currently working on enhancing a slider functionality, and I have observed that everything is functioning smoothly - function Slider(element) { this.i = 0; this.element = element; var self = this; this.timer = window.setInterval(functi ...