TeX에는 색이라는 개념이 없습니다. 커누스가 설계한 조판 엔진은 상자와 글루로 지면을 쌓아 올릴 뿐이고, 그 모형 안에 색이 들어갈 자리는 없습니다. 색을 나타내는 원시 명령 자체가 없습니다. 그렇다면 LaTeX의 xcolor 패키지는 무엇을 하는 걸까요. 출력 드라이버에게 쪽지를 남깁니다. \textcolor{red}{…}라고 쓰면 TeX은 “여기부터 빨강”이라는 \special을 출력 파일에 끼워 넣고, 실제로 색을 칠하는 일은 나중에 PDF를 만드는 쪽이 맡습니다. 이 사실 하나만 알면 LaTeX에서 색과 관련해 이해가 안 가던 일이 거의 다 설명됩니다. 이 페이지는 그 길을 차례로 따라갑니다. \usepackage{xcolor} 불러오기에서 시작해 \textcolor, \colorbox, \pagecolor, \definecolor와 색 모델, red!30!white 같은 혼색 표기, 그리고 마지막 함정——화면의 색은 인쇄기에서 나오는 색이 아니라는 사실——까지입니다.
\usepackage{xcolor} 와 color 패키지의 차이: 무엇을 불러올까
답은 언제나 \usepackage{xcolor}입니다. xcolor는 David Carlisle의 color 패키지를 완전히 포함하는 상위 패키지로, color의 명령을 그대로 물려받은 위에 혼색, 추가 색 이름 집합, 모델 변환을 얹었습니다. 만든 사람은 Uwe Kern(2003–2021)이며 2021년부터는 LaTeX Project가 관리합니다. TeX Live 2024에 들어 있는 것은 v3.01(2023년 11월 15일) 입니다. 설계의 중심은 드라이버 비의존성 이어서, pdfTeX으로 조판하든 dvips를 거치든 같은 색 지정이 같은 방식으로 해석됩니다.
드라이버 비의존성에 대한 이 고집은 옵션 설계에 그대로 남아 있습니다. 옛 color 패키지는 dvips 계열 드라이버가 선택되면 dvipsnames의 68색을 말없이 켰습니다. 그 결과 내 컴퓨터에서는 잘 되다가 pdfTeX으로 바꾸는 순간 정의되지 않은 색으로 멈추는 문서가 만들어졌습니다. xcolor는 이 동작을 없앴습니다. dvipsnames라고 직접 쓴 사람에게만 색 이름을 내주는 대신, 그 이름들이 모든 드라이버에서 통하도록 했습니다. 아무 옵션 없이 쓸 수 있는 것은 19개의 기본 색이고, 필요에 따라 dvipsnames(68색), svgnames(151개 이름), x11names(317개 이름)를 얹습니다. 표에 색을 넣고 싶다면 table 옵션이 colortbl을 함께 데려옵니다.
\usepackage{xcolor} % 19 base colours, always available
\usepackage[dvipsnames]{xcolor} % + 68 cmyk names from the dvips driver
\usepackage[svgnames]{xcolor} % + 151 names from the SVG 1.1 spec
\usepackage[x11names]{xcolor} % + 317 names from the X11 rgb.txt
\usepackage[dvipsnames,svgnames]{xcolor} % sets can be combined
\usepackage[table]{xcolor} % also loads colortbl for coloured tables\textcolor 와 \color 의 차이, 그리고 \colorbox 와 \fcolorbox
\textcolor{red}{문자} 는 인수로 넘긴 범위만 색칠하고, \color{red} 는 감싸고 있는 TeX 그룹이 닫힐 때까지 색을 바꿔 두는 스위치입니다. 둘은 별개의 장치가 아닙니다. \textcolor는 중괄호를 대신 채워 준 \color일 뿐이며, xcolor 문서가 그렇게 설명하고 있습니다. 그래서 {\color{blue} …} 바깥의 { } 를 빠뜨리면 그 뒤 문서 전체가 파랗게 됩니다. 거꾸로 보면, 절이나 환경 안에서 쓴 \color는 그 환경이 끝날 때 저절로 원래대로 돌아온다는 뜻이기도 합니다. \textcolor는 여기에 더해 \leavevmode를 호출하므로 문단 맨 앞에 두어도 들여쓰기가 망가지지 않습니다.
This word is \textcolor{red}{red}, the rest is not.
{\color{blue} Everything from here to the closing brace is blue.} Back to black.
% the whole box gets a background; the frame colour comes first
\colorbox{yellow}{highlighted}
\fcolorbox{red}{yellow}{red frame, yellow fill}배경을 칠하는 것은 \colorbox{색}{문자} 이고, 테두리와 채우기를 따로 지정하는 것은 \fcolorbox{테두리색}{채움색}{문자} 입니다. 인수 순서는 “테두리가 먼저, 채우기가 나중”입니다. 여기에 빠지기 쉬운 함정이 하나 있습니다. \colorbox는 이름 그대로 상자 여서 내용이 행을 넘어가지 못합니다. 긴 문장에 강조를 넣으면 줄바꿈되지 않고 판면 밖으로 튀어나가며 Overfull \hbox 경고가 남습니다. 단어 몇 개를 도드라지게 하기에는 충분하지만, 문장 단위로 칠하고 싶다면 줄바꿈을 다룰 수 있는 soul의 \hl이나 tcolorbox 쪽으로 옮겨 가세요. 또한 다른 패키지의 색 인수——설명서가 직접 드는 예가 soul의 \sethlcolor 입니다——는 red!30!white 같은 색 표현식을 그대로 받지 못할 수 있습니다. 그럴 때는 \colorlet으로 이름을 붙인 뒤 그 이름을 넘깁니다.
| 명령 | 하는 일 | 적용 범위 |
|---|---|---|
\textcolor{c}{text} | 인수의 글자만 색 c로 | 인수 안에서만 |
\color{c} | 이 지점부터 글자색을 c로 바꿈 | 현재 TeX 그룹이 끝날 때까지 |
\colorbox{c}{text} | 글자 뒤에 c로 채운 상자를 둠 | 상자 하나. 행을 넘지 못함 |
\fcolorbox{f}{b}{text} | 테두리는 f, 배경은 b로 감쌈 | 위와 같음. 선 굵기는 \fboxrule |
\pagecolor{c} | 페이지 전체 바탕색을 c로 | 전역 선언. 이후의 모든 페이지 |
\nopagecolor | 바탕색을 지워 투명으로 되돌림 | 모든 드라이버가 지원하지는 않으며 로그에 기록이 남음 |
\pagecolor 가 그룹을 무시하는 이유: 색은 \special 이기 때문
\pagecolor{black} 은 현재 페이지와 그 뒤의 모든 페이지 바탕색을 바꿉니다. 게다가 \color와 달리 이것은 TeX 그룹을 존중하지 않는 전역 선언 입니다. {\pagecolor{black} …} 라고 써도 닫는 중괄호에서 되돌아오지 않습니다. 되돌리려면 \nopagecolor(투명으로 복귀)나 \pagecolor{white} 를 명시적으로 놓아야 합니다. 표지만 검게 하려 할 때 가장 먼저 발목을 잡는 성질이라, \maketitle 바로 뒤에 취소를 넣어 두는 것이 정석입니다. 바탕색이 아니라 특정 페이지에만 테두리나 워터마크를 겹치고 싶다면 eso-pic 계열 도구가 더 적합합니다.
\pagecolor{black}\color{white}
\maketitle
% \pagecolor is global: it must be cancelled by hand
\nopagecolor\color{black}이 “전역” 성질은 예의 없음이 아니라, 첫머리에서 말한 \special의 본성 그 자체입니다. 색은 TeX의 상자 안에 담기지 않고, 출력 파일에 남겨진 쪽지일 뿐입니다. 그래서 페이지가 바뀌면 쪽지가 닿지 않습니다. 초기 pdfTeX에는 이 때문에 유명한 문제가 있었습니다. 색을 켠 채로 페이지를 넘기면 다음 페이지에서 색이 사라졌습니다. 대책으로 pdfcolmk라는 패키지가 LaTeX의 마크 기구를 이용해 “이 페이지는 이 색으로 시작한다”를 매 페이지 다시 적어 넣었을 정도입니다. 2007년에 나온 pdfTeX 1.40이 색 스택을 내장하면서 이 기교는 필요 없어졌습니다. 지금 pdfcolmk는 아무 일도 하지 않는 호환용 빈 패키지이고, xcolor의 fixpdftex 옵션도 Package option 'fixpdftex' is obsolete and ignored 라고 경고만 내는 유물입니다. 오늘날의 pdfLaTeX에서는 색이 페이지를 넘어 유지됩니다.
\definecolor 와 \colorlet 을 나누어 쓰는 법
숫자에서 색을 만드는 것이 \definecolor{이름}{모델}{값}, 이미 있는 색에서 만드는 것이 \colorlet{이름}{색} 입니다. 브랜드 규정이 “#1B3A6B” 형태로 내려왔다면 앞쪽, “본문의 파랑을 조금 더 어둡게”라면 뒤쪽이라고 생각하면 헷갈리지 않습니다. 둘 다 프리앰블에 한 번만 써 두면 그 뒤로는 red나 blue와 같은 평범한 색 이름으로 행동합니다. \colorlet의 인수에는 다음 절에서 다룰 색 표현식을 그대로 넘길 수 있어서, 실무에서 가장 쓸모 있는 용도는 혼색에 이름을 붙이는 일 입니다. \colorlet{accent}{blue!30!black} 처럼 씁니다. 문서의 모든 색을 이런 이름을 거쳐 쓰도록 해 두면, 전체 색조 조정은 프리앰블 한 줄을 고치는 일로 끝납니다.
\definecolor{myblue}{rgb}{0.2,0.4,0.8} % from numbers
\definecolor{brand}{HTML}{1B3A6B} % from a web hex code
\colorlet{accent}{blue!30!black} % from an existing colour
\colorlet{ruleline}{brand!25} % a 25 % tint of the brand colourrgb・RGB・HTML・cmyk・gray: 색 모델은 무엇을 고를까
\definecolor의 두 번째 인수가 색 모델, 곧 색을 숫자로 적는 방식입니다. 실무에서 고르는 기준은 단순합니다. 손에 있는 숫자의 형태에 맞추면 됩니다. 웹 색상 코드를 받았다면 HTML, 디자인 도구가 0–255로 내준다면 RGB, 인쇄소에서 4색 지정이 왔다면 cmyk입니다. xcolor는 내부에서 서로 변환하므로 같은 색을 다른 모델로 써도 결과는 같습니다.
| 모델 | 값의 의미와 범위 | 예 |
|---|---|---|
rgb | 빨강・초록・파랑, 각각 소수 0–1 | {0.2,0.4,0.8} |
RGB | 같은 세 값을 정수 0–255로 | {51,102,204} |
HTML | 16진수 여섯 자리 RRGGBB. 앞의 # 는 붙이지 않음 | {FF8800} |
cmyk | 시안・마젠타・노랑・검정, 각각 0–1. 인쇄용 | {0,0.5,1,0} |
gray | 밝기 값 하나. 0이 검정, 1이 흰색 | {0.5} |
Gray | 같은 밝기이나 정수. 기본 상한은 15 | {8} |
hsb | 색상・채도・명도, 각각 0–1. 색상만 돌리기에 편리 | {0.6,0.8,0.9} |
wave | 가시광 파장(nm), 363–814. 물리 도판에 적합 | {589} |
named | 숫자 대신 기존 색 이름을 참조하는 유사 모델 | {Periwinkle} |
% four spellings of one orange
\definecolor{o1}{rgb}{1,0.5,0}
\definecolor{o2}{RGB}{255,128,0}
\definecolor{o3}{HTML}{FF8000}
\definecolor{o4}{cmyk}{0,0.5,1,0}
% the model can also be given inline, in brackets, at the point of use
\textcolor[HTML]{FF8800}{a one-off orange}
\color[gray]{0.5}모델은 쓰는 자리에서 대괄호로 직접 지정할 수도 있습니다. 한 번만 쓸 색이라 이름을 붙일 것도 없다면 \textcolor[HTML]{FF8800}{…} 나 \color[gray]{0.5} 로 끝냅니다. 표에서 유별난 것은 wave입니다. 가시광 파장을 나노미터로 건네면 xcolor가 그 파장이 어떻게 보이는지 계산합니다. \definecolor{sodium}{wave}{589} 는 나트륨 D선의 노란 주황색이 됩니다. 광학이나 스펙트럼 도판의 색을 맞출 때 이보다 정직한 지정은 없습니다. 반대로 named는 숫자를 갖지 않는 유사 모델로, dvipsnames 같은 옵션으로 불러온 기존 색 이름을 참조하기 위한 것입니다. 평소에는 색 이름을 그대로 쓰면 충분합니다.
red!30!white 의 ! 는 무엇을 하는가: 색 표현식으로 색 섞기
! 는 혼합 비율을 가르는 기호로, 색A!숫자!색B 는 “A를 그 퍼센트만큼, 나머지를 B로” 라는 뜻입니다. red!50!blue 를 실제로 펼치면 rgb의 0.5,0,0.5 가 나옵니다. 빨강과 파랑이 정확히 반씩인 보라입니다. 색 B를 생략한 red!20 은 나머지가 흰색 으로 간주되어 1,0.8,0.8, 곧 빨강 20 %에 흰색 80 %인 옅은 분홍이 됩니다. 바로 이 지점에서 xcolor는 color와 결정적으로 갈라집니다. 색 이름을 끝없이 늘리지 않고도, 지금 가진 색에서 필요한 농도를 뽑아낼 수 있습니다.
red!50!blue— 빨강과 파랑을 반씩. 펼치면rgb의0.5,0,0.5red!20— 빨강 20 %, 나머지는 흰색. 옅은 색(틴트)을 만드는 정석blue!30!black— 파랑 30 %, 검정 70 %. 어두운 색(셰이드)을 만드는 정석-red— 앞의 마이너스는 보색.-red는 정확히 시안(rgb의0,1,1)green!40!yellow!60— 표현식은 연결할 수 있고 왼쪽부터 차례로 섞임gray!15~gray!25— 글자 뒤에 깔 때 적당한 농도. 원색 위에서는 읽기 어려움
색 표현식은 “색이 필요한 모든 자리”에서 통합니다. \textcolor{blue!30!black}{…}, \colorbox{yellow!40}{…}, \definecolor 와 \colorlet 의 인수, 표를 칠하는 \rowcolor{gray!15} 까지 같은 표기입니다. 실무에서 효과가 큰 습관은 혼색을 본문 여기저기에 흩뿌리지 않고 \colorlet 으로 한 번만 이름을 붙여 두는 것입니다. accent 와 accent!15 두 개로 제목・상자・표 줄무늬까지 감당한다면, 색조 변경은 프리앰블 한 줄로 끝납니다. 반대로 blue!30!black 을 마흔 군데에 흩어 써 두면 나중에 색을 바꾸는 일이 찾아 바꾸기 노동이 됩니다.
\colorlet{accent}{blue!30!black}
\colorlet{accentbg}{accent!15}
% then, in the body
\textcolor{accent}{a heading}
\colorbox{accentbg}{a quiet highlight}
\fcolorbox{accent}{accentbg}{framed and filled}쓸 수 있는 색 이름: 기본 19색에서 752색까지
옵션을 하나도 붙이지 않아도 다음 19색 은 언제나 쓸 수 있습니다. xcolor.sty 자체가 정의하므로 어떤 드라이버, 어떤 문서 클래스에서도 같은 이름이 통합니다. 색 표현식의 재료로도 이 19색이면 대체로 충분해서, gray!20 이나 blue!30!black 같은 표기에 익숙해지면 색 이름을 더 늘릴 필요가 크게 줄어듭니다.
black,blue,brown,cyan,darkgray,gray,green,lightgray,lime,magenta,olive,orange,pink,purple,red,teal,violet,white,yellow
그래도 모자라면 옵션으로 이름을 더합니다. dvipsnames 는 dvips 드라이버에서 온 68색(RoyalBlue, Periwinkle, BurntOrange 등, 모두 cmyk 로 정의)을, svgnames 는 SVG 1.1 명세의 이름에 X11에서 가져온 네 개를 더한 151개 이름을, x11names 는 X11의 rgb.txt 에서 가져온 317개 이름을 줍니다. 여기에 xcolor 설명서가 스스로 적어 둔 재미있는 주석이 있습니다. svgnames 의 151개 이름이 가리키는 색은 실제로 141가지뿐입니다. Gray 와 Grey 처럼 철자만 다른 별칭이 같은 값을 가리키기 때문입니다. x11names 도 317개 이름에 315색입니다. 두 집합을 함께 불러오면 rgb.txt 의 752개 이름 전부에 손이 닿는다는 것이 설명서의 안내입니다.
이 색 이름들은 대소문자를 구별합니다. RoyalBlue 를 royalblue 라고 쓰면 ! Package xcolor Error: Undefined color 'royalblue'. 로 멈춥니다. 색 이름 집합을 아예 불러오지 않았을 때도——\usepackage{xcolor} 만 쓰고 Periwinkle 을 사용한 경우처럼——같은 오류가 납니다. 어느 이름이 어떤 색인지는 기억에 맡기지 말고 texdoc xcolor 로 설명서를 여는 편이 빠릅니다. 이름마다 인쇄된 색 견본이 나란히 실려 있습니다. 경계 하나를 알아 두면 좋습니다. 표의 행과 셀을 칠하는 \rowcolor, \cellcolor, \rowcolors 는 xcolor 가 아니라 colortbl 소관이며, \usepackage[table]{xcolor} 한 줄이면 둘 다 갖춰집니다. 자세한 내용은 색이 있는 표 페이지를 보세요.
화면의 색은 종이에 나오지 않는다: 인쇄와 접근성의 함정
상업 인쇄에 넘길 문서라면 rgb 로 적은 색이 그대로 찍혀 나오리라는 보장이 없습니다. 오프셋 인쇄는 cmyk 네 가지 잉크로만 색을 만들 수 있고, 그 재현 범위는 화면의 RGB보다 좁기 때문입니다. xcolor 에 cmyk 옵션을 주면 문서의 모든 색이 변환되어, 예를 들어 blue 는 {cmyk}{1,1,0,0} 이 됩니다. 화면에서 선명하던 파랑이 종이 위에서는 묵직한 보랏빛 남색으로 보이는 일——이런 차이는 드물지 않습니다. 넘기기 전에 \usepackage[cmyk]{xcolor} 로 한 번 조판해 교정쇄를 확인하거나, 처음부터 cmyk 로 색을 정의해 두는 편이 안전합니다.
한 걸음 더 깊은 함정은 색을 유일한 단서로 삼는 일 입니다. 빨간 행은 경고, 초록 행은 정상——이런 설계는 지면을 흑백으로 복사하는 순간, 색각 특성이 있는 독자 앞에서, 또는 전자잉크 화면에서 정보를 통째로 잃습니다. 웹 접근성 기준 WCAG가 “색의 사용”(성공 기준 1.4.1)에서 요구하는 것이 바로 이 점으로, 색은 반드시 기호・굵은 글씨・명시적 라벨 같은 다른 단서와 함께 써야 합니다. 다행히 확인 수단은 xcolor 자신이 가지고 있습니다. \usepackage[gray]{xcolor} 라고 쓰면 모든 색이 gray 모델로 변환되어(red 는 {gray}{0.3} 이 됩니다) 흑백 프린터의 출력을 그대로 시험할 수 있습니다. 그 상태에서도 뜻이 전달된다면 그 문서는 색에 지나치게 기대고 있지 않습니다.
% convert every colour in the document to cmyk, for offset printing
\usepackage[cmyk]{xcolor}
% convert every colour to gray: a one-word black-and-white proof
\usepackage[gray]{xcolor}