When trying to implement a dark/light theme, CSS variables may not function properly on the body tag

Currently, I am in the process of developing two themes (light and dark) for my React website. I have defined color variables for each theme in the main CSS file as shown below:

#light{
--color-bg: #4e4f50;
--color-bg-variant: #746c70;
--color-primary: #e2ded0;
--color-primary-variant: #647c90;
--color-white: white;
--color-light: rgb(255 255 255 / 60%);
}

#dark{
--color-bg: #1A1A2E;
--color-bg-variant: #16213E;
--color-primary: #E94560;
--color-primary-variant: #0F3460;
--color-white: white;
--color-light: rgb(255 255 255 / 60%);
}

These variables are applied throughout the project except in the body tag style declaration:

body {
font-family: Poppins, sans-serif;
background: var(--color-bg);
color: var(--color-white);
line-height: 1.7;
background-image: none;
}

However, the background variable does not seem to be working within the body tag. This issue needs immediate attention. It's puzzling why the other variables are functioning correctly but not this one.

In order to switch between light and dark themes, I have implemented the following logic in App.jsx:

import { createContext } from "react"
import { useState } from "react"

export const ThemeContext = createContext(null)

const App = () => {
const [theme, setTheme] = useState("dark")

const toggleTheme = () => {

setTheme((curr) => (curr === "light" ? "dark" : "light"))
}
return (
<ThemeContext.Provider value={{theme, setTheme}}>
  <Router>
      <Routes>
        <Route path="/" element={
          <div id={theme}>
            <Header/>
            <Nav/>
            <About/>
            <Experience/>
            <Services/>
            <BlogPreview/>
            <Contact/>
            <Footer/>
          </div>}
        />
        <Route path="/Blog" element={
          <div id={theme}>
            <Blog/>
            <NavG/>
          </div>}  
        />
        <Route path="*" element={
          <div id={theme}>
            <Error/>
            <NavGG/>
          </div>
        }/>
        <Route path="/Blog/buymeanr6please" element={
          <div id={theme}>
            <Post1/>
          </div>
        }/>
      </Routes>
  </Router>
</ThemeContext.Provider>
)
}

export default App

If anyone can offer guidance on resolving this issue, I would greatly appreciate it.

Answer №1

This issue relates to cascading and inheritance in CSS. Your CSS variables are defined within the context of a <div id={theme}>, which is a child of the body element. Therefore, the body element cannot access them.

To resolve this, you can either move the properties from the body element to the <div id={theme}> like this:

#dark, #dark{
 font-family: Poppins, sans-serif;
 background: var(--color-bg);
 color: var(--color-white);
 line-height: 1.7; /* distance between sections */
 background-image: none;
}

Alternatively, you can set your variables on the html element so that every child element, including the body, can access them. If you choose this option, add the following code snippet to App.jsx and remove the id attribute from <div id={theme}>:

useEffect(() => {
   document.documentElement.setAttribute("id", theme);
}, [theme]);

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

Using jQuery's ajax to populate several div elements in a single call

Trying to wrap my head around jQuery's Ajax function. There exists a page composed of various divs, along with an XML document generated from a MySql resultset. Within the jQuery function displayed below, I successfully fill the titleDiv with data. M ...

There seems to be a malfunction in the PHP controller causing issues with the functionality

