title: Scalable size of dark theme toggle button
body: <p>I have created a dark theme toggle button using CSS, HTML, and JavaScript:</p>
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>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);
  }</code></pre>
  <pre class="snippet-code-css lang-css prettyprint-override"><code>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;
  }</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;div class="btn"&gt;
    &lt;input type="checkbox" name="theme-btn" id="theme-btn"&gt;
    &lt;label for="theme-btn"&gt;
      &lt;span class="box"&gt;
        &lt;span class="ball"&gt;&lt;/span&gt;
        &lt;span class="scenary"&gt;
          &lt;span class="moon"&gt;
            &lt;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"&gt;
              &lt;path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"&gt;&lt;/path&gt;
            &lt;/svg&gt;
          &lt;/span&gt;
          &lt;span class="sun"&gt;
            &lt;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"&gt;
              &lt;circle cx="12" cy="12" r="5"&gt;&lt;/circle&gt;
              &lt;line x1="12" y1="1" x2="12" y2="3"&gt;&lt;/line&gt;
              &lt;line x1="12" y1="21" x2="12" y2="23"&gt;&lt;/line&gt;
              &lt;line x1="4.22" y1="4.22" x2="5.64" y2="5.64"&gt;&lt;/line&gt;
              &lt;line x1="18.36" y1="18.36" x2="19.78" y2="19.78"&gt;&lt;/line&gt;
              &lt;line x1="1" y1="12" x2="3" y2="12"&gt;&lt;/line&gt;
              &lt;line x1="21" y1="12" x2="23" y2="12"&gt;&lt;/line&gt;
              &lt;line x1="4.22" y1="19.78" x2="5.64" y2="18.36"&gt;&lt;/line&gt;
              &lt;line x1="18.36" y1="5.64" x2="19.78" y2="4.22"&gt;&lt;/line&gt;
            &lt;/svg&gt;
          &lt;/span&gt;
        &lt;/span&gt;
      &lt;/span&gt;
    &lt;/label&gt;
  &lt;/div&gt;</code></pre>
  </div>
  </div>
  </p>
  <p>As you might observe, it works quite well in this situation (i.e., <code>width</code> and <code>height</code> of <code>box</code> equal to <code>90</code> and <code>45</code>). However, when I changed the <code>width</code> and <code>height</code> of <code>box</code> to <code>60</code> and <code>30</code>, respectively in the CSS file, some problems popped up: (Please run the code snippet below)</p>
  <ol>
  <li>When switching to <strong>dark</strong> mode, some part of the sun image will be visible, which of course is not ideal and annoying.</li>
  <li>It seemed the slider path length of going <em>right</em> and <em>left</em> are different. But I couldn't figure out where did the problem come from...</li>
  </ol>
  <p>As mentioned in the title, I think it would be nice to make this code snippet of dark theme toggle button to be <strong>scalable</strong>. (<em>Preferably having variables defined in the CSS file -&gt; I am not sue if this is possible</em>) I.e., when one changes the <code>width</code> and <code>height</code> of the box, everything will behave properly and nicely.</p>
  <p>I am new to web development. Any advice and help would be of great appreciation.</p>
  <hr />
  <p>Code snippet with <code>width</code> and <code>width</code> of <code>box</code> changed to <code>60</code> and <code>30</code>:</p>
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>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);
  }</code></pre>
  <pre class="snippet-code-css lang-css prettyprint-override"><code>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;
  }</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;div class="btn"&gt;
    &lt;input type="checkbox" name="theme-btn" id="theme-btn"&gt;
    &lt;label for="theme-btn"&gt;
      &lt;span class="box"&gt;
        &lt;span class="ball"&gt;&lt;/span&gt;
        &lt;span class="scenary"&gt;
          &lt;span class="moon"&gt;
            &lt;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"&gt;
              &lt;path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"&gt;&lt;/path&gt;
            &lt;/svg&gt;
          &lt;/span&gt;
          &lt;span class="sun"&gt;
            &lt;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"&gt;
              &lt;circle cx="12" cy="12" r="5"&gt;&lt;/circle&gt;
              &lt;line x1="12" y1="1" x2="12" y2="3"&gt;&lt;/line&gt;
              &lt;line x1="12" y1="21" x2="12" y2="23"&gt;&lt;/line&gt;
              &lt;line x1="4.22" y1="4.22" x2="5.64" y2="5.64"&gt;&lt;/line&gt;
              &lt;line x1="18.36" y1="18.36" x2="19.78" y2="19.78"&gt;&lt;/line&gt;
              &lt;line x1="1" y1="12" x2="3" y2="12"&gt;&lt;/line&gt;
              &lt;line x1="21" y1="12" x2="23" y2="12"&gt;&lt;/line&gt;
              &lt;line x1="4.22" y1="19.78" x2="5.64" y2="18.36"&gt;&lt;/line&gt;
              &lt;line x1="18.36" y1="5.64" x2="19.78" y2="4.22"&gt;&lt;/line&gt;
            &lt;/svg&gt;
          &lt;/span&gt;
        &lt;/span&gt;
      &lt;/span&gt;
    &lt;/label&gt;
  &lt;/div&gt;</code></pre>
  </div>
  </div>
  </p>