들어가며: 랜덤 UI, CSS만으로 가능할까?
웹 디자인에서 '무작위성'은 생각보다 강력한 도구입니다. 컨페티 효과, 별이 반짝이는 배경, 랜덤 컬러 그리드 등 사용자 경험을 풍부하게 만드는 요소들이죠. 그런데 이 무작위성을 CSS만으로 구현하려면 JavaScript에 의존해야 했습니다.
2025년 말, Safari가 random() 함수를 최초로 지원하면서 상황이 바뀌었습니다. 하지만 문제는 다른 브라우저에서는 아직 사용할 수 없다는 점입니다. Chrome과 Firefox도 작업 중이라는 신호는 있지만, 언제쯤 안정적으로 쓸 수 있을지는 미지수입니다.
이 글에서는 CSS random() 폴리필을 직접 구현하고, 실제 데모에 적용하는 방법을 단계별로 공유합니다. Safari 사용자가 아니더라도 랜덤 UI를 지금 바로 실무에 적용할 수 있는 실전 가이드입니다.
참고로 이 글은 근거자료를 바탕으로 재구성했습니다.

핵심: 폴리필 동작 원리와 코드
폴리필의 핵심 아이디어는 간단합니다. 브라우저가 random()을 지원하지 않으면, JavaScript로 계산해서 인라인 스타일로 주입하는 것이죠.
1. 네이티브 지원 여부 감지
if (!CSS.supports("width", "random(0px, 100px)")) {
// 폴리필 실행
}
2. --random 접두사 커스텀 프로퍼티 수집
CSS 커스텀 프로퍼티는 문법이 매우 관대합니다. 브라우저가 random()을 이해하지 못해도, 값은 문자열로 파싱되어 JavaScript에서 읽을 수 있습니다.
.star {
--random-star-size: random(1px, 7px, 1px);
width: var(--random-star-size);
}
3. JavaScript로 값 계산 및 주입
import { calc } from "@csstools/css-calc";
const calcFn = calc;
if (!CSS.supports("width", "random(0px, 100px)")) {
// 깜빡임 방지를 위해 잠시 숨김
const styleTag = document.createElement("style");
styleTag.textContent = ".randomized { display: none; }";
document.head.appendChild(styleTag);
const elementIDs = new WeakMap();
const documentID = crypto.randomUUID();
document.querySelectorAll(".randomized").forEach((element) => {
const styles = getComputedStyle(element);
[...styles]
.filter((property) => property.startsWith("--random"))
.forEach((propertyName) => {
const css = styles.getPropertyValue(propertyName);
const value = resolveRandom(css, {
element,
propertyName,
documentID,
elementIDs,
calcFn,
crypto,
});
element.style.setProperty(propertyName, value);
});
});
// 숨김 해제
if (styleTag.parentNode) {
styleTag.parentNode.removeChild(styleTag);
}
}
function resolveRandom(css, { element, propertyName, documentID, elementIDs, calcFn, crypto }) {
// base 값이 없으면 고정 랜덤값 주입 (균등 분포 보정)
const patchedCss = css.replace(
/random\(\s*(?!(?:[^,]*\b(?:shared|scoped)\b|fixed\b|--))([^,]+),/gi,
(_, expression) => `random(fixed ${Math.random()}, ${expression},`
);
return calcFn(patchedCss, {
precision: 5,
toCanonicalUnits: true,
randomCaching: {
documentID,
elementID: elementIDs.getOrInsert(element, `element-${crypto.randomUUID()}`),
propertyName,
},
});
}
4. HTML에 마커 클래스 추가
폴리필 대상 요소에 randomized 클래스를 붙여주면 끝입니다.
<div class="star randomized"></div>
이 방식의 가장 큰 장점은 네이티브 지원이 시작되면 스크립트만 제거하면 된다는 것입니다. CSS는 그대로 유지되므로 마이그레이션 부담이 거의 없습니다.

주의사항과 심화 팁
⚠️ 주의: 폴리필의 한계
- 동적 변경 미지원: 현재 구현은 페이지 로드 시점의 computed style만 처리합니다. DOM 변경이나 스타일 동적 변경에는 반응하지 않습니다.
random-item()미지원: 리스트에서 랜덤 선택하는random-item()은 아직 어떤 브라우저도 구현하지 않았습니다. (Safari 프리뷰 제외)- 스펙 변경 가능성:
random()은 아직 Editor's Draft 단계로, 주요 breaking change가 예상됩니다. 프로덕션 적용 시 주의가 필요합니다.
💡 심화: random-item() 흉내내기
Chromium의 CSS 커스텀 함수(@function)와 인라인 조건문을 조합하면 random-item()과 유사한 기능을 구현할 수 있습니다.
@function --item(--index,
--arg-1: , --arg-2: , --arg-3: , --arg-4: , --arg-5: ,
--arg-6: , --arg-7: , --arg-8: , --arg-9: , --arg-10: ) {
result: if(
style(--index: 1): var(--arg-1);
style(--index: 2): var(--arg-2);
style(--index: 3): var(--arg-3);
style(--index: 4): var(--arg-4);
style(--index: 5): var(--arg-5);
style(--index: 6): var(--arg-6);
style(--index: 7): var(--arg-7);
style(--index: 8): var(--arg-8);
style(--index: 9): var(--arg-9);
else: var(--arg-10);
);
}
.square {
--random-index: random(element-shared, 1, 5, 1);
--random-color: --item(var(--random-index), aqua, purple, pink, grey, green);
background-color: var(--random-color);
}
이 접근법은 특정 데이터 타입에 국한되지 않고, CSS 표준을 의도된 방식으로 활용한다는 점에서 해킹이 아닙니다.
🇰🇷 한국 개발 생태계에서의 적용 맥락
국내 SI 환경에서는 브라우저 호환성 요구사항이 특히 까다롭습니다. 공공기관이나 금융권 프로젝트에서는 IE 지원을 요구하는 경우도 여전히 있어, 폴리필의 존재가 실질적인 선택지를 넓혀줍니다. 다만 폴리필 자체가 JavaScript 의존성을 추가하므로, "CSS만으로 해결"이라는 원래 목표와는 약간의 괴리가 생깁니다. 성능이 중요한 랜딩 페이지보다는, 인터랙티브한 마케팅 페이지나 프로토타입 단계에서 활용하는 것이 현실적입니다.

마무리: 지금 바로 시도해볼 것
CSS random()은 분명 매력적인 기능입니다. 하지만 네이티브 지원이 baseline에 도달하기까지는 시간이 걸릴 것입니다. 폴리필은 그 공백을 메워주는 실용적인 도구입니다.
실무 적용을 위한 체크리스트:
- ✅ 랜덤 UI가 정말 필요한지 먼저 검토 (과유불급)
- ✅ 폴리필 적용 시 초기 로드 성능 영향 측정
- ✅ 네이티브 지원 시작 시 폴리필 제거 계획 수립
- ✅ 스펙 변경 가능성을 대비해 추상화 레이어 유지
다음 단계 학습 방향:
- CSS Values and Units Module Level 5 스펙 문서 정독
@function과 인라인 조건문 등 emergent CSS 기능 탐구@csstools/css-calc라이브러리 소스 코드 분석
함께 보면 좋은 글
랜덤한 UI가 필요할 때, 이제 JavaScript 없이도 충분히 elegant한 해결책이 있다는 것을 기억하세요. 즐거운 randomizing 되세요! 🎲