상대 색상 문법

Relative Color Syntax

원래 색의 포맷을 몰라도 `color(from ...)`로 그 색을 읽어 채널 일부만 바꾼 새 색을 만드는 문법.

다른 이름: color(from ...)hsl(from ...)
···
html
<div class="wrap">
  <div class="badge" id="badge"><svg viewBox="0 0 10 10"><path id="bpath" d="M1.5 5.2l2.6 2.6L8.5 2.4" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"/></svg><span id="btext">확인 중</span></div>
  <div class="row" id="row"><div class="sw base"></div><div class="sw light"></div><div class="sw dark"></div><div class="sw alpha"></div></div>
</div>
css
.wrap{position:relative;width:min(260px,92%)}
.row{display:flex;gap:8px}
.sw{flex:1;height:52px;border-radius:8px}
.base{background:var(--accent)}
.light{background:hsl(from var(--accent) h s calc(l + 22))}
.dark{background:hsl(from var(--accent) h s calc(l - 18))}
.alpha{background:color(from var(--accent) srgb r g b / 0.35)}
.row.fallback .light{background:#8f8ffa}.row.fallback .dark{background:#3d3dc4}.row.fallback .alpha{background:rgba(91,91,247,.35)}
.badge{position:absolute;top:-30px;right:0;display:flex;align-items:center;gap:5px;padding:4px 9px;border-radius:999px;font-size:10px;font-weight:700;background:var(--bg);border:1px solid var(--line);color:var(--accent-3)}
.badge.no{color:var(--accent-2)}
.badge svg{width:9px;height:9px}
js
const ok = CSS.supports('color', 'hsl(from red h s calc(l + 10))');
const b=document.getElementById('badge'),p=document.getElementById('bpath'),t=document.getElementById('btext');
b.classList.toggle('no', !ok);
p.setAttribute('d', ok ? 'M1.5 5.2l2.6 2.6L8.5 2.4' : 'M2 2l6 6M8 2l-6 6');
t.textContent = ok ? '상대 색상 문법 지원됨' : '미지원 · 정적 색 폴백';
if (!ok) document.getElementById('row').classList.add('fallback');

"이 색의 밝기만 20% 올린 버전"을 만들려면 예전에는 원래 색이 hex인지 hsl인지 rgb인지부터 알아야 했고, 디자인 토큰이 어떤 포맷으로 올지 모르는 컴포넌트 라이브러리에서는 이게 꽤 번거로웠습니다. JS 색상 라이브러리로 파싱-변환-재조합하는 게 흔한 우회였습니다.

상대 색상 문법은 `hsl(from var(--accent) h s calc(l + 20))`처럼 기존 색을 `from`으로 불러와 `h`(hue)·`s`(saturation)·`l`(lightness) 같은 채널 변수로 바로 씁니다. `color(from var(--accent) srgb r g b / 0.4)`로 투명도만 바꾸는 것도 가능해서, 원래 포맷이 무엇이든 CSS 안에서 바로 파생 색을 만들 수 있습니다.

기본 지원은 caniuse/MDN baseline을 확인하세요. 미지원 브라우저에서는 JS로 원래 색을 파싱해 채널을 바꾼 뒤 다시 문자열로 합치는 것이 대안입니다.

언제 쓰나

토큰 색의 포맷을 모른 채로 밝기·채도·투명도만 바꾼 파생 색을 만들 때.