CSS 변수를 통해 Astro 웹사이트의 다크 모드 활성화

다크 모드의 사용이 인기를 끌었습니다. 많은 대형 웹사이트와 애플리케이션은 종종 CSS 변수를 사용하여 수행되는 자체 버전을 개발하고 있습니다.

이 게시물에서는 먼저 CSS를 사용한 다음 JavaScript 토글을 사용하여 웹 사이트에 다크 모드 지원을 추가하는 방법을 살펴보겠습니다.

전제 조건



계속해서 Astro.new에서 Astro 스타터를 포크하는 것이 좋습니다.



선택한 템플릿을 선택한 다음 CodeSandbox에서 템플릿을 열면 필요한 종속성이 자동으로 처리됩니다.

다크 모드 컴포넌트 만들기



구성 요소 폴더 안에 ThemeChange.astro라는 새 구성 요소를 추가했습니다. 기본 기능에는 토글용 svg 이미지와 함께 클릭 가능한 요소가 포함되어 있습니다.

<div class="theme-switch-wrapper">
          <label class="theme-switch" for="checkbox">
            <input type="checkbox" id="checkbox" />
            <div class="slider">
              <svg
                xmlns="http://www.w3.org/2000/svg"
                width="16"
                height="16"
                viewBox="0 0 24 24"
                fill="#FCD53F"
                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>
              <svg
                xmlns="http://www.w3.org/2000/svg"
                width="16"
                height="16"
                viewBox="0 0 24 24"
                fill="#FCD53F"
                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>
            </div>
          </label>
        </div>


이 구성 요소를 Header 구성 요소로 즉시 가져옵니다.

---
import HeaderLink from './HeaderLink.astro';
import { SITE_TITLE } from '../config';
import Toggle from './ThemeChange.astro';
---

<header>
    <Toggle />
    <h2>
        {SITE_TITLE}
    </h2>
    <nav>
        <HeaderLink href="/">Home</HeaderLink>
        <HeaderLink href="/blog">Blog</HeaderLink>
        <HeaderLink href="/about">About</HeaderLink>
        <HeaderLink href="https://twitter.com/astrodotbuild" target="_blank">Twitter</HeaderLink>
        <HeaderLink href="https://github.com/withastro/astro" target="_blank">GitHub</HeaderLink>
    </nav>
</header>
<style>
    header {
        margin: 0em 0 2em;
    }
    h2 {
        margin: 0.5em 0;
    }
</style>


테마에 CSS 변수 사용



CSS 변수를 사용하면 런타임에 변경할 수 있는 재사용 가능한 값을 정의할 수 있습니다. 먼저 루트 요소에서 사용 가능한 모든 색상을 정의합니다. 그런 다음 이러한 색상을 사용하여 밝고 어두운 두 가지 상반되는 데이터 테마를 만듭니다.

:root {
  --color-bg: #f2f2f2;
  --color-text: #444444;
  --bold-text: #222;
  --nav-text: #000000;
  --code: #f2f2f2;
  --block-quote-border: #999;
  --block-quote-text: #222;
  --slider-bg: #dddddd;
  --slider-bg-before: #fff;
  --slider-input-bg: #8758ff;
}

[data-theme="light"] {
  --color-bg: #f2f2f2;
  --color-text: #444444;
  --bold-text: #222;
  --nav-text: #000000;
  --code: #f2f2f2;
  --block-quote-border: #999;
  --block-quote-text: #222;
  --slider-bg: #dddddd;
  --slider-bg-before: #fff;
  --slider-input-bg: #8758ff;
}

[data-theme="dark"] {
  --color-bg: #000;
  --color-text: #dddddd;
  --bold-text: #eeeeee;
  --nav-text: #dddddd;
  --code: #f2f2f2;
  --block-quote-border: #8e32dc;
  --block-quote-text: #dddddd;
}


💡 Note - When the data-theme="dark" is applied to the <body> element, the background-color of the component changes from white to black.



이 동일한 개념을 웹 앱의 모든 색상에 적용하면 테마 전환기가 생깁니다! 누락된 것은 선택하면 본문 요소에서 데이터 테마를 추가하거나 제거하는 토글 요소입니다.

마지막으로 아래와 같이 나머지 토글 요소 스타일을 적용합니다.

/* TOGGLE  */
.theme-switch-wrapper {
  display: flex;
  justify-content: flex-end;
  align-items: center;
}

.theme-switch {
  display: inline-block;
  height: 34px;
  position: relative;
  width: 60px;
}

.theme-switch input {
  display: none;
}

.slider {
  background-color: var(--slider-bg);
  bottom: 0;
  cursor: pointer;
  left: 0;
  position: absolute;
  right: 0;
  top: 0;
  transition: 0.4s;
  border-radius: 34px;
}

.slider:before {
  background-color: var(--slider-bg-before);
  bottom: 4px;
  content: "";
  height: 26px;
  left: 4px;
  position: absolute;
  transition: 0.4s;
  width: 26px;
  border-radius: 50%;
}

input:checked + .slider {
  background-color: var(--slider-input-bg);
}

input:checked + .slider:before {
  transform: translateX(26px);
}

.slider svg {
  color: #222;
  position: absolute;
  transition: opacity 0.2s ease 0s, transform 0.35s ease 0s;
  pointer-events: none;
}

.feather-moon {
  opacity: 0;
  left: 9px;
  bottom: 9px;
  transform: translateX(4px);
}

.feather-sun {
  opacity: 1;
  right: 10px;
  bottom: 9px;
  transform: translateX(0px);
}

input:checked + .slider .feather-moon {
  opacity: 1;
  transform: translateX(0);
}

input:checked + .slider .feather-sun {
  opacity: 0;
  transform: translateX(-4px);
}



💡 Note - If you get stuck on picking colors for your CSS variables then discover the newest hand-picked palettes from Color Hunt.



자바스크립트



JavaScript에서 로컬 저장소는 창 개체의 일부인 개체이므로 직접 액세스하여 내부에 저장된 항목을 찾으려고 시도할 수 있습니다. getItem 함수를 사용하고 ThemeChange.astro 구성 요소 내부에서 찾고자 하는 속성을 전달합니다.

<script>
          // Get the theme toggle input
          const themeToggle = document.querySelector(
            '.theme-switch input[type="checkbox"]'
          );

          // Get the current theme from local storage
          const currentTheme = localStorage.getItem("theme");

          // If the current local storage item can be found
          if (currentTheme) {
            // Set the body data-theme attribute to match the local storage item
            document.documentElement.setAttribute("data-theme", currentTheme);

            // If the current theme is dark, check the theme toggle
            if (currentTheme === "dark") {
              themeToggle.checked = true;
            }
          }

          // Function that will switch the theme based on the if the theme toggle is checked or not
          function switchTheme(e) {
            if (e.target.checked) {
              document.documentElement.setAttribute("data-theme", "dark");
              localStorage.setItem("theme", "dark");
            } else {
              document.documentElement.setAttribute("data-theme", "light");
              localStorage.setItem("theme", "light");
            }
          }

          // Add an event listener to the theme toggle, which will switch the theme
          themeToggle.addEventListener("change", switchTheme, false);

</script>


모든 구성 요소가 제자리에 배치되면 최종 결과는 다음과 같습니다.



결론



읽어주셔서 감사합니다. 연결해 봅시다!

언제든지 내email newsletter를 구독하고 에서 연결하세요.

좋은 웹페이지 즐겨찾기