Resizable dimensions for the dark mode switch

My latest project involves creating a toggle button for switching between light and dark themes using CSS, HTML, and JavaScript:

id("theme-btn").addEventListener("change", function() {
  if (this.checked) {
    qs(".box").setAttribute('style', 'background-color:#CCCCCC;')
    qs(".ball").setAttribute('style', 'transform:translatex(100%);')
    document.body.classList.remove("light");
    document.body.classList.add("dark");
  } else {
    qs(".box").setAttribute('style', 'background-color:black; color:white;')
    qs(".ball").setAttribute('style', 'transform:translatex(0%);')
    document.body.classList.remove("dark");
    document.body.classList.add("light");
  }
});

// Helper functions
function id(id) {
  return document.getElementById(id);
}

function qs(selectors) {
  return document.querySelector(selectors);
}
body.dark {
  background-color: #616161;
  color: white;
}

body.light {
  background-color: white;
  color: black;
}

input[type="checkbox"] {
  display: none;
}

.btn {
  align-self: flex-end;
  margin: 5px 10px;
}

.box {
  display: flex;
  flex-direction: column;
  justify-content: center;
  /* BOX-WIDTH */
  width: 90px;
  /* BOX-WIDTH/2 */
  height: 45px;
  background-color: black;
  transition: all 1s ease;
  position: relative;
  /* BOX-WIDTH/4 */
  border-radius: 22.5px;
  cursor: pointer;
}

.box .ball {
  /* BOX-WIDTH/2 */
  width: 45px;
  /* BOX-WIDTH/2 */
  height: 45px;
  background-color: grey;
  transition: all 1s ease;
  position: absolute;
  border-radius: 50%;
  border: 3px solid black;
}

.box .scenary {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  transition: all 1s ease;
  padding: 5px 10px 0px 10px;
}

.box .scenary svg {
  /* BOX-WIDTH/3 */
  width: 30px;
}
<div class="btn">
  <input type="checkbox" name="theme-btn" id="theme-btn">
  <label for="theme-btn">
    <span class="box">
      <span class="ball"></span>
      <span class="scenary">
        <span class="moon">
          <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-moon">
            <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path>
          </svg>
        </span>
        <span class="sun">
          <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-sun">
            <circle cx="12" cy="12" r="5"></circle>
            <line x1="12" y1="1" x2="12" y2="3"></line>
            <line x1="12" y1="21" x2="12" y2="23"></line>
            <line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
            <line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
            <line x1="1" y1="12" x2="3" y2="12"></line>
            <line x1="21" y1="12" x2="23" y2="12"></line>
            <line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
            <line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
          </svg>
        </span>
      </span>
    </span>
  </label>
</div>

The functionality of the toggle button is great with a box width of 90 and height of 45. However, upon changing the dimensions to 60 and 30 respectively, issues arise when transitioning to dark mode:

  1. In dark mode, part of the sun image becomes visible, which is not ideal.
  2. There seems to be an inconsistency in the path length when sliding left and right, but I can't pinpoint the source of the problem.

To address these challenges, I am looking to make this code more scalable in terms of design adjustments. It would be beneficial to have variables defined in the CSS file for easy customization as per different dimensions. Any guidance or suggestions from experienced developers are highly appreciated.


Updated code snippet below reflects changes made to the width and height attributes of the box:

id("theme-btn").addEventListener("change", function() {
  if (this.checked) {
    qs(".box").setAttribute('style', 'background-color:#CCCCCC;')
    qs(".ball").setAttribute('style', 'transform:translatex(100%);')
    document.body.classList.remove("light");
    document.body.classList.add("dark");
  } else {
    qs(".box").setAttribute('style', 'background-color:black; color:white;')
    qs(".ball").setAttribute('style', 'transform:translatex(0%);')
    document.body.classList.remove("dark");
    document.body.classList.add("light");
  }
});

// Helper functions
function id(id) {
  return document.getElementById(id);
}

