<button aria-pressed="false">
  <span class="sr-only">Toggle Dark Mode</span>
  <span class="sun-and-moon">
    <span class="rays">
      <span class="ray" style="--index: 0; --entry: 0; --exit: 1;"></span>
      <span class="ray" style="--index: 1; --entry: 1; --exit: 2;"></span>
      <span class="ray" style="--index: 2; --entry: 0; --exit: 3;"></span>
      <span class="ray" style="--index: 3; --entry: 1; --exit: 4;"></span>
      <span class="ray" style="--index: 4; --entry: 0; --exit: 3;"></span>
      <span class="ray" style="--index: 5; --entry: 1; --exit: 2;"></span>
      <span class="ray" style="--index: 6; --entry: 0; --exit: 1;"></span>
      <span class="ray" style="--index: 7; --entry: 1; --exit: 0;"></span>
    </span>
    <span class="star" style="--index: 0;"></span>
    <span class="star" style="--index: 1;"></span>
    <span class="body"></span>
  </span>
</button>
*,
*:after,
*:before {
	box-sizing: border-box;
}

:root {
	--step: 0.25s;
	--dark-mode: 0;
	--surface: hsl(
		210
		calc((17 - var(--dark-mode) * 6) * 1%)
		calc((98 - var(--dark-mode) * 83) * 1%)
	);
	--color: hsl(
		210
		calc((9 + var(--dark-mode) * 5) * 1%)
		calc((31 + var(--dark-mode) * 52) *1%)
	);
	--hover: hsl(
		210
		calc((16 - var(--dark-mode) * 6) * 1%)
		calc((93 - var(--dark-mode) * 60) * 1%)
	);
}

:root:has([aria-pressed="true"]) {
	--dark-mode: 1;
}

body {
	display: grid;
	place-items: center;
	min-height: 100vh;
	font-family:  'Google Sans', sans-serif, system-ui;
	background: var(--surface);
	transition: background var(--step);
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border-width: 0;
}

button {
  --size: calc(2 * 48px);
	--distance: calc(1 - var(--dark-mode, 0));
	--position: calc((40 + (var(--dark-mode, 0) * 70)) * 1%);
	--ray-position: calc(var(--dark-mode, 0) * 150%) 0;
	--step: 0.25s;
	--bg: var(--surface);
	aspect-ratio: 1;
	padding: 0;
	display: grid;
	place-items: center;
  background: var(--bg);
  width: var(--size);
  aspect-ratio: 1;
  padding: 1%;
  border-radius: calc(var(--size) * 0.2);
  border: 1px solid hsl(0 0% 50%);
  overflow: hidden;
  transition: transform var(--step) var(--ease-elastic-5), box-shadow var(--step) var(--ease-elastic-5), background var(--step);
  transform: translateY(var(--elevate, 0)) scale(var(--scale, 1));
  box-shadow:
    calc(var(--size) * var(--shadow-x, 0.05))
    calc(var(--size) * var(--shadow-y, 0.05))
    0
    calc(var(--size) * var(--spread, 0)); 
}

button:focus-visible {
	outline-color: hsl(0 0% 50%);
  transition: transform var(--step) var(--ease-elastic-5),
  	box-shadow var(--step) var(--ease-elastic-5),
  	background var(--step);
}

button:hover {
  background: var(--hover);
}

button:active {
  --shadow: 0;
  --elevate: 5%;
  --scale: 0.9;
  --shadow-x: 0;
  --shadow-y: 0;
}

[aria-pressed="true"],
[aria-pressed="true"]:is(:hover, :active) {
  --shadow: 0;
  --elevate: 5%;
  --scale: 0.9;
  --shadow-x: 0;
  --shadow-y: 0;
}

button span {
	display: inline-block;
}

.sun-and-moon {
	height: 100%;
	width: 100%;
	display: grid;
	place-items: center;
	position: relative;
}

.body {
	height: 40%;
	aspect-ratio: 1;
	background: var(--color);
	border-radius: 50%;
	mask: radial-gradient(circle at right center, transparent 25%, #000 25.5%) var(--position, 40% 50%) / 200% 200% no-repeat;
	transition: all var(--step);
	transform: rotate(-45deg) scale(calc(1.5 - (var(--distance, 1) * 0.5)));
}

.star {
	width: 10%;
	aspect-ratio: 1;
	background: var(--color);
	border-radius: 50%;
	position: absolute;
	top: 20%;
	left: 55%;
	transition: transform var(--step) var(--ease-elastic-5);
	transform: translate(-50%, -50%) translate(calc(var(--index) * 250%), calc(var(--index) * 220%)) scale(calc((1 + (var(--index) * 1)) * (1 - var(--distance, 1))));
}


.rays {
	position: absolute;
	inset: 0;
	transition: all var(--step);
	transform: rotate(-45deg);
	mask: linear-gradient(90deg, #000 50%, transparent 75%) var(--ray-position, 0 0) / 200% 200% no-repeat;
}

.ray {
	width: 10%;
	aspect-ratio: 1;
	background: var(--color);
	border-radius: 50%;
	position: absolute;
	top: 50%;
	left: 50%;
	transition: transform var(--step) calc((var(--step) * 0.5) + ((var(--entry) * var(--step)) * 0.25)) var(--ease-elastic-5);
	transform: translate(-50%, -50%)
		rotate(calc((360 / 8) * var(--index) * 1deg))
		translateX(calc(var(--distance, 1) * 350%));
}

[aria-pressed="true"] .ray {
	transition: transform 0s var(--step);
}

[aria-pressed="true"] .star {
	transition: transform var(--step) calc(var(--step) + (var(--index) * var(--step))) var(--ease-elastic-5);
}
const BUTTON = document.querySelector('[aria-pressed]')

BUTTON.addEventListener('click', () => BUTTON.setAttribute('aria-pressed', BUTTON.matches('[aria-pressed="true"]') ? false : true))

BUTTON.setAttribute('aria-pressed', window.matchMedia('prefers-color-scheme: dark') ? true : false)
View Compiled
Run Pen

External CSS

  1. https://codepen.io/jh3y/pen/zYRjgjW.css
  2. https://unpkg.com/open-props/normalize.min.css
  3. https://unpkg.com/open-props/open-props.min.css

External JavaScript

  1. https://codepen.io/jh3y/pen/zYRjgjW.js