색과 글자는 조금만 어긋나도 화면이 촌스럽거나 안 읽히게 됩니다. 실무에서 반복해서 마주치는 실수들을 나쁜 예와 좋은 예 코드로 나란히 놓고 고쳐 봅니다. 아래 예제는 그대로 확인할 수 있습니다.

60.1 순수 검정 본문

본문을 완전한 검정으로 두면 흰 배경과 대비가 너무 세서 눈이 쉽게 지칩니다. 아주 진한 회색이 오래 읽기 편합니다.


/* 나쁜 예 */
body { color: #000000; }
/* 좋은 예 */
body { color: #1f2937; }


순수 검정은 화면에서 획이 번져 보이기까지 합니다. 명도를 살짝 올린 먹색이 종이에 가까운 느낌을 줍니다.

60.2 대비 낮은 회색 글씨

반대로 옅은 회색 본문은 세련돼 보이지만 안 읽힙니다. 대비 기준을 넘기는 선까지만 옅게 씁니다.


/* 나쁜 예: 흰 배경에서 약 2.3:1 */
.desc { color: #a8a8a8; }
/* 좋은 예: 약 5.7:1 */
.desc { color: #6b6b6b; }


보조 설명이라도 4.5:1은 지켜야 합니다. 옅게 두고 싶은 마음과 읽혀야 하는 필요 사이에서 후자가 이겨야 합니다.

60.3 폰트를 너무 많이

제목, 본문, 강조에 서로 다른 폰트를 쓰면 화면이 소란스럽습니다. 두 벌로 줄이고 굵기로 변화를 줍니다.


/* 나쁜 예: 폰트 네 개 */
h1 { font-family: "Lobster"; }
h2 { font-family: "Oswald"; }
p { font-family: "Georgia"; }
.cta { font-family: "Pacifico"; }
/* 좋은 예: 두 벌 + 굵기 */
h1, h2 { font-family: "Poppins", sans-serif; font-weight: 700; }
p, .cta { font-family: "Inter", sans-serif; }


폰트가 많을수록 통일감이 깨지고 로딩도 무거워집니다. 두 벌 안에서 굵기와 크기로 위계를 주는 편이 훨씬 깔끔합니다.

60.4 모바일에서 너무 작은 글씨

데스크탑에서 정한 작은 글씨가 폰에서는 눈을 찡그리게 합니다. 본문은 16px 아래로 내리지 않습니다.


/* 나쁜 예 */
body { font-size: 13px; }
/* 좋은 예 */
body { font-size: 1rem; } /* 16px 이상 */


모바일 브라우저는 16px 미만 입력창에서 화면을 확대해 버리기도 합니다. 본문 기준을 16px에 두면 확대 없이 그대로 읽힙니다.

60.5 색만으로 상태 표시

필수 항목이나 오류를 색 하나로만 알리면 색을 구분 못 하는 사용자는 놓칩니다. 아이콘이나 글자를 겹칩니다.


/* 나쁜 예: 빨강만 */
.required label { color: #dc2626; }
/* 좋은 예: 기호를 함께 */
.required label::after {
content: " *";
color: #dc2626;
}


별표 하나만 붙여도 색을 못 봐도 필수임이 전해집니다. 색은 신호를 거들 뿐, 유일한 신호가 되면 안 됩니다.

60.6 픽셀 고정 행간

행간을 픽셀로 고정하면 글자 크기가 바뀔 때 따라오지 못합니다. 단위 없는 배수로 줍니다.


/* 나쁜 예 */
p { font-size: 1.25rem; line-height: 20px; }
/* 좋은 예 */
p { font-size: 1.25rem; line-height: 1.6; }


20px 행간은 큰 글씨에서 줄이 겹칠 지경이 됩니다. 배수로 두면 크기가 바뀌어도 간격이 비율을 지킵니다.

60.7 한 줄이 너무 긴 본문

넓은 화면에서 본문이 끝까지 늘어지면 눈이 다음 줄을 못 찾습니다. 폭을 ch로 묶습니다.


/* 나쁜 예: 폭 제한 없음 */
.article { width: 100%; }
/* 좋은 예 */
.article {
max-width: 65ch;
margin-inline: auto;
}


한 줄이 100자를 넘어가면 읽는 속도가 뚝 떨어집니다. 65ch 언저리로 묶고 가운데 정렬하면 넓은 모니터에서도 편합니다.

60.8 색을 곳곳에 하드코딩

같은 색을 여러 파일에 직접 적어 두면 바꿀 때 지옥입니다. 변수 하나로 모읍니다.


/* 나쁜 예: 같은 색 반복 */
.btn { background: #2563eb; }
.link { color: #2563eb; }
.badge { border-color: #2563eb; }
/* 좋은 예: 토큰 하나 */
:root { --brand: #2563eb; }
.btn { background: var(--brand); }
.link { color: var(--brand); }
.badge { border-color: var(--brand); }


색을 바꿀 때 하드코딩은 파일을 뒤지게 하지만 토큰은 한 줄이면 끝납니다. 브랜드색처럼 반복되는 값일수록 변수로 묶어 두는 것이 이득입니다.

60.9 긴 문장을 전부 대문자로

강조하려고 긴 문장을 대문자로 도배하면 오히려 읽기 어려워집니다. 짧은 라벨에만 쓰고 자간을 벌립니다.


/* 나쁜 예: 긴 문장 대문자 */
.notice { text-transform: uppercase; }
/* 좋은 예: 짧은 라벨만 */
.tag {
text-transform: uppercase;
letter-spacing: 0.08em;
font-size: 0.75rem;
}


대문자는 글자 높이가 같아 긴 문장에서 단어 모양이 사라집니다. 카테고리 라벨처럼 짧은 곳에만 쓰고 자간을 살짝 벌려야 답답하지 않습니다.

60.10 그라데이션 위 글씨

화려한 그라데이션 배경에 글자를 얹으면 어떤 지점에서는 대비가 무너집니다. 글자 뒤에 반투명 판을 깔거나 그림자로 받칩니다.


/* 나쁜 예: 배경 색이 밝은 곳에서 안 읽힘 */
.hero-text { color: #fff; }
/* 좋은 예: 어두운 판을 덧대 대비 확보 */
.hero-text {
color: #fff;
text-shadow: 0 1px 3px rgba(0,0,0,0.5);
background: rgba(0,0,0,0.25);
padding: 0.5em 0.75em;
}


배경이 자리마다 밝기가 달라지면 흰 글씨가 어떤 구간에서 사라집니다. 그림자와 반투명 판이 글자 주변만 어둡게 눌러 어디서나 읽히게 합니다.

60.11 링크를 색으로만 구분

본문 링크를 색만 바꿔 표시하면 색을 못 보는 사용자에겐 그냥 본문입니다. 밑줄을 함께 씁니다.


/* 나쁜 예: 색만 */
a { color: #2563eb; text-decoration: none; }
/* 좋은 예: 밑줄 병행 */
a {
color: #1d4ed8;
text-decoration: underline;
text-underline-offset: 2px;
}


밑줄이 있으면 색을 못 봐도 링크임을 압니다. offset을 조금 줘서 밑줄이 글자에 딱 붙지 않게 하면 더 읽기 편합니다.

60.12 정리

흔한 실수는 대부분 극단에서 나옵니다. 순수 검정과 순수 흰색, 너무 옅은 회색, 너무 많은 폰트, 너무 작은 글씨, 색 하나에만 실은 신호가 그렇습니다. 진한 회색으로 물러서고, 대비 기준을 지키고, 폰트를 두 벌로 줄이고, 색은 토큰으로 모으고, 신호는 두 겹으로 주는 것, 이 몇 가지만 피해도 화면은 눈에 띄게 편안해집니다.