Currently, I am utilizing jQuery and PHP for my project. In the controller, I have integrated AJAX functionality. Upon the initial click action, the result is successfully retrieved (the current "show more button" is hidden and a new "show more button" is ...

Script for automated functions

I have implemented 4 functions to handle button clicks and div transitions. The goal is to hide certain divs and show one specific div when a button is clicked. Additionally, the background of the button should change upon hovering over it. Now, I am look ...

User must wait for 10 seconds before closing a JavaScript alert

Can a JavaScript alert be set to stay open for a certain amount of time, preventing the user from closing it immediately? I would like to trigger an alert that remains on screen for a set number of seconds before the user can dismiss it. ...

Adjust the appearance of a specific element

When it comes to styling my HTML tags, I prefer a definitive approach. However, there is one particular tag that I want to exempt from this style choice. Is there a way to achieve this? ...

Extension for Chrome - Personalized pop-up notification when page loads

I am looking to create a custom alert box that triggers on page load instead of the default one, which I find unattractive and possibly irritating for users. alert('hello'); My current approach involves the following code: manifesto.js "cont ...

What is the solution to resolving the issue of props.match being

this is the code from my Editstudent.js file: async componentDidMount() { const stud_id = this.props.match; console.log(stud_id); } and here is a snippet from my App.js file: <Routes> <Route exact path="/" element={<St ...

Error in TypeScript: The property "component" is not found on the React MUI MenuItem

I am currently working with the react mui MenuItem component and I am trying to turn a menu item into a link. Here is how I have attempted to achieve this: <MenuItem component={<Link href={`/backend/api/exam/${row.id}/result`} />} className={c ...

How can I dynamically change the orderBy parameter based on conditions in an Angular application?

I need to dynamically change the orderBy parameter in a table row based on the result of a method. Here is an example of my current tr setup - <tr class="pl" ng-repeat="thing in things | orderBy:'oldId':reverse" ng-class="{'row-error&apo ...

Extracting data from multiple web pages with R - An extensive collection of tables

Looking for assistance in extracting data from a website with multiple pages and importing it into R. Can anyone help me with this task? Website: ...

403 Forbidden error encountered while making a REST API call using jQuery AJAX

Attempting to create a basic jQuery ajax call to an API Here is the code I'm using: jQuery.ajax({ type: "GET", url: "http://example.com/api/v1/testapi", headers: { "Authorization": "Basic Ylc5aWXXXXXXlk1ucWx5ZnA=" }, success: fu ...

Implementing universal styles to injected HTML (v-html)

I am facing an issue while injecting HTML content from my database using Vue. The problem is that although I can successfully inject the HTML, the framework stylesheet (Vuetify) does not seem to be applied to the injected content. The rest of the page ha ...

Solving the Issue of Multiple Object Handling in JavaScript

Is there a way to remove the object from a JSON response and only keep the array of objects? I've tried using methods like Slice, Replace, and Filter but haven't been successful. {"error":"no data"}[{"name":"Ali"},{"name":"Momin"}] What I need ...

What is the best way to extract the variable inside a script tag as a JSON value?

Hey, I need help figuring out how to convert a JavaScript variable into a JSON value using Python with the help of libraries like BeautifulSoup and requests. I attempted to solve this issue by following a similar topic on Stack Overflow, but unfortunately ...

The combination of NextJS and Firebase Auth using the GoogleAuthProvider is powerful

I am encountering challenges while trying to integrate firebase authentication with Google Provider in NextJS. I have set up the necessary environment variables and successfully established a connection with firebase. However, I keep running into an error ...

How can I convert a PHP array into radio buttons in an HTML form?

I'm looking to develop a survey using HTML, PHP, and Javascript. I have my questions and answers stored in a csv file (which will eventually be transferred to a SQL server). My main concern is how to convert my answers into radio button types so that ...

The status of the 'slider' may be 'undefined'

I'm really struggling to figure out how to resolve this issue, even though I suspect it's a simple fix that's eluding me... Here is the part of my code in TypeScript that's causing the error: const slideLeft = () => { cons ...

Fade out the content using jQuery and simultaneously change the div

I stumbled upon this interesting code snippet here: http://jsfiddle.net/7hqyq/ Being a novice in the realm of jQuery, I am curious to learn how one can modify the background color of the selected square (including the first square on page load) and implem ...

Link embedded within a list item

How can I make the hyperlink element fill up the width and height of the li element inside? <ul> <li><a href="#" style="display: block; width: 100%; height: 100%;">this link to fill up the li element width and height</a><l ...

Utilizing identical data in two distinct React child components: one component enables manipulation of the data, while the other component restricts any changes to it

Within a react application, I am fetching data (an array of objects with two key-value pairs per object) in a parent component and passing this data down to two pureComponent children in props. Interestingly, when I perform any data manipulation, such as a ...