
한참 모니터를 들여다보다가 퇴근하면서 눈이 뻑뻑하고 화면이 잔상처럼 남는 느낌, 한 번쯤 겪어봤을 거다. 나는 그게 당연한 줄 알았다. 컴퓨터를 많이 써서 그런 거라고. 그런데 어느 날 CSS를 조금 손봤더니 같은 시간을 봐도 눈이 덜 피로한 걸 느꼈다. 모니터가 바뀐 것도, 안경을 새로 맞춘 것도 아니었는데.
그 뒤로 화면이 눈에 주는 피로감이 설정에 따라 달라진다는 걸 체감했다. 오늘은 내가 직접 써보고 "이건 확실히 다르다"고 느낀 CSS 설정 다섯 가지와, 그걸 다크모드까지 연결하는 방법을 정리한다.
배경색, 글자색, 줄 길이 — 숫자로 보는 색상 설정
배경색을 순수 흰색인 #ffffff 대신 #faf9f6으로 바꾸는 것은 단순한 취향 문제가 아닙니다. 이 차이는 광도(Luminance) 값의 차이로 설명됩니다. 광도란 화면이 방출하는 빛의 밝기를 수치화한 것으로, 순수 흰색은 최대 광도를 출력하여 눈의 조절근(눈의 초점을 맞추는 근육)을 지속적으로 긴장시킵니다. 저도 처음 배경색을 바꿨을 때는 그 자리에서 큰 차이를 못 느꼈습니다. 그런데 그날 저녁 눈이 평소보다 덜 뻑뻑하다는 걸 알아챘고, 그때부터 이 설정을 진지하게 보기 시작했습니다.
글자색도 마찬가지입니다. #000000 대신 #2c2c3e처럼 약간 완화된 색상을 쓰는 이유는 명암비(Contrast Ratio)와 관련이 있습니다. 명암비란 배경색과 글자색 사이의 밝기 차이를 나타내는 비율로, 너무 높으면 오히려 눈의 피로를 가중시킵니다. 제가 직접 원래 설정으로 되돌려봤을 때, 순수 검정 텍스트가 얼마나 강하게 눈에 박히는지 비교해보고 나서야 그 차이를 실감했습니다. 수치상으로 미미해 보여도 장시간 읽기에서는 누적 피로가 다릅니다.
줄 길이 제한도 눈에 띄는 효과가 있습니다. CSS에서 max-width: 65ch로 설정하면 한 줄에 표시되는 문자 수를 약 65자로 제한할 수 있습니다. 여기서 ch 단위란 해당 폰트에서 숫자 '0'의 너비를 1단위로 삼는 상대 단위로, 폰트 크기가 달라져도 가독성 기준을 일정하게 유지할 수 있습니다. 처음에는 콘텐츠 영역이 너무 좁아지는 게 아닌가 걱정했는데, 실제로 적용하고 나니 오히려 본문이 더 깔끔하고 읽기 편해 보였습니다. 눈이 한 줄 끝에서 다음 줄 첫 글자를 찾아 이동하는 거리 자체가 줄어들기 때문입니다.
한 가지 아쉬운 점을 짚자면, max-width: 65ch 설정이 반응형 환경에서 어떻게 동작하는지에 대한 언급이 빠진 경우가 많습니다. 모바일에서는 화면 자체가 좁아 이 설정이 실질적인 효력을 발휘하지 못하는 경우도 있습니다. 이럴 때는 미디어 쿼리(Media Query)를 활용해 뷰포트 너비에 따라 조건 분기를 걸어두는 것이 좋습니다. 미디어 쿼리란 화면 크기나 해상도 같은 환경 조건에 따라 다른 스타일을 적용하게 해주는 CSS 기능입니다.
눈 피로를 줄이기 위한 핵심 CSS 설정을 정리하면 다음과 같습니다.
- 배경색: #ffffff → #faf9f6 (광도 완화)
- 글자색: #000000 → #2c2c3e (명암비 조정)
- 줄 길이: max-width: 65ch (ch 단위 활용)
- 줄 간격: line-height: 1.7~1.8 (행간 확보)
- 폰트 렌더링: -webkit-font-smoothing: antialiased 적용
웹 접근성 관련 명암비 기준은 WCAG(Web Content Accessibility Guidelines)에서 본문 텍스트 기준 최소 4.5:1 이상을 권고하고 있습니다(출처: W3C WCAG). 여기서 WCAG란 웹 콘텐츠를 장애인을 포함한 모든 사용자가 접근 가능하도록 만들기 위한 국제 표준 지침을 말합니다. 단순히 예쁜 색을 고르는 게 아니라, 접근성 기준을 충족하면서도 피로를 줄이는 색 조합을 찾는 것이 핵심입니다.
체크리스트 코드에는 font-smoothing 속성이 포함되어 있는데, 이 부분을 설명 없이 넘기는 글들이 꽤 있습니다. -webkit-font-smoothing: antialiased는 글자 가장자리를 부드럽게 렌더링해주는 속성으로, 거칠게 계단식으로 표현되는 픽셀을 완화합니다. 장시간 텍스트를 읽을 때 이 처리 차이가 눈의 피로 누적에 영향을 줄 수 있습니다.
다크모드 구현 — OS 연동 vs 토글, 어느 쪽이 나을까
다크모드를 구현하는 방식은 크게 두 가지입니다. 하나는 prefers-color-scheme 미디어 쿼리를 통해 OS 설정을 자동으로 감지하는 방식이고, 다른 하나는 사용자가 직접 버튼으로 전환하는 토글 방식입니다. 여기서 prefers-color-scheme란 운영체제의 다크/라이트 모드 설정값을 CSS가 직접 읽어올 수 있게 해주는 미디어 기능입니다(출처: MDN Web Docs).
저도 두 방식을 모두 구현해서 운영해봤습니다. OS 연동 방식은 설정이 간결하고 자동으로 적용된다는 장점이 있지만, 독자 입장에서는 제어권이 없다는 불만이 있었습니다. 반면 토글 방식을 도입했을 때 독자 반응이 확연히 달라졌습니다. "낮에 밝게 써도 되고 밤에 어둡게도 되니 편하다"는 피드백이 직접 들어올 정도였습니다.
토글 방식을 구현할 때 JavaScript 한 줄로 클래스만 교체하는 방식은 간단하지만 한계가 있습니다. 페이지를 새로고침하거나 다른 페이지로 이동하면 설정이 초기화됩니다. 이를 해결하려면 localStorage를 활용해 사용자의 선택값을 브라우저에 저장해야 합니다. 여기서 localStorage란 브라우저에 키-값 형태로 데이터를 저장하고, 탭이나 브라우저를 닫아도 값이 유지되는 Web Storage API를 말합니다. 재방문 시에도 다크모드 설정이 그대로 유지된다면 독자 경험이 한 단계 올라갑니다. 이 부분을 빠뜨리고 단순 토글만 구현한 코드가 많은데, 제 경험상 이건 꼭 챙겨야 할 부분입니다.
CSS 변수(Custom Properties)를 활용하면 다크모드 전환이 훨씬 깔끔해집니다. CSS 변수란 :root 선택자에 색상이나 간격값을 변수로 정의해두고, 다크모드 클래스 하나만 교체하면 사이트 전체 색상이 한꺼번에 바뀌도록 만드는 방식입니다. 각 요소마다 개별적으로 색상을 재정의할 필요가 없어서 유지보수 측면에서도 훨씬 효율적입니다.
CSS 몇 줄로 독자 경험이 실질적으로 달라진다는 걸 직접 느끼고 나서, 설정 하나하나를 훨씬 꼼꼼하게 챙기게 됐습니다. 배경색, 글자색, 줄 길이, 줄 간격, 그리고 다크모드까지 — 이 다섯 가지를 순서대로 적용해보는 것만으로도 충분히 체감 가능한 변화가 생깁니다. 특히 줄 길이 제한과 localStorage 기반 다크모드 토글은 바로 오늘 적용해볼 수 있는 설정입니다. 작은 수치 하나가 장시간 독자를 붙잡는 경험의 질을 결정한다고 저는 생각합니다.
참고
MDN Web Docs – prefers-color-scheme
Google Material Design – Dark Theme
CSS-Tricks – Dark Mode in CSS
web.dev – prefers-color-scheme 가이드