How to effectively implement light and dark themes using SCSS colors?

Currently, I am utilizing Vue.js and SCSS along with PrimeVue and Element plus, where I am importing their variables. My objective is to dynamically change the theme color.

In my dark-variables.scss file, I have defined various color variables for different elements in the theme:

$--color-primary: #c9d1d9 !default;
$--color-white: #11141a !default;
$--color-black: #000000 !default;
$--color-primary-light-1: mix($--color-white, $--color-primary, 10%) !default; /* 53a8ff */
...
$--color-info: #909399 !default;

The main focus is on changing the $--color-primary variable based on the selected theme. For instance, setting it to white for a light theme and black for a dark theme.

To achieve this, I attempted using the following code snippet:

$themes: (
  darkTheme: (
    "text-color": rgb(245, 0, 0),
    "bg-color": #424242,
  ),
  lightTheme: (
    "text-color": black,
    "bg-color": #f5f5f5,
  ),
);

@mixin theme() {
  @each $theme, $map in $themes {
    $theme-map: $map !global;
    .#{$theme} & {
    }
  }
  $theme-map: null !global;
}

@function theme-get($key) {
  @return map-get($theme-map, $key);
}

// - Error
$--color-primary: theme-get("text-color");

Unfortunately, this code triggered an error which states:

Syntax Error: SassError: Undefined variable.
   ╷
56 │   @return map-get($theme-map, $key);
   │                   ^^^^^^^^^^
   ╵
  src\assets\styles\element-variables.scss 56:19  theme-get()
  src\assets\styles\element-variables.scss 59:19  @import
  src\assets\styles\kendoUI\kendoUI.scss 1:9      @import
  E:\Sproj\Web\src\assets\styles\styles.scss 7:9    

How can I resolve this issue and make it work as intended?

Answer №1

I believe there are a couple of adjustments that need to be made:

  1. The incorrect syntax involving dynamic class with & needs to be removed

  2. We should also ensure that the mixin is included to initialize $theme-map

      darkTheme: (
        "color": rgb(245, 0, 0),
        "background-color": #424242,
      ),
      lightTheme: (
        "color": black,
        "background-color": #f5f5f5,
      ),
    );
    
    @mixin theme() {
      $theme-map: null !global;
      @each $theme, $map in $themes {
        $theme-map: $map !global;
        .#{$theme} {
        }
      }
    }
    
    @include theme();
    
    @function theme-get($key) {
      @return map-get($theme-map, $key);
    }
    
    // - Error
    $--color-primary: theme-get("text-color");
    
    .theme {
        color: $--color-primary;
    }
    
    

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

An effective method for modifying the active class on an li element in jQuery and ensuring that the user is directed to the desired page upon clicking the li element

I am facing an issue with my script tag. When I click on the links test.php or test2.php, the active class changes from index.php to the respective file but I am not redirected to the clicked page. I have tried solutions from various sources but none of th ...

Talking about passed properties in Vue.js components

I recently embarked on creating a prototype for a board game using Vue.js. I have some knowledge of JavaScript and was progressing smoothly until I encountered an issue with accessing a property passed with 'props' in a component. Below is the c ...

Issue with Bootstrap 5 navbar dropdown: It opens easily but struggles to close

I am currently using Bootstrap 5 to design a website and have incorporated a dropdown feature into the navigation bar. On desktop, when hovering over the dropdown, it should open, while on mobile, clicking the dropdown should toggle its visibility (open/cl ...

Excessive image display | HTML and CSS synergize

I am having some trouble with my image gallery. Each image is displayed as a vertical column and has zooming effects when hovered over. Clicking on an image should show it in full screen with a caption. The problem arises when dealing with images that are ...

Getting started with Vue.js Components

Being a newbie in the world of Vue.js, my question may seem quite basic. Bear with me, please. I've set up the components App.vue and Character.vue. My goal is to dynamically create characters and add them to an array in App.vue, then use Character.v ...

developing a fluid grid system with flexible ordering

I'm currently working on a section for my app that consists of one row with 3 columns, each column containing 3 divs. JSFIDDLE: demo Here is how it should appear in desktop view: https://i.sstatic.net/ugAXd.png And here is the expected appearance ...

Is it feasible to activate a function when certain Vue data elements are altered?

Looking to monitor a set of data elements for changes and then save them in localStorage. Is there an easy way to achieve this? ...

When hovering over one item, it causes a hover effect on an item in a SEPARATE container

My goal is to create a unique interaction between links and images, where hovering over a link will transform the corresponding image below it, and vice versa. I have been searching for solutions but have only found methods that work when all items are wit ...

Display the scrollbar on a flexbox container instead of the entire browser window

I'm curious about how to implement a scroll-bar on a div using flexbox CSS. To better illustrate the issue, I've provided an example below: * { box-sizing: border-box; } .flex-display { display: flex; align-items: stretch; height: 100 ...

A guide on how to selectively blur and make the background transparent in jgrowl notifications without affecting the content

After some experimentation, I found that making the jGrowl notification background both transparent and blurry was not possible. When applying blur to the background, the content also became blurry, which is not the desired effect. If you want a transparen ...

Styling elements with CSS can sometimes lead to unexpected behavior in Safari on iOS devices, especially

Ever since the release of iOS 14, I've noticed that content within a div element with an 'overflow-y: scroll' property no longer functions properly on Safari. Does anyone happen to have a solution for this? (Or maybe my code just needs some ...

generating the <tr> element within a loop

I've been working on creating a calendar, but I'm facing an issue with the way the days are laid out horizontally. Here's how it currently looks: https://i.sstatic.net/PWcCi.png As you can see, only the <td> tags have been created. I ...

Enhance performance in Vue.js with a translation file upgrade

If my website offers language options that change all content, where is the best place to store this information for optimal performance? Would it be more efficient to have a translation file on the client side, especially for websites with large amounts ...

HTML5 header video with a subtle color palette

Is there a way to insert a muted video in the header that spans the full width but only has a height of 300px? The issue I am encountering is that when I decrease the height of the video, the width automatically decreases as well. However, what I want is ...

Leveraging Vue multiselect for modifying Algolia database index

In my current setup, I have a functionality on a page that allows me to switch between Algolia indices using the following code: <template> <button @click="selectedIndex = a">List A</button> <button @click ...

Tips for effectively invoking a method in a Vue component

As a Vue2 beginner, I am currently working with the Vue CLI and following the structure generated from it. My goal is to submit form data, but I keep encountering a warning and error: [Vue warn]: Property or method "onSubmit" is not defined on the insta ...

Troubleshooting: Issue with Angular routerlink not functioning in the sidebar section of SB Admin 2 Bootstrap 4 template

I am currently in the process of integrating the SB Admin2 template with my Angular 7 project. Unfortunately, I have encountered an issue where the links in the sidebar are unresponsive and not clickable at all. However, when I place a router link within t ...

What is the best way to create a text input that is both secure and non-editable?

While I am aware of the <input type="text" readonly /> possibility, it is not entirely secure. For example, if there is an input field that must remain uneditable by users, making it "readonly" can still be bypassed by inspecting the code and remov ...

Tips for customizing the appearance of material-ui SelectField

Currently, I am utilizing material-ui alongside react with the version "material-ui": "^0.19.2". I am facing an issue while attempting to embed a SelectField inside a table. Although the functionality is working smoothly, there are two unexpected behaviors ...

Attempting to choose everything with the exception of a singular element using the not() function in Jquery

Within the mosaic (div #mosaique) are various div elements. My goal is to make it so that when I click on a specific div, like #langages or #libraries, the other divs become opaque while the selected div undergoes a size change (which works correctly in t ...