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

Displaying incorrect symbols with icon fonts

I have successfully integrated icon fonts into my simple web page. Check it out on jsFiddle here My design is similar to this example, but instead of bars, I see a snake icon displayed. How can I fix this issue with the fonts? Here is the code snippet: ...

What could be causing my PHP mail script to report success but fail to deliver the email?

Previously, I have successfully used the same script and AJAX query to manage emails without any issues. However, on this particular site, it seems that the process is not functioning properly. Although the POST request indicates success, no email is being ...

Signing up with DJ Rest Auth

One of the challenges I'm currently facing involves using dj-rest-auth, an authentication tool specifically designed for Django. Upon user registration, a verification email is automatically sent to confirm their email address. However, I am strugglin ...

Setting up a connection to MongoDB on a local network using express and mongoose

As I set up a server with express and mongoose, my goal is to make it accessible on other devices within my local network. To achieve this, I configured the bind_ip variable to 0.0.0.0 in the Mongodb configuration file. const connection = mongoose .co ...

Tips for identifying the most effective element locator in the DOM with Playwright

Currently, I am in the process of incorporating Playwright tests for a website that supports multiple locales. The majority of the page content is dynamically generated from CMS content (Contentful). I am hesitant about using hardcoded text locators like ...

Can you include both a routerLink and a click event on the same anchor tag?

I am facing an issue with my li elements. When a user clicks on them, it should open a more detailed view in another component. However, I noticed that it takes TWO clicks to show the data I want to display. The first click opens the component with an em ...

Passing form values from JavaScript to a JSP page - a comprehensive guide

I am working on a sample HTML page that includes inline JavaScript for calculating geocodes and retrieving latitude and longitude values. My question is, how can I submit all the form values along with the latitude and longitude returned from the showlocat ...

Create and adapt dynamic tiles to fit within the available width

I am looking to create a dynamic tile (div) that adjusts based on the number of users available, similar to how it works in Microsoft Teams meetings. For example, if there is only one user, the div should occupy the full screen. When there are two users ...

Is it possible to use a JavaScript string as a selector in jQuery?

So, my issue is with the following JavaScript code snippet: for ( i=0; i < parseInt(ids); i++){ var vst = '#'+String(img_arr[i]); var dst = '#'+String(div_arr[i]); } I'm wondering how I can proceed in jQuery to handle ...

React hooks problem with toggle arrow functionality

Could anyone assist me with the following issue: I have a React Hooks component where I am trying to toggle an arrow when clicking on a span element. It currently works only once, and if clicked again, it does not work anymore. I am confused as to why th ...

Ways to protect my login details when making an ajax request?

The scenario I am dealing with is as follows: I have developed a website using Javascript where users are required to input a username and password. Subsequently, the site makes an ajax call to the Webserver. On the other end, I have a PHP-powered Webser ...

Optimizing CSS With jQuery During Browser Resize

I am currently facing an issue with recalculating the height of the li element during window resizing or scrolling. Strangely, on page load, the height is no longer being re-calculated and set to the ul's child height. Here is the code I have written ...

Switching ng-Idle countdown time from seconds to minutes is possible by adjusting the configuration settings

I have implemented ng-idle in my application, where the warning popup appears after 10 seconds with the message: "Your session will be close in 10 seconds" However, I need to change this to minutes. The session should be closed in 5 minutes instead. How ...

Add the Load More feature to your Next JS project for enhanced user experience

Utilizing the SWR package along with Next JS, I have successfully retrieved data and displayed it in a table. Now, my goal is to implement a "load more" type of pagination for the listing page. Below is the code snippet: Locations component: import useSW ...

Basic node.js server that responds with HTML and CSS

I have successfully created a basic http server to send an HTML file as a response. However, I'm struggling with how to also send a CSS file so that the client can view the HTML page styled with CSS in their browser. Here is my current code: var htt ...

Why isn't the mounted() lifecycle hook being triggered in my Vue 3 component?

I am struggling with a simple Vue 3 component that closely resembles some examples in the documentation. Here is the code: // Typewriter.vue <template> <div id="wrapper"> <p>{{ text }}</p> </div> </templa ...

Continuous horizontal columns

Is there a way to create horizontal columns with inline-blocks, like the method described here, without having vertical gaps between items on the second line due to different heights? I want to eliminate the vertical gaps between the tiles using only CSS. ...

Identify and troubleshoot scripts that are included in the response returned by Chrome

I am facing an issue where I have a webpage that loads HTML sections through an AJAX call. The response includes both HTML and JavaScript files. Currently, I am trying to figure out how to set a debug point on the JavaScript file. In Internet Explorer, I ...

Instructions for appending an id to the URL of events in fullcalendar using Rails

Looking for a way to attach an ID to the URL of a fullcalendar event in a Rails application? I am using a json.jbuilder file: json.array!(@estudiante.clases) do |clase| json.extract! clase, :id json.id clase.id json.title clase.name json.start cl ...

Tips for automatically incorporating animation upon page initialization

I'm looking to add an automatic image effect when the page is loaded. I currently have this code in my js file: $(window).ready(function(){ $(pin).click(function(){ $("#pin01").show().animate({left: '650px'}); }) }); Here is the HTML wit ...