Technote

테마 · 플러그인 실무

연재 워드프레스에 디자인 시스템 심기 8부 중 4부

CSS 커스텀 프로퍼티로 토큰 심기

토큰 목록을 :root 한 곳에 두고 컴포넌트가 그것만 참조하게 만들면, 사이트 전체의 색과 간격이 파일 하나에서 움직입니다.

토큰을 코드로 옮기는 방법은 여러 가지가 있지만, 워드프레스 테마에서는 CSS 커스텀 프로퍼티가 거의 언제나 정답입니다. 이유는 두 가지입니다 — 상속되고, 런타임에 바뀝니다.

전처리기 변수와 무엇이 다른가

SCSS 변수는 빌드 시점에 값으로 치환되고 사라집니다. 브라우저는 그 이름을 모릅니다. 반면 커스텀 프로퍼티는 브라우저까지 살아서 도착합니다. 그래서 특정 영역 안에서만 값을 다시 선언해 그 아래 전체를 반전시킬 수 있습니다.

:root {
  --brand: #0e7c66;
  --brand-hover: #0a5f50;
  --ink: #1f2933;
  --surface: #ffffff;
  --space-4: 16px;
  --radius-md: 8px;
}

.site-button {
  background: var(--brand);
  color: var(--surface);
  padding: var(--space-4);
  border-radius: var(--radius-md);
}

.site-button:hover {
  background: var(--brand-hover);
}

여기서 .site-button 은 브랜드색이 무엇인지 모릅니다. 알 필요도 없습니다. 리브랜딩이 오면 :root 블록만 열면 됩니다.

스코프 재선언 — 이 구조의 진짜 값

커스텀 프로퍼티는 상속되므로, 어떤 영역에서 토큰을 다시 선언하면 그 안의 모든 컴포넌트가 코드 수정 없이 따라옵니다.

.section--inverse {
  --ink: #f7f9fa;
  --surface: #121a24;
  background: var(--surface);
  color: var(--ink);
}

어두운 섹션을 만들 때 버튼 · 카드 · 배지의 규칙을 각각 다시 쓰지 않아도 됩니다. 다크 모드도 같은 원리이고, 클래스 대신 미디어 쿼리 안에서 토큰을 재선언하면 됩니다. 컴포넌트가 토큰만 참조한다는 규칙을 지킨 대가가 여기서 한꺼번에 돌아옵니다.

테마에 실제로 배치하기

토큰이 화면에 닿기까지 — 리터럴은 첫 칸에만 존재한다

파일 배치에는 규칙이 하나뿐입니다. 토큰 정의 파일 밖에서는 색과 간격 리터럴을 쓰지 않습니다. 이 규칙은 검사할 수 있다는 점에서 특히 좋습니다 — 컴포넌트 디렉터리에서 # 로 시작하는 색을 찾는 검색 한 줄이 리뷰 절차가 됩니다.

로드 순서도 정해 둡니다. 부모 테마의 스타일시트가 우리 뒤에 로드되면 우선순위 싸움이 시작되고, 그때부터는 규칙마다 강제 선언을 붙이게 됩니다. 우리 번들이 마지막이면 그 싸움 자체가 없습니다. 자식 테마에서 스타일을 등록할 때 우선순위 숫자를 부모보다 크게 두는 것으로 끝납니다.

폴백 값(var(--brand, #0e7c66))은 남용하지 않습니다. 토큰이 없을 때를 대비한 안전장치처럼 보이지만, 실제로는 리터럴이 컴포넌트로 돌아오는 통로가 되고 토큰이 빠진 사실을 숨깁니다. 토큰은 항상 정의되어 있어야 하고, 정의되지 않았다면 그것이 드러나는 편이 낫습니다.

테마 구조를 정리하는 실제 작업 순서는 작업 과정에 있고, 무료로 배포하는 점검 도구들은 무료 도구에서 받을 수 있습니다.

다음 회차

토큰이 테마에 심겼습니다. 그런데 블록 에디터는 이 토큰을 모릅니다 — 편집자의 색 선택기에는 여전히 무지개가 뜹니다. 다음 회차의 theme.json 이 그 통로를 엽니다.

이 주제의 다른 글

노하우 목록으로

테마 · 플러그인 실무

편집 가능한 영역을 디자인 전에 정합니다

CMS 가 표현할 수 없는 디자인은 배포된 뒤에도 계속 협상 대상으로 남습니다. 어디까지 편집자가 바꿀 수 있는지를 먼저 정하면 그 협상 자체가 사라집니다.

디자이너 3분 읽기

테마 · 플러그인 입문

업데이트가 멈춘 플러그인을 판별하는 기준

마지막 업데이트 날짜 하나로는 방치를 판정할 수 없습니다. 판별 신호 다섯 개를 함께 보고, 대체 불가라면 격리 조건이라도 걸어야 합니다.

기획자 · 운영 · 관리자 2분 읽기

테마 · 플러그인 심화

JS 없이 만드는 상호작용과 그것을 안전하게 하는 규칙

details · :target · :focus-within · :has() · 스크롤 타임라인으로 상당수의 상호작용이 스타일시트 안에서 끝납니다. 안전하게 만드는 규칙은 하나입니다 — 기본값이 완성된 상태여야 합니다.

디자이너 6분 읽기

₩270,000 · 신청하기