Mastering Theme Transformation with SASS

My website is constructed using SASS, and I am facing an issue where the variables I set for light and dark themes are not changing as expected. Whenever I switch between themes, all variables revert to their original values, making it difficult for me to customize them accordingly.

Within my style.scss, I have the following variables:

$mainColor: #eaeaea;
$secondaryColor: #fff;

$mainText: black;
$secondaryText: #2a3a47;

$borderColor: #c1c1c1;

$themeDotBorder: #24292e;

$previewBg: rgba(251, 249, 243, 0.8);
$previewShadow: #f9ead6;
$buttonColor: #0a0a0a;

I am struggling to find a way to update these variables dynamically when switching between themes. Although creating separate CSS files for each theme is an option, it introduces redundant code. Can anyone provide guidance on how to efficiently manage variable changes while transitioning themes?

Answer №1

When it comes to customizing themes based on different requirements and older browser compatibility, such as IE11, there are various approaches you can take.

One effective way to simplify theme customization is by using CSS custom properties, also known as CSS variables. The concept revolves around defining variables for various style properties and updating them dynamically when the theme changes.

In a basic example like mine, the process involves the following steps:

  1. Define the default theme variables at the root level of your stylesheet.
  2. Create a class that represents the specific theme, for instance, .dark-theme.
  3. Add a class to the body element when switching to the dark theme using JavaScript or a similar method based on your server-side setup. In my demo, I accomplish this using JavaScript.

The key idea behind this approach is that by applying the .dark-theme class, you can update the variable values to reflect the dark theme colors, thereby achieving a significant portion of the desired styling changes.

It's worth noting that the implementation strategy for saving and persisting the selected theme may vary depending on the type of website architecture you're working with, whether it's a single-page application, WordPress site, .NET platform, etc. Storing the theme preference in local storage rather than user-specific databases can be a viable option if user authentication isn't a core requirement.

const themeSwitcherButton = document.querySelector('.js-theme-switcher')

themeSwitcherButton.addEventListener('click', function() {
    const body = document.querySelector('body')
  
  if (body.classList.contains('dark-theme')) {
    body.classList.remove('dark-theme')
  } else {
    body.classList.add('dark-theme')
  }
})
:root {
  --primary-color: deepskyblue;
}

body.dark-theme {
  --primary-color: deeppink;
}


.block {
  margin-bottom: 3rem;
  padding: 2rem;
  background-color: var(--primary-color);
}
<body>
  <p class="block">
    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Minima quos odio atque excepturi, aut voluptate. Similique autem, eos rem cum tenetur perspiciatis voluptatibus reprehenderit cumque, inventore, nam laudantium fugiat molestias eveniet sit commodi deleniti. Ipsa eum animi, excepturi tempore placeat.
  </p>
  
  <button class="js-theme-switcher">Theme switcher</button>
</body>

Answer №2

opt for using css variables over sass variables

--primaryColor: #eaeaea;

and

color: var(--primaryColor);

to apply the variable

update:

for dynamically changing css variables

let bodyStyles = document.body.style;
bodyStyles.setProperty('--primaryColor', 'white');

if the variables were declared on the body element

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

Centering an unordered list and ensuring the image is responsive across different screen sizes are both top priorities for this design

Currently, I am working on an HTML project through freecode academy and encountering some obstacles. My goal is to center align the unordered list and make sure that the image responds well to various screen sizes. Please feel free to leave comments with ...

Tips for containing content within a div element

Does anyone know how to achieve this using CSS? https://i.sstatic.net/1eY38.png I'm having trouble keeping the written content inside the wrapper div, like this: https://i.sstatic.net/5vDot.png I attempted to use material-ui Grid but didn't h ...

strange JSON structure

