<input type="checkbox" id="toggle" class="toggle sr-only" />
<label for="toggle">
  <span>Switch light/dark mode</span>
</label>
<nav class="nav">
  <a class="item" href="#">
    <svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
      <path d="M11 17a1 1 0 001.447.894l4-2A1 1 0 0017 15V9.236a1 1 0 00-1.447-.894l-4 2a1 1 0 00-.553.894V17zM15.211 6.276a1 1 0 000-1.788l-4.764-2.382a1 1 0 00-.894 0L4.789 4.488a1 1 0 000 1.788l4.764 2.382a1 1 0 00.894 0l4.764-2.382zM4.447 8.342A1 1 0 003 9.236V15a1 1 0 00.553.894l4 2A1 1 0 009 17v-5.764a1 1 0 00-.553-.894l-4-2z"></path>
    </svg>
  </a>

  <a class="item" href="#">
    <svg class="icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"></path>
    </svg>
  </a>
  <a class="item active" href="#">
    <svg class="icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
    </svg>
  </a>
  <a class="item" href="#">
    <svg class="icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 8v8m-4-5v5m-4-2v2m-2 4h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"></path>
    </svg>
  </a>
  <a class="item" href="#">
    <svg class="icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7v8a2 2 0 002 2h6M8 7V5a2 2 0 012-2h4.586a1 1 0 01.707.293l4.414 4.414a1 1 0 01.293.707V15a2 2 0 01-2 2h-2M8 7H6a2 2 0 00-2 2v10a2 2 0 002 2h8a2 2 0 002-2v-2"></path>
    </svg>
  </a>

  <a class="item" href="#">
    <svg class="icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 3h2l.4 2M7 13h10l4-8H5.4M7 13L5.4 5M7 13l-2.293 2.293c-.63.63-.184 1.707.707 1.707H17m0 0a2 2 0 100 4 2 2 0 000-4zm-8 2a2 2 0 11-4 0 2 2 0 014 0z"></path>
    </svg>
  </a>
  <a class="item" href="#">
    <svg class="icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4"></path>
    </svg>
  </a>
  <a class="item" href="#">
    <svg class="icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 8h10M7 12h4m1 8l-4-4H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-3l-4 4z"></path>
    </svg>
  </a>

  <a class="item" href="#">
    <svg class="icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5.121 17.804A13.937 13.937 0 0112 16c2.5 0 4.847.655 6.879 1.804M15 10a3 3 0 11-6 0 3 3 0 016 0zm6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path>
    </svg>
  </a>
</nav>
@import url("https://fonts.googleapis.com/css2?family=Exo:wght@600&display=swap");
@import url("//fonts.googleapis.com/css?family=Lato:400,400italic,700|Sansita+One");
@import url("https://fonts.googleapis.com/css?family=Merriweather:400,400i,700");

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  width: 100vw;
  min-height: 100vh;

  display: flex;
  justify-content: center;
  align-items: center;
  font-family: "Exo", Arial, sans-serif;
  background-color: rgba(209, 213, 219, 1);
  gap: 10vmin;
}
.sr-only {
  position: absolute;
  height: 1px;
  width: 1px;
  clip: rect(1px 1px 1px 1px);
  clip: rect(1px, 1px, 1px, 1px);
  clip-path: polygon(0px 0px, 0px 0px, 0px 0px);
  overflow: hidden !important;
}

label {
  padding: 20px;
  margin: 60px;
  transition: background-color 200ms ease-in-out;
  width: 200px;
  height: 50px;
  border-radius: 50px;
  text-align: center;
  background-color: slateGray;
  box-shadow: -4px 4px 15px inset rgba(0, 0, 0, 0.4);
  position: absolute;
  top: 0;
  right: 0;
  font-family: "Sansita One", serif;
  cursor: pointer;
  display: flex;
  justify-content: flex-start;
}
label::before,
label::after {
  font-size: 2rem;
  position: absolute;
  transform: translate3d(0, -50%, 0);
  top: 50%;
}
label::before {
  content: "\263C";
  right: 100%;
  margin-right: 10px;
  color: orange;
  font-size: 2rem;
  line-height: 1;
  bottom: -7px;
}

label::after {
  content: "\263E";
  left: 100%;
  margin-left: 10px;
  color: lightSlateGray;
}

label span {
  position: absolute;
  bottom: calc(100% + 10px);
  left: 50%;
  transform: translate(-50%, 0);
  white-space: nowrap;
}
label span::after {
  position: absolute;
  top: calc(100% + 15px);
  left: 0;
  width: 40px;
  height: 40px;
  content: "";
  border-radius: 50%;
  background-color: lightBlue;
  transition: transform 200ms, background-color 200ms;
  box-shadow: -3px 3px 8px rgba(0, 0, 0, 0.4);
  transform: translate3d(0, 0, 0);
}

input[type="checkbox"]:checked ~ label {
  background-color: lightSlateGray;
}
input[type="checkbox"]:checked ~ label::before {
  color: lightSlateGray;
}

input[type="checkbox"]:checked ~ label::after {
  color: turquoise;
}

input[type="checkbox"]:checked ~ label span::after {
  transform: translate3d(145px, 0, 0);
}

.nav {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 0.75rem;

  width: 4rem;
  border-radius: 0.25rem;
  padding: 0.75rem;

  --dark-color: rgba(156, 163, 175, 1);
  --dark-bgcolor: rgba(17, 24, 39, 1);
  --dark-active-bgcolor: rgba(55, 65, 81, 1);

  --light-color: rgba(55, 65, 81, 1);
  --light-bgcolor: rgba(243, 244, 246, 1);
  --light-active-bgcolor: rgba(209, 213, 219, 1);

  color: var(--light, var(--light-color)) var(--dark, var(--dark-color));
  background-color: var(--light, var(--light-bgcolor))
    var(--dark, var(--dark-bgcolor));
}

a {
  color: inherit;
  text-decoration: inherit;
  display: flex;
  justify-content: center;
  align-items: center;

  width: 3rem;
  aspect-ratio: 1 / 1;
  border-radius: 0.25rem;
}

a.active,
a:hover {
  background-color: var(--light, var(--light-active-bgcolor))
    var(--dark, var(--dark-active-bgcolor));
}

svg {
  width: 2rem;
  aspect-ratio: 1 / 1;
}

/* 设置切换开关 */
:root {
  --ON: initial;
  --OFF: ;
}

.nav {
  --light: var(--ON);
  --dark: var(--OFF);
}

@media (prefers-color-scheme: dark) {
  .nav {
    --light: var(--OFF);
    --dark: var(--ON);
  }
}

input[type="checkbox"]:checked ~ .nav {
  --light: var(--OFF);
  --dark: var(--ON);
}

input[type="checkbox"]:not(:checked) ~ .nav {
  --light: var(--ON);
  --dark: var(--OFF);
}
document.addEventListener("DOMContentLoaded", function () {
  const checkbox = document.querySelector(".toggle");

  checkbox.checked = localStorage.getItem("darkMode") === "true";

  checkbox.addEventListener("change", function (event) {
    localStorage.setItem("darkMode", event.currentTarget.checked);
  });
});

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.