[Next.js] tailwind 다크모드
tailwindcss로 다크모드 설정하고, 제어 버튼으로 라이트모드/다크모드 전환하기. 디바이스 모드 확인하여 첫 방문 모드 설정하기.
코딩목차
사이트 콘텐츠는 조금 정리가 되었다.
이제 천천히 분류에 맞게 내용을 추가하면된다.
그래서 요즘
사이트 기능이나 디자인을 조금씩 수정하면서
어떻게 해야 더 좋은 UI가 될지 고민이 되기 시작했다.
tailwidncss 다크모드
요즘은 대부분 사이트에 있는 다크모드.
처음에 사이트를 만들 때,
"우선 만들고 고치자" 마인드이어서,
css코드에 색상 가이드를 전혀하지 않았다.
시작하려하니 조금 막막했으나,
우선 tailwind에서 찾아보기로 했다.
[tailwindcss 공식문]
아주 간단하게,
클라스네임에 dark:
만 사용하면
다크 모드를 뜻한다.
그러면
body 혹 html의 class명에 "dark"가 있으면dark:
뒤에 스타일이 적용된다.
body class 추가
전체적으로 수정할 수 있도록,
아예 body태그에 dark:
을 추가했다.
나는 전체를 layout.js
로 틀을 만들어서,
Home의 layout.js 를 수정했다.
// .\app\(route)\layout.js
export default function RootLayout({ children }) {
return (
<html lang="ko" className="dark">
<head>...</head>
<body className={inter.className + ' bg-white dark:bg-black dark:text-white'}>...</body>
</html>
);
}
위처럼
body의 className bg-white
뒤에dark:bg-black dark:text-white
를 추가했다.
(다크모드에 검은 배경 및 하얀 텍스트)
html 테스트용 class 추가
위처럼 테스트를 위해
html의 className은 dark
를 추가했다.
다른 색상을 사용한 텍스트 혹 요소는
하나씩 찾아보면 안보이는지 확있하고,
필요한 부분은 다크모드 class를 추가했다.
다크모드 controller
css는 완료되었다.
이제 html의 class에dark
를 추가/삭제하는 제어장치가 필요하다.
이벤트를 사용해야 하기 때문에,use client
를 사용해야 한다.
그래서 별도의 컴포넌트를 만들었다.
DarkmodeBtn
방식은 간단하다.
버튼을 만들고,
버튼이 클릭되면
html태그의 클래스를 추가/삭제한다.
// .\app\components\DarkmodeBtn.js
'use client';
const DarkmodeBtn = () => {
return <button onClick={handleClick}>🌗</button>;
function handleClick() {
document.querySelector('html').className == '' ? (document.querySelector('html').className = 'dark') : (document.querySelector('html').className = '');
}
};
export default DarkmodeBtn;
예시처럼,
button을 return하는 컴포넌트이다.
button이 onClick되면 handleClick을 호출한다.
handleClick은
document.querySelector('html').className 으로 현재 클라스명을 확인하고,
값이 없으면 dark
를 추가하고,
값이 dark
이면 "빈칸"으로 변경한다.
렌더링을 고려해야 하나 했지만 그냥 잘 작동된다.
생각해보니 css는 원래 브라우저가 처리해서
아마 class명이 변경되면
스타일도 자동으로 변경시키는 것 같다.
디바이스 모드 감지
처음 방문하면 무조건 라이트모드이다.
디바이스가 다크/라이트인지 확인하고
처음 방문할 때, 디바이스를 기준으로 하는 기능을 추가했다.
// .\app\components\DarkmodeBtn.js
'use client';
import { useEffect } from 'react';
const DarkmodeBtn = () => {
function handleClick() {
document.querySelector('html').className == '' ? (document.querySelector('html').className = 'dark') : (document.querySelector('html').className = '');
}
useEffect(() => {
if (window.matchMedia('(prefers-color-scheme:dark)').matches) {
document.querySelector('html').className = 'dark';
}
}, []);
return <button onClick={handleClick}>🌗</button>;
};
export default DarkmodeBtn;
react의 useEffect를 사용했다.
의존으로 빈 배열을 []
을 사용해서
처음 랜더링될 때만 작동한다.
window.matchMedia('(prefers-color-scheme:dark)').matches
으로 디바이스가 'dark'인지 확인하고,
다크모드이면 html의 class에 'dark'를 추가한다.
완료
이렇게 다크모드를 완료했다.
결론은
tailwindcss를 사용해서
다크모드일 때 변화가 필요한 부분에dark:
을 추가해서 스타일을 만든다.다크모드 제어 버튼을 만든다.
querySelector
로 html태그를 확인하고,
class에 'dark'를 추가/삭제한다.추가로
window.matchMedia
를 이용해서
디바이스가 다크/라이트모드를 확인하고useEffect
를 사용해서
처음 렌더링 시, 디바이스 모드 기준으로 사이트 모드를 정하게 했다.