function qs(selectors) {
  return document.querySelector(selectors);
}
body.dark {
  background-color: #616161;
  color: white;
}

body.light {
  background-color: white;
  color: black;
}

input[type="checkbox"] {
  display: none;
}

.btn {
  align-self: flex-end;
  margin: 5px 10px;
}

.box {
  display: flex;
  flex-direction: column;
  justify-content: center;
  /* BOX-WIDTH */
  width: 60px;
  /* BOX-WIDTH/2 */
  height: 30px;
  background-color: black;
  transition: all 1s ease;
  position: relative;
  /* BOX-WIDTH/4 */
  border-radius: 15px;
  cursor: pointer;
}

.box .ball {
  /* BOX-WIDTH/2 */
  width: 30px;
  /* BOX-WIDTH/2 */
  height: 30px;
  background-color: grey;
  transition: all 1s ease;
  position: absolute;
  border-radius: 50%;
  border: 3px solid black;
}

.box .scenary {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  transition: all 1s ease;
  padding: 5px 10px 0px 10px;
}

.box .scenary svg {
  /* BOX-WIDTH/3 */
  width: 20px;
}
<div class="btn">
  <input type="checkbox" name="theme-btn" id="theme-btn">
  <label for="theme-btn">
    <span class="box">
      <span class="ball"></span>
      <span class="scenary">
        <span class="moon">
          <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-moon">
            <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path>
          </svg>
        </span>
        <span class="sun">
          <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-sun">
            <circle cx="12" cy="12" r="5"></circle>
            <line x1="12" y1="1" x2="12" y2="3"></line>
            <line x1="12" y1="21" x2="12" y2="23"></line>
            <line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
            <line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
            <line x1="1" y1="12" x2="3" y2="12"></line>
            <line x1="21" y1="12" x2="23" y2="12"></line>
            <line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
            <line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
          </svg>
        </span>
      </span>
    </span>
  </label>
</div>

Answer №1

    .box .ball {
      /* Adjusting the size of the ball to be half of the box width */
      width: 30px;
      height: 30px;
      background-color: grey;
      transition: all 1s ease;
      position: absolute;
      border-radius: 50%;
      border: 3px solid black;
      box-sizing: border-box;
    }

In the CSS above, I included a new property "box-sizing:border-box" to ensure that when transforming on click, it includes the width, border, margin, padding, etc. By default, its value is "content-box," which means these properties are not included in the transformation. Changing it to "border-box" ensures they are included. For more information, you can read about it here: https://www.w3schools.com/css/css3_box-sizing.asp

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

Utilize getElementsByClassName to dynamically alter the appearance of specific elements upon triggering an event

I'm attempting to utilize onmouseover="document.getElementsByClassName().style.background='color'" in order to switch the color of all divs with a specified classname to a different color when hovering over another element on the page. ...

Optimizing web layouts to fit on a single page is the most effective

Struggling to create a print layout for my web page that seamlessly transitions from the digital realm to the physical world. Utilizing HTML and CSS has presented challenges in aligning the "digital" design with a "real printable" page due to uncertainties ...

There was an error while parsing JSON on line 1, where it was expecting either a '{' or '[' to start the input