I am puzzled by the json output and its relation with jquery. Below is the json data, but the syntax seems quite peculiar: {"ResC": { "@attributes": { "ver": "1.1", "prod": "HAFAS 5.31.VBB.4.8.9", "lang": "DE" }, "STBRes": { "@attributes": {"plan_ ...

Breaking the layout using recursive components in VueJS

I am currently facing an issue where I need to dynamically load components. However, when some of these components are loaded, they appear with faulty or missing CSS styles due to a problematic first div element after the template. Removing this DIV manual ...

Extract HTML href links that correspond to a specific string from a given list of strings using Beautiful Soup

I am currently working on extracting specific URLs from a webpage that contains a list of various links. My goal is to only retrieve the URLs that match certain strings in a predetermined list. These strings are a subset of the text found within the links ...

When rendering, HTML characters are not translated

My JavaScript code generates the following HTML structure: <div contenteditable="false" tabindex="0" class="ProseMirror"> <p> didn't project a significant increase</p> </div> When rendered in the browser, it shows the cha ...

Animating Elements with CSS and HTML

Struggling with my website project, specifically creating a login page. The issue arises when resizing the browser, causing elements to look misaligned and chaotic. Before: view image here After: view image here /* Bordered form */ form { margin-l ...

What is the best way to change the class of an input using jQuery when it is not empty?

Utilizing Bootstrap 4. I am working on a feature where I have four text inputs. If any of these inputs contain values, I want to add a specific class to a button. Upon clicking the button, my goal is to clear all input values and remove the aforementione ...

The Python Django site is failing to detect and implement CSS updates

Currently, I am in the process of developing a Django website where I have successfully loaded my CSS and HTML files as static resources. In this project, I am utilizing two CSS files: one for Bootstrap and another for my custom styling. However, I encoun ...

A step-by-step guide on changing an image

Is it possible to change an image when the user clicks on a link to expand its content? <ul class="accor"> <li> Item 1 <img src="../plus.png"> <p> Lorem ipsum dolor sit amet</p> </li> </ul> $(' ...

When HTML/JS code is utilized, the submit button or image should function to open the same page as

In addition to the left and right mouse buttons, you also have a middle mouse button. If you click on an image or hyperlink with this middle mouse button while browsing any website, it will open a new window in the background. Now, I want to achieve a sim ...

CSS3 family tree tutorial: Incorporating a wife into the design

I came across a fascinating tutorial about creating a family tree using CSS3 only. However, I'm struggling to understand how to depict a marriage. To explain further: What the code currently accomplishes is this: what i aim to include is this: Alth ...

What is the best way to restrict a link to only a specific div element and not a Bootstrap

My HTML conundrum involves a div styled with the class .win_box: This particular div is nested within a Bootstrap column, and the link associated with it extends throughout the entirety of said column. However, I want to restrict user access to this link ...

Transferring time for streaming MP3 files from server to HTML5 audio

Currently, my node.js server is set up to convert and stream mp3 files in real-time. I have integrated an HTML5 audio tag to play this stream, but I am encountering a problem - the audio element is unable to determine the duration of the mp3 until it has c ...

Application that exclusively launches the web browser

Recently, I created a basic website and now I am looking to make it accessible on mobile devices. My plan is to develop an app that opens a browser without displaying the tab bar or URL bar. I want to achieve this for both Android and iOS platforms. Are t ...

What causes <input> elements to vertically center when using the same technique for centering <span> elements? (The line-height of <input> does not match its parent's height)

Important: The height of <div> is set to 50px, and the line-height of <span> is also 50px When 'line-height' is not applied to the <span>, all elements align at the top of the parent. However, when 'line-height: 50px&apo ...

JavaScript: How can I remove it when I click anywhere on the webpage with onClick?

A challenge I'm facing involves creating a form with an input field that changes its border color when clicked. My goal is for the border to return to its original color when clicking anywhere else on the page. -HTML <form action=""> ...

Switch the view to a grid layout upon clicking

Using bootstrap 5, I've successfully created a list view: <div class="col"> Click to switch to grid/list </div> Below is the content list: <div class="row mt-3 list"> list view ... ..... ....... </div ...

Show specific content based on which button is selected in HTML

I am working on a project where I have three buttons in HTML - orders, products, and supplier. The goal is to display different content based on which button the user clicks: orders, products, or supplier information. function showData(parameter){ i ...

JQuery failing to display image within set timeframe

In my website, I have implemented a feature that displays data from a database using auto-scrolling. As the user scrolls down the page, an AJAX function is triggered to fetch the next set of records from the database and append them to the existing content ...