Tailwind CSS Typography의 양면성: prose 태그 색상 덮어쓰기 문제 해결 가이드
가끔 우리는 마크다운으로 작성된 콘텐츠를 렌더링할 때 tailwindcss/typography 플러그인의 prose 클래스를 마법의 지팡이처럼 사용하곤 합니다. 하지만 이 지팡이가 때로는 의도치 않은 곳에 불을 지르기도 하죠. 오늘은 실무에서 개발자를 괴롭히는 prose 클래스의 텍스트 색상 강제 문제와 그 근본적인 원인, 그리고 해결책을 깊이 있게 다뤄보겠습니다.
목차
- tailwindcss/typography를 사용하는 이유
- 블로그에는 축복, UI에는 재앙인 이유
- 텍스트 색상이 덮어씌워지는 기술적 원인
- 고통에서 벗어나는 3가지 해결 전략
- 개발자의 팁: CSS Cascade 제어하기
tailwindcss/typography를 사용하는 이유
일반적으로 Tailwind CSS는 Utility-first 철학을 따릅니다. 즉, 모든 HTML 요소에 직접 클래스를 입력해야 하죠. 하지만 CMS에서 가져온 HTML이나 마크다운 파일처럼 내가 직접 태그에 클래스를 입힐 수 없는 동적 콘텐츠는 어떻게 처리해야 할까요?
이때 구원투수로 등장하는 것이 바로 tailwindcss/typography입니다. 부모 요소에 prose 클래스 하나만 추가하면, 그 하위에 있는 <h1>, <p>, <ul>, <a> 등의 태그에 미리 정의된 세련된 타이포그래피 스타일이 자동으로 적용됩니다.
- 자동 스타일링:
<h1>의 여백,<li>의 불렛 기호 등을 일일이 설정할 필요가 없습니다. - 일관성: 전체 서비스에서 글의 형태를 상위 레벨에서 강제하여 가독성을 높입니다.
블로그에는 축복, UI에는 재앙인 이유
블로그에서의 축복
블로그 포스트나 문서 페이지처럼 **“글 자체가 주인공”**인 곳에서 prose는 완벽합니다. 마크다운을 HTML로 변환한 뒤 별도의 스타일링 없이도 바로 읽기 좋은 상태를 만들어주기 때문입니다.
UI 구성 요소에서의 재앙
하지만 일반적인 서비스 UI(대시보드, 카드 컴포넌트, 모달 등) 내부에 마크다운 영역이 포함될 때 문제가 발생합니다. prose 클래스는 하위 요소의 스타일을 강력하게 제어하려고 합니다.
특히 텍스트 색상이 문제입니다. 다크 모드를 지원하거나, 브랜드 컬러가 중요한 UI 요소에서 prose가 적용된 영역은 자신만의 색상 체계를 고집하며 부모로부터 상속받아야 할 디자인 시스템을 무시해버립니다.
Warning:
prose는 단순히 스타일을 추가하는 것이 아니라, 내부 요소의 CSS 우선순위를 높여서 기존 스타일을 덮어씌우는 성질이 있습니다.
텍스트 색상이 덮어씌워지는 기술적 원인
prose 클래스는 내부적으로 Complex Selectors를 생성합니다. 예를 들어 .prose p는 단순한 .text-gray-500보다 우선순위가 높을 수 있습니다.
<div class="prose text-blue-500">
<p>하지만 나는 여전히 회색(prose 기본값)으로 보일 겁니다.</p>
</div>
위 코드에서 text-blue-500은 부모 요소인 div에 적용되지만, typography 플러그인이 생성한 .prose p 규칙이 브라우저에서 더 구체적인 선택자로 판단되어 내부 <p> 태그의 색상을 가로챕니다.
고통에서 벗어나는 3가지 해결 전략
1. prose-invert 사용 (다크모드 대응)
다크 모드에서 텍스트가 안 보이는 현상은 prose-invert 클래스로 간단히 해결 가능합니다. 이는 밝은 텍스트 테마로 전환해줍니다.
2. 색상 무효화 (not-prose)
특정 영역만 prose의 영향력에서 벗어나게 하고 싶다면 not-prose 클래스를 사용하세요.
<article className="prose">
<h1>나의 멋진 블로그</h1>
<div className="not-prose">
{/* 이 내부의 요소들은 prose의 스타일을 전혀 상속받지 않습니다. */}
<CustomComponent color="text-red-600" />
</div>
</article>
3. prose-{{color}} 유틸리티 활용
Tailwind 3.x 버전부터는 prose-slate, prose-gray 등을 통해 기본 텍스트 톤을 조절할 수 있습니다. 만약 특정 색상을 강제하고 싶다면 prose-headings:text-indigo-600 처럼 개별 요소에 대한 수정자(modifier)를 사용할 수도 있습니다.
개발자의 팁: CSS Cascade 제어하기
실무에서는 prose 내부에서 특정 텍스트만 다른 색상을 가져야 하는 경우가 많습니다. 이때 가장 깔끔한 방법은 CSS Variable을 활용하는 것입니다. Tailwind Typography는 내부적으로 CSS 변수를 사용하므로, tailwind.config.js에서 이를 커스터마이징하거나 인라인 스타일로 해당 변수값만 주입하는 방식이 가장 유지보수에 유리합니다.
// tailwind.config.js 예시
module.exports = {
theme: {
extend: {
typography: {
DEFAULT: {
css: {
color: 'inherit', // 부모의 색상을 상속받도록 강제
'h1, h2, h3': {
color: 'inherit',
},
},
},
},
},
},
}
자주 묻는 질문 (FAQ)
Q1. prose 클래스를 썼는데 링크(a 태그) 색상만 안 바뀌어요.
prose는 기본적으로 링크에 밑줄과 특정 색상을 부여합니다. 이를 끄고 싶다면 클래스에 prose-a:text-current 혹은 no-underline을 추가하여 부모의 설정을 따르도록 강제해야 합니다.
Q2. 모든 페이지에 prose를 적용하는 게 좋을까요?
아니요. 사용자가 텍스트를 입력하는 에디터 출력물, 공지사항, 가이드 문서 등에만 제한적으로 사용하는 것을 권장합니다. 일반 UI 컴포넌트(GNB, Footer, Card)에는 직접 유틸리티 클래스를 쓰는 것이 훨씬 제어하기 쉽습니다.
Q3. 커스텀 폰트를 prose에 적용하려면?
prose 요소에 직접 Tailwind의 font-family 클래스(예: font-sans)를 추가하면 하위 요소들에 자연스럽게 적용됩니다. 만약 특정 제목에만 적용하고 싶다면 prose-h1:font-serif 형식을 사용하세요.
오늘 살펴본 것처럼 tailwindcss/typography는 강력한 도구이지만, 그만큼의 제어권도 가져갑니다. “글의 형태를 위에서 강제한다”는 철학을 이해하고 적절한 곳에만 배치한다면, 여러분의 개발 고통 지수는 확연히 낮아질 것입니다!