웹사이트나 앱에 다크 모드를 추가하는 방법 (깜빡임 없이)
다크 모드를 추가하려면 색상을 하드코딩된 값 대신 이름이 있는 토큰(배경, 텍스트, 표면, 테두리, 강조색)으로 정의하고, 각 토큰에 라이트 값과 다크 값을 주세요. 그리고 CSS prefers-color-scheme 미디어 기능으로 두 값을 전환하면 사이트가 방문자의 시스템 설정을 따라가요. 수동 토글도 원한다면 선택 내용을 브라우저에 저장하고, 페이지 head에 있는 아주 작은 인라인 스크립트로 적용해서 로드 시 하얗게 깜빡이지 않게 하세요. 그다음 두 테마 모두에서 대비, 이미지, 차트를 확인하세요. AI 앱 빌더에서는 명확한 프롬프트 하나로 이 작업의 대부분을 할 수 있어요. 품질은 확인하는 단계에서 결정돼요.
두 가지 방식
| 방식 | 동작 방법 | 적합한 경우 | 고려할 점 |
|---|---|---|---|
| 시스템 따르기 | CSS 미디어 기능 prefers-color-scheme이 라이트나 다크를 고름 | 단순한 사이트, UI 없음 | 방문자가 기기 설정과 다르게 고를 수 없어요 |
| 토글 + 시스템 기본값 | 시스템 설정으로 시작하고, 라이트 / 다크 / 시스템 스위치로 덮어쓰며 그 선택을 기억함 | 사람들이 자주 쓰는 앱 | 약간의 자바스크립트와 로드 시 깜빡임 문제를 해결해야 해요 |
대부분의 앱은 두 번째 방식이 가장 잘 맞아요. 기본으로 시스템을 존중하고, 사람들이 이를 바꿀 수 있게 하세요.
색상 토큰부터 시작하세요
색상이 white, #333, gray-100처럼 코드 곳곳에 흩어져 있으면 다크 모드는 고통스러워요. 모든 색상이 몇 개의 이름 있는 토큰에서 나오면 쉬워져요:
| 토큰 | 라이트 | 다크 |
|---|---|---|
background | 거의 흰색 | 아주 어두운 회색 |
surface (카드, 메뉴) | 흰색 | 조금 더 밝은 어두운 회색 |
text | 거의 검은색 | 흰색에 가까운 색 |
text-muted | 중간 회색 | 더 밝은 중간 회색 |
border | 밝은 회색 | 약간 대비가 있는 어두운 회색 |
accent | 브랜드 색상 | 보통 더 밝거나 채도가 낮은 버전 |
각 컴포넌트는 토큰 이름을 사용해요. 그러면 테마를 바꾸는 것은 모든 컴포넌트를 고치는 일이 아니라 값 한 세트를 바꾸는 일이 돼요.
다크 팔레트를 위한 팁:
- 넓은 영역에는 순수한 검은색과 순수한 흰색을 피하세요. 아주 어두운 회색과 흰색에 가까운 색이 읽기 더 편해요.
- 그림자가 아니라 더 밝은 표면으로 깊이를 표현하세요. 그림자는 어두운 배경에서 거의 보이지 않아요.
- 밝은 브랜드 색상은 약간 채도를 낮추세요. 어두운 배경에서는 불편하게 빛날 수 있어요.
- 대비를 읽을 수 있게 유지하세요. WCAG AA 기준은 일반 텍스트에 최소 4.5:1의 대비를 요구해요. 흐린 회색 텍스트는 다크 테마에서 이 기준을 자주 못 맞춰요.
Tailwind CSS 사용 시
Tailwind는 AI로 만든 많은 앱에서 기본 스타일링 도구예요. Tailwind의 다크 모드 문서에 따르면, dark: 변형은 기본적으로 prefers-color-scheme을 쓰므로 bg-white dark:bg-gray-900 같은 클래스는 추가 작업 없이 시스템 설정을 따라요.
Tailwind v4에서 수동 토글을 쓰려면, 문서는 변형을 부모 요소의 클래스로 바꾸는 방법을 보여 줘요:
@import "tailwindcss";
@custom-variant dark (&:where(.dark, .dark *));
그러면 앱은 루트 요소에 dark 클래스를 추가하거나 제거해요. 문서는 또한 페이지가 그려지기 전에 저장된 선택(또는 시스템 설정)을 적용하는 head의 인라인 스크립트를 권장해요. 이것이 바로 깜빡임을 피하는 방법이에요.
하얗게 깜빡이는 현상 막기
깜빡임은 페이지가 라이트 모드로 먼저 그려진 뒤, 자바스크립트가 로드되어 저장된 선택을 읽고 다크로 바꾸기 때문에 생겨요. 해결 방법은 다음과 같아요:
- 무엇이든 렌더링되기 전에 저장된 테마를 읽어 루트 요소에 클래스를 설정하는 아주 작은 인라인 스크립트를 페이지 head에 넣으세요.
- 각 테마에 맞춰
color-schemeCSS 속성을 설정하세요. 그래야 브라우저가 그리는 부분(스크롤바, 폼 컨트롤)도 맞아요. - 두 테마 모두에 명시적인 배경색을 지정하세요.
- 앱이 서버 렌더링이라면, 서버와 브라우저가 초기 테마에 동의하도록 하세요. 그렇지 않으면 페이지가 다시 그려지며 깜빡일 수 있어요.
프롬프트 예시
전체 설정:
다크 모드를 추가해 줘. 먼저 하드코딩된 색상을 테마 토큰(배경, 표면, 텍스트, 흐린 텍스트, 테두리, 강조색)으로 바꾸고, 각 토큰에 라이트와 다크 값을 줘. 기본값은 방문자의 시스템 설정을 따르게 해. 헤더에 라이트, 다크, 시스템 옵션이 있는 테마 스위치를 추가하고, 선택은 localStorage에 기억하고, head의 인라인 스크립트로 적용해서 로드 시 하얗게 깜빡이지 않게 해 줘. 각 테마에 color-scheme을 설정해 줘. 현재 라이트 디자인은 그대로 유지해 줘.
남은 부분 정리:
모든 페이지를 다크 모드에서 확인하고 다음을 고쳐 줘: 대비가 낮은 텍스트(최소 4.5:1 목표), 하드코딩된 흰색 배경, 사라지는 테두리, 어두운 배경 위의 어두운 텍스트 차트, 사라지는 로고. 라이트 테마는 바꾸지 마.
이미지와 차트:
다크 모드에서는 밝은 버전의 로고를 써 줘. 차트의 축, 격자선, 라벨이 테마 토큰을 쓰게 해. 다크 모드에서 스크린샷에 은은한 테두리를 줘서 배경과 섞이지 않게 해 줘.
단계별 진행
- 색상 감사. 하드코딩된 색상을 찾아 토큰으로 바꾸세요. 이것이 작업의 대부분이에요.
- 각 토큰의 다크 값을 정의하세요.
prefers-color-scheme(또는 Tailwind의 기본dark:)으로 시스템 설정을 따르게 하세요.- 원한다면 토글을 추가하세요: 라이트, 다크, 시스템. 선택은 브라우저에 저장하고, 로그인하는 앱이라면 사용자 프로필에도 저장할 수 있어요.
- head 인라인 스크립트와
color-scheme으로 깜빡임을 막으세요. - 까다로운 부분을 확인하세요: 로고, 아이콘, 흰 배경을 가진 이미지, 차트, 코드 블록, 지도, 임베드, 이메일.
- 두 테마 모두 테스트하세요. 데스크톱과 휴대폰에서, 시스템을 라이트와 다크로 각각 설정해서, 그리고 강력 새로고침 후에도 확인하세요.
흔한 실수
- 모든 것을 반전시키기. 색을 반전하는 필터는 사진과 브랜드 색상을 망가뜨려요.
- 하드코딩된 색상이 남아 있음. 다크 페이지에 흰 카드 하나만 있어도 바로 눈에 띄어요.
- 대비가 낮은 회색 텍스트. 세련돼 보이지만 가독성 기준에서 떨어져요.
- 로드 시 흰색 깜빡임. 특히 밤에 휴대폰에서 두드러져요.
- 제3자 임베드를 잊음. 지도, 영상, 위젯이 밝은 상태로 남을 수 있어요. 다크 옵션이 있는지 확인하세요.
- 두 가지 상태만 있는 토글. 한 번 누르면 다시 시스템을 따르는 상태로 돌아갈 수 없어요.
- 라이트 테마를 망가뜨림. 프롬프트에 라이트 디자인은 그대로 유지하라고 명시하세요.
체크리스트
- 모든 색상이 테마 토큰에서 나와요
- 기본값으로 시스템 설정을 따라요
- 라이트, 다크, 시스템을 고를 수 있는 선택 토글이 있고 선택이 기억돼요(선택 사항)
- 로드나 새로고침 시 흰색 깜빡임이 없어요
- 폼 컨트롤과 스크롤바가 맞도록
color-scheme이 설정되어 있어요 - 두 테마 모두에서 텍스트 대비가 최소 4.5:1이에요
- 로고, 이미지, 차트, 임베드를 다크 모드에서 확인했어요
- 라이트 테마는 바뀌지 않았어요
- 데스크톱과 휴대폰에서 테스트했어요
Mythex에서 다크 모드
Mythex로 만든 앱은 기본적으로 Vite, React, TypeScript, Tailwind를 쓰므로 위의 Tailwind 방식이 그대로 적용돼요. 전체 설정 프롬프트를 채팅에 붙여 넣은 뒤, 미리보기에서 두 테마 모두와 휴대폰 크기로 확인하세요. Mythex의 디자인 프롬프트 권장 사항은 무엇을 바꾸고 무엇을 유지할지 말하는 것인데, 여기서 특히 중요해요. 라이트 테마는 그대로 유지해야 한다고 말하세요. 자세한 내용은 디자인과 UI 프롬프트를 참고하고, 작업이 잘못되면 체크포인트로 되돌리세요.
디자인을 좋게 만드는 방법에 대해서는 AI로 좋은 디자인의 앱을 만드는 방법과 AI 앱 빌더용 프롬프트 작성 방법을 참고하세요.
자주 묻는 질문
사이트가 기기의 다크 모드 설정을 따르게 하려면 어떻게 하나요?
CSS prefers-color-scheme 미디어 기능을 쓰세요. 방문자의 시스템이 라이트인지 다크인지 알려 줘요. Tailwind의 dark: 변형은 기본적으로 이 기능을 써요.
다크 모드로 바꾸기 전에 사이트가 하얗게 깜빡이는 이유는 무엇인가요?
저장된 테마는 페이지가 이미 그려진 뒤에 자바스크립트로 적용돼요. 페이지 head에 아주 작은 인라인 스크립트를 넣어 무엇이든 렌더링되기 전에 테마 클래스를 설정하고, 두 테마 모두에 명시적인 배경색을 지정하면 해결돼요.
다크 모드는 순수한 검은색이어야 하나요?
보통은 아니에요. 아주 어두운 회색이 긴 글을 읽을 때 눈이 덜 피곤하고, 조금 더 밝은 표면으로 깊이감을 줄 수 있어요. 순수한 검은색은 OLED 중심이거나 미디어가 많은 디자인에 어울릴 수 있어요.
시스템 설정을 따른다면 다크 모드 토글이 필요한가요?
꼭 그렇지는 않아요. 시스템을 따르는 것이 좋은 기본값이지만, 라이트, 다크, 시스템 옵션이 있는 토글은 기기 설정과 다르게 사이트를 보고 싶은 사람들에게 도움이 돼요.