dark mode without plugin

1) Toggle

Begin by creating a checkbox toggle using HTML and CSS, and place it, for example, in the header section. In your HTML, assign an unique id to the checkbox, in my case „switch-mode“. Next, decide on the default mode for your website, as this choice will affect the CSS for the :before and :after selectors. In my setup, the default mode is dark mode, which is why I use a moon icon with the :before selector and a sun icon with the :after selector. Here you can see the two states as well as the HTML & CSS code.

				
					<label class="mode-toggle">
  <input type="checkbox" id="mode-switch">
  <span class="slider round"></span>
</label>

				
			
				
					/* Your selector here */
selector .mode-toggle {
  position: relative;
  display: inline-block;
  width: 56px;
  height: 30px;
}

selector .mode-toggle input {
  opacity: 0;
  width: 0;
  height: 0;
}

selector .slider {
  position: absolute;
  cursor: pointer;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  /* Dark background for moon (now default) */
  background-color: #222;
  /* White border */
  border: 1px solid #FFF; 
  -webkit-transition: .4s;
  transition: .4s;
}

selector .slider::after {
  position: absolute;
  content: "";
  height: 18px;
  width: 18px;
  left: 4px;
  /* Center the sun icon vertically */
  top: 5px;
  background-color: white;
  /* Make the sun icon round */
  border-radius: 50%;
  -webkit-transition: .2s;
  transition: .2s;
  /* Hide the sun by default */
  opacity: 0;
}

selector .slider::before {
  position: absolute;
  content: "\263E"; /* Unicode moon symbol */
  font-size: 20px;
  font-weight: bold;
  left: 31px; /* Adjust the position for the moon */
  bottom: 5px;
  color: #FFF; /* White color for moon */
  opacity: 1; /* Show the moon by default */
  /* Smooth transitions */
  transition: opacity .2s ease, transform .2s ease;
}

selector input:checked + .slider {
/* Light background for sun when checked */
  background-color: grey;
}

selector input:checked + .slider::after {
  opacity: 1; /* Show the sun when checked */
}

selector input:checked + .slider::before {
  opacity: 0; /* Hide the moon when checked */
}

/* Rounded sliders */
selector .slider.round {
  border-radius: 500px;
}

selector .slider.round::after {
/* Ensure the sun icon remains round in 'round' sliders */
  border-radius: 50%;
}

selector .slider.round::before {
  border-radius: 0px;
}

				
			

2) JavaScript function

Next, a function is required that reacts to the click of the toggle. In addition, the user’s setting must be saved so that the mode is retained even after a page reload. I can recommend the WordPress plugin Code Snippets to implement the PHP / JavaScript Code.

The code consists of a PHP part that is used to insert the code into WordPress. JavaScript then controls the dark light mode.

The outer PHP function light_mode_toggle_script() is integrated into the HTML header of the WordPress page with the command add_action(‚wp_head‘, ‚light_mode_toggle_script‘). This ensures that the JavaScript is executed.

The dark light mode is controlled with JavaScript. The previously created checkbox with the Id “mode-switch” serves as a switch. When the page is loaded, the script checks whether the light or dark mode was last activated. The setting is saved in the localStorage and restored. Depending on the mode, a corresponding CSS class is set to <body> to automatically adapt the design.

				
					add_action('wp_head', 'light_mode_toggle_script');

function light_mode_toggle_script() {
  ?>
  <script>" // Remove quotation mark in this line
  ...
  </script>
  <?php
}

				
			
				
					add_action('wp_head', 'light_mode_toggle_script');

function light_mode_toggle_script() {
  ?>
  <script>" // Remove quotation mark in this line
  document.addEventListener('DOMContentLoaded', () => {
    const modeSwitch = document.querySelector('#mode-switch');
    
    // Ensure the toggle exists to avoid errors
    if (!modeSwitch) return;

    // Default to dark mode unless localStorage indicates light mode
    const isLightMode = localStorage.getItem('lightMode') === 'true';

    // Function to update the mode
    const setMode = (light) => {
      document.body.classList.toggle('lightMode', light);
      localStorage.setItem('lightMode', light);
      // Sync checkbox state
      modeSwitch.checked = light;
      // Update aria-checked
      modeSwitch.setAttribute('aria-checked', light);
    };

    // Set initial mode based on localStorage or default to dark
    setMode(isLightMode);

    // Toggle mode on switch click
    modeSwitch.addEventListener('change', () => {
      setMode(modeSwitch.checked);
    });
  });
  </script>
  <?php
}

				
			

3) CSS classes

The last step is to define CSS classes, once for the light mode and once for the dark mode. There are different approaches where to manage CSS code in WordPress. I save the code in the Elementor theme:
“Appereance” -> “Themes” -> “Customize” -> “Additional CSS”

Here is a simple example of <p> elements within a container/widget with the “.dm-text” class. By default, the color is set to var(–col-white). If the light mode is active (recognizable by the class .lightMode on <body>, see JavaScript), the text color is changed to var(–col-black) instead. I have also decided to save the color hex codes in variables.

				
					.dm-text p {
    color: var(--col-white);
  }

.lightMode .dm-text p {
    color: var(--col-black);
  }
				
			
				
					:root {
    /* COLORS BASE*/
    --col-white: #ffffff;
    --col-black: #000000;
    --col-orange: #FF9C0F;
    --col-blue: #0E00F5;
  }