본문 바로가기
토이 프로젝트/포트폴리오 웹사이트

포트폴리오 만들기 - 라이트/다크 모드 적용

by 강물둘기 2023. 9. 24.

다들 포트폴리오 웹사이트 하나정도는 가지고 있는거 같아서(?) 나도 만들어 보기로 했다.

 

사실 이 블로그를 쓰는 시점에서 대략 완료를 한 상태이다.

 

포트폴리오를 만들면서 새로 접한 개념이나 처음 구현해본 기능들의 기록을 남겨두려고 한다.

 

라이트모드/ 다크모드

찾아보니 다크모드 구현을 할 때 보통은 Context API의 ThemeProvider를 사용한다고 한다.

 

몇 가지 블로그를 둘러보다가 조금 더 간단하게 다크모드를 구현하는 블로그를 발견하여 이 방식대로 다크모드를 구현해보기로 했다.

https://kyounghwan01.github.io/blog/etc/CSS/dark-mode/

 

react로 다크 모드(dark mode) 만드는 법, styled-components, css, scss, theme

react로 다크 모드(dark mode) 만드는 법, styled-components, css, scss, theme

kyounghwan01.github.io

 

핵심은 가장 상위 html 태그에 클래스를 주는 방식으로 다크모드와 라이트모드를 변경하는 것이다.

const handleMode = () => {
if (mode === "dark") {
  setMode("light");
  document.getElementsByTagName("html")[0].classList.remove("dark-mode");
  localStorage.setItem("mode", "light");
} else {
  setMode("dark");
  document.getElementsByTagName("html")[0].classList.add("dark-mode");
  localStorage.setItem("mode", "dark");
}
};

 

위의 함수가 실행되면 다크 모드로 변경되고, 가장 상위 태그인 html 태그에 dark-mode class가 추가되고, state가 dark로 바뀐다. 그리고 새로고침할 때도 다크모드를 유지하기 위해 로컬 스토리지를 활용하여 다크모드 상태를 저장해둔다.

반대로 다크모드에서 위 함수가 실행되면 같은방식으로 라이트모드가 된다.

 

헤더 부분 아이콘을 클릭하면 다크모드로 변경되도록 Onclick 이벤트 리스너로 위의 함수를 추가한다.

const [mode, setMode] = useState<"dark" | "light">("light");

...

<button onClick={handleMode}>
    {mode === "light" ? <MdDarkMode /> : <MdLightMode />}
</button>

 

mode는 아이콘을 변경하기 위한 상태로 현재 모드에 따라 다른 아이콘을 렌더링 하도록 삼항연산자 사용했다.(아이콘은 react-icons 라이브러리를 사용했다.)

 

새로고침 할 때도 모드를 유지할 수 있도록 첫 렌더링 때 useEffect에서 로컬 스토리지의 mode를 불러올 수 있도록 코드를 작성해준다.

useEffect(() => {
    const localMode = localStorage.getItem("mode") as "dark" | "light" | null;
    if (localMode) setMode(localMode);
    if (localMode === "dark") {
      document.getElementsByTagName("html")[0].classList.add("dark-mode");
    }
  }, []);

 

만약 다크모드가 저장되어있으면 바로 다크모드로 바꿔준다.

 

이제 모드에 따라 다른 색상을 적용하도록 GlobalStyle에 아래처럼 모드 별 색상을 적용한다. 

:root {
        --background-color : #F8F6F4;
        --background-color2 : #CAEDFF;
        --border-color : black;
	// ...
}
.dark-mode {
    --background-color : #0E2954;
    --background-color2 : #1F6E8C;
    --border-color : white;

	// ...
}

 

css 변수를 지정하여 같은 변수명으로 :root에는 라이트모드에서 사용할 색상을, .dark-mode에서는 다크모드에서 사용할 색상을 쌍으로 선택해주었다.

 

라이트모드/ 다크모드

생각보다 간단하게 다크모드가 구현되는 것 같다!

 

 

댓글