I've been struggling to extract data from my PHP array that is encoded using json_encode. I'm new to JQuery and have been attempting this for a few days without success. This code snippet is not producing the desired results: $.post('coord ...

Set the minimum height of a section in jQuery to be equal to the height of

My goal is to dynamically set the minimum height of each section to match the height of the window. Here is my current implementation... HTML <section id="hero"> </section> <section id="services"> </section> <section id="wo ...

What is the best way to extract a piece of text and incorporate it onto my website?

I'm currently attempting to extract the URL from a page on Steam. My goal is to obtain the picture URL of any user who visits it. Here is the JSON code provided by Steam when requesting a user's information: { "response": { "players": [ ...

What can you tell me about Page Event functionality in Datatables?

Curious question -- I'm currently seeking a practical example of how to implement a 'page' event in a project utilizing DataTables. The provided documentation can be found here -- http://datatables.net/docs/DataTables/1.9.4/#page. Despite t ...

What is the best way to deselect all "md-checkboxes" (not actual checkboxes) on an HTML page using a Greasemonkey script?

After spending a frustrating amount of time trying to disable the annoying "md-checkboxes" on a certain food store website, despite unchecking them multiple times and reporting the issue without any luck, I have come to seek assistance from knowledgeable e ...

React Alert Remove Alert: Each item in a list must be assigned a distinct "identifier" prop

How can I resolve the React warning about needing a unique "key" prop for each child in a list? I'm trying to eliminate the warning that says: "Each child in a list should have a unique key prop." The code snippet causing this warning is shown below ...

"Changing a Java script base addon file to a customized addon in Odoo 16: A step-by-step guide

Here is the JavaScript file located in the "documents" enterprise base addon: I want to include the field "document_type_id" in the export const inspectorFields = [] array through a custom addon. /** @odoo-module **/ import { device } from "web.confi ...

The HTML object is experiencing difficulties with the Ajax page loader feature not functioning as

I attempted to use the code below in order to show an Ajax loader image while the page loads into an HTML object. Unfortunately, it didn't work as expected and I'm having trouble figuring out why. Everything seems to be functioning correctly exce ...

Pass an array containing an HTML string to the $.post method in jQuery

I have a problem with displaying HTML content fetched from a PHP script using the jQuery $.post method: $.post('{$site_url}tests/tests/content', params, function (data) { $('#some-div1').html(data[1]); $('#some-div2').htm ...

The submit button is unable to initiate the ajax function

I encountered an issue with my code while attempting to separate my form function into a different PHP file and utilize an Ajax function to call the form based on the IDs. However, after separating the form function, the submit button no longer triggers th ...

Every single checked value in the checkbox variable

Encountered a small hiccup. Let me explain. In my form, there are 8 checkboxes. The goal is to loop through and capture the value of each checked checkbox using a variable. However, I'm always getting the same value from the first checkbox. Here&apo ...

What is the best way to call another "put" action method within the same controller file?

My project revolves around the interaction of two models - User and Request. A User can create a food delivery Request, attaching tokens as rewards. Another User can then help deliver the request and claim the tokens. Within the same controller.js file, I ...

Improving user input in AngularJS

My goal is to create a filter that converts time into seconds, such as: 01:30:10 becomes 5410, and vice versa. This way, the model only holds seconds while providing users with a more user-friendly representation. I've successfully implemented a work ...

Efficient methods for transferring information between a main and pop-up page within angularjs

On my webpage, I have a button that opens a popup page. I need to figure out a way to transfer json data from the main page to the popup page. These two pages are running separate angular applications. Once the data is transferred, it will be updated base ...

Vue.js - computed property not rendering in repeated list

It seems like the issue lies in the timing rather than being related to asynchronous operations. I'm currently iterating through an object and displaying a list of items. One of the values requires calculation using a method. While the direct values ...

Ways to efficiently implement configuration settings in a functional approach

I've delved into the world of functional programming and I'm working on developing a package that needs to be configurable. My goal is to set up this configuration only once to maintain purity in my functions without relying on global state. Curr ...

Is the Date Epoch a reliable form of unique identification?

Currently, I'm developing a Node API and encountered a situation where I need to create a unique 15-digit random number for a model without using autoincrement. The challenge is to ensure that the generated number is not trivial. I am hesitant about ...

Issue with loading background image in HTML/CSS is being caused by a Cross-Origin Read Blocking problem

As part of my project, I need to load an image from my image hosting site by using my github repository. The CSS code I am using for this task is as follows: #main-section{ background-image : url("https://github.com/<mypath>/myphoto.jpg"); } Be ...