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

Incorporating Java project dependencies into an npm project

I'm facing a challenge in my development process, where I need to incorporate dependencies from a Maven Java project into my package.json file within my Vue/Typescript project. These dependencies are crucial for accessing specific data types that my p ...

Unlocking the secrets of accessing data props from a different component in Vue.js

I am working with a component called nabber/header that has some props. I need to insert these props into the component and then pass them onto another component. How can I retrieve this data in order to use it for CRUD operations on a database? Is it feas ...

CodePen displaying CSS errorsI'm having trouble getting my CSS

I'm facing an issue with my CSS code and I need your help to figure out what's wrong. I believe it's a simple problem that someone can quickly identify just by looking at the code. Any assistance would be greatly appreciated! Here is the co ...

What is the best way to set the width of an element to 100% while accounting for padding

My dilemma involves an HTML input field. The input currently has padding: 5px 10px;, but I need it to occupy 100% of its parent div's width (which is fluid). If I try using width: 100%;, the input ends up being wider than intended due to the padding ...

Boost your website's loading time by utilizing the async and defer attributes

Looking to enhance the speed of my webpage, particularly focusing on improving initial page speed. Research suggests that using the async and defer attributes for JavaScript can be beneficial. All JavaScript scripts are currently placed just above the cl ...

Is there a way to bypass cells within an html table?

Creating an online board game and looking to have the cells go around the board. Wondering if anyone knows a way to skip the cells in the middle? Attempted using   but it doesn't seem to be effective. Here is a snippet of the code: #board { ...

Using the "align" attribute is considered outdated and not recommended in HTML5 documents

I have encountered an error when using the align attribute. How can I fix this issue with the correct HTML5 compatible syntax? <table style="margin: 0 auto;"> <tbody> <tr> <td><input typ ...

Difficulty encountered while using CSS to customize a vue template

I'm currently working on a login page and experiencing difficulty styling Vue templates using CSS. Here is the code that works without Vue: HTML <body class="text-center"> <form class="form-signin"> <h1 class="h3 mb-3 fon ...

Placing an Image in Next.js

I've been trying to position my image all the way to the right of the page using CSS properties like position: absolute and right: 0. I've also attempted setting the parent element's position to relative and the image's position to abso ...

Customize the rowspan dynamically for every row within a v-for iteration

After reviewing the data provided in this codepen, my goal is to render a table like the one displayed in the same codepen. Each driver can be associated with one or more teams, with the position and points being displayed only once, while the team name an ...

Learn how to set up webpack or Next.js to generate a CSS file from custom Material styles and automatically inject it into the header

One of the things I've done is define some custom material styles, like this: import {createStyles, makeStyles, Theme} from '@material-ui/core/styles'; export const useStyles = makeStyles((theme: Theme) => createStyles({ fab ...

Jumbotron causes navigation bar to malfunction on mobile site

I'm experiencing an issue with Bootstrap Jumbotrons on my website - they extend beyond the container, causing the navbar on the mobile version to not fill the screen. This problem only occurs on pages with a jumbotron present. Attempting to use a Car ...

Accessing form data using Vue on submit

I'm working on a project that involves creating a form with a single input field and saving the data to a database. The technology I am using is Vue.js. Here is the template I have designed: <form class="form-horizontal" @submit.prevent="submitBi ...

How to customize the color of md-radio-button in Angular?

I've been trying to customize the color of my radio buttons, but I haven't had much luck. Here are a couple of examples I attempted: Example 1 HTML <md-radio-button class"radio-button"> yes <md-radio-button> CSS //checked .radio- ...

Troubleshooting why Vue.js isn't updating the DOM with two-way binding

I'm currently utilizing Vue.js for implementing two-way binding. One issue I am facing is with an edit button that should convert a text field into an input field upon clicking. However, the DOM does not update immediately as expected. For instance: ...

Implemented a solution to ensure the menubar remains fixed when zooming in and out

When zooming in and out on a webpage, the menu does not stay fixed to the header image shown in the figure below: The CSS code for this issue is as follows: #navmenu{ z-index:99999; margin-top:40px; position:absolute; width:100%; m ...

Applying CSS transformations to scale up a div within its parent body

Having an issue with formatting an anchor link using transform scale attributes on hover. The link is inside a div that's aligned to the right, and I want it to enlarge when hovered over. However, this increase in size also affects the parent div, ca ...

Utilize JavaScript to apply the CSS -moz-transition

Creating a web application and using CSS3 to transform a div, but encountering a challenge with Firefox. Able to make Chrome, Opera, and IE work properly, except for Firefox. Here's how I'm setting up the working browsers: obj.style.WebkitTrans ...

Encountering an issue with eslint-loader in a new VueJS project: TypeError - eslint.CLIEngine is not recognized as

Embarking on a fresh VueJS venture with WebStorm. A brand new VueJS project has been established, NPM upgraded, Vuetify added, and upon server initiation, an error pops up: ERROR Failed to compile with 1 errors ...

Adding padding with and without child elements

As I work on styling a basic menu, I'm struggling to find a solution for adding padding to list items so they all have a consistent look. The challenge arises from the fact that I have an unordered list where list items may or may not contain an anch ...