Technote

테마 · 플러그인 심화

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

테마가 가진 토큰과 우리 토큰의 경계 — 브릿지 한 파일

요즘 테마는 자기 토큰을 수백 개 갖고 옵니다. 그것을 직접 고치면 업데이트마다 사라지고, 무시하면 화면이 두 시스템으로 갈립니다. 답은 브릿지 한 파일입니다.

요즘 상용 테마는 :root 에 자기 토큰을 수백 개 선언한 채로 옵니다. 색 · 버튼 · 헤더 · 폼이 전부 그 토큰으로 그려집니다. 여기에 우리 디자인 시스템을 얹으려 할 때 선택지는 셋처럼 보입니다.

테마 파일을 직접 고치는 방법이 있고 — 업데이트가 오면 사라집니다. 테마 토큰을 무시하고 우리 CSS 로 덮는 방법이 있고 — 규칙마다 우선순위 싸움이 생기며 화면이 두 시스템으로 갈립니다. 남은 하나가 실제로 유지되는 방법입니다.

3층으로 나눕니다

3층 토큰 구조 — 두 시스템이 만나는 지점을 파일 하나로 좁힌다

규칙은 두 줄입니다. 벤더 토큰은 편집하지 않습니다. 그리고 벤더 토큰을 우리 값으로 다시 가리키는 일은 브릿지 파일 하나에서만 합니다. 컴포넌트는 우리 토큰만 참조하고 벤더 토큰의 이름을 모릅니다.

보상은 테마 업데이트가 왔을 때 나옵니다. 감사할 파일이 전 컴포넌트가 아니라 브릿지 하나입니다. 벤더가 토큰 이름을 바꿨다면 그 파일에서만 드러나고, 나머지 코드는 손댈 필요가 없습니다.

브릿지는 대개 생각보다 짧습니다. 잘 만든 테마의 토큰은 서로 파생되기 때문입니다 — 기본 색 하나를 재지정하면 링크색 · 버튼 배경 · 포커스 링 · 텍스트 선택 영역이 함께 따라옵니다. 브릿지를 쓰기 전에 벤더 토큰의 파생 관계를 먼저 읽어 두면 재지정할 줄이 절반으로 줄어듭니다.

-rgb 짝 — 이 연재에서 가장 조용한 함정

많은 테마가 색 토큰마다 두 개를 둡니다. 하나는 색 자체(--x-color), 다른 하나는 투명도를 만들 때 쓰는 rgb 삼중값(--x-color-rgb)입니다. 후자는 이렇게 쓰입니다.

.badge {
  background: rgba(var(--x-color-rgb), 0.12);
}

--x-color 만 우리 값으로 바꾸고 -rgb 를 빠뜨리면 어떤 일이 생기는지가 이 함정의 핵심입니다. 불투명한 요소는 전부 우리 색으로 바뀌는데, 반투명한 요소만 테마 기본색으로 남습니다. 버튼 포커스 링, 오버레이, 배지 배경 같은 것들입니다.

화면의 대부분이 맞게 보이기 때문에 리뷰를 통과합니다. 그리고 프로덕션에서, 대개 남이 먼저, 발견됩니다.

원인은 CSS 문법에 있습니다. var() 로는 헥스 값을 rgb 삼중값으로 변환할 수 없습니다. 그래서 둘을 빌드 시점에 함께 생성합니다.

@use 'sass:color';

@mixin token($name, $hex) {
  --#{$name}: #{$hex};
  --#{$name}-rgb:
    #{color.channel($hex, 'red')},
    #{color.channel($hex, 'green')},
    #{color.channel($hex, 'blue')};
}

:root {
  @include token('x-color', #0e7c66);
}

믹스인 하나로 짝이 어긋날 방법이 없어집니다. 최신 CSS 의 상대 색 문법으로 런타임에 분해하는 길도 열리고 있지만, 브라우저 지원이 고르지 않은 동안에는 빌드 시점 생성이 확실합니다.

규약을 기계가 검사하게 합니다

이 구조는 사람의 주의력으로 유지되지 않습니다. 검색 세 줄이면 규약이 지켜지는지 확인할 수 있습니다 — 컴포넌트가 벤더 토큰을 직접 참조하는가, 브릿지 밖에서 벤더 토큰을 재정의하는가, 그리고 색 토큰의 개수와 -rgb 토큰의 개수가 같은가. 마지막 줄이 위 함정을 정확히 잡습니다.

테마 업데이트를 안전하게 처리하는 절차는 작업 과정에 있고, 상용 테마 위에서 이 구조를 세우는 작업은 최적화 지원 사업의 범위에 들어갑니다.

다음 회차

구조가 완성됐습니다. 마지막 회차는 이 구조를 다음 사람에게 넘기는 방법입니다 — 코드와 함께 사는 문서만 살아남습니다.

이 주제의 다른 글

노하우 목록으로

테마 · 플러그인 실무

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

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

디자이너 3분 읽기

테마 · 플러그인 입문

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

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

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

테마 · 플러그인 심화

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

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

디자이너 6분 읽기

₩270,000 · 신청하기