CSS에 살아있는 값을 주입하는 Prop For That
마우스가 어디 있는지, 스크롤이 얼마나 빠른지, 지금 몇 시인지 — CSS는 이런 ‘살아있는 값’을 혼자 알지 못한다. 늘 자바스크립트가 값을 추적해 커스텀 속성으로 넘겨줘야 했다. CSS-Tricks가 2026년 6월 16일 공개한 Geoff Graham의 글은 Adam Argyle가 만든 작은 라이브러리 ‘Prop For That’을 소개한다. 라이브러리를 불러오고 HTML에 데이터 속성 한 줄을 붙이면, 포인터 좌표·스크롤 속도·진행도·폼 상태·현재 시각이 자동으로 CSS 변수로 흘러든다.
"All that's needed is to import the library, declare it in HTML, then style away in CSS."Geoff Graham, CSS-Tricks
무슨 일인가
사용법은 단순하다. data-props-for="pointer" 같은 속성을 요소에 붙이면 라이브러리가 백그라운드에서 이벤트를 듣고 --live-pointer-x·--live-pointer-y 같은 변수를 갱신한다. 개발자는 그 변수를 calc()나 translate에 꽂아 쓰기만 하면 된다. 데모로는 포인터를 따라오는 그림자, 관성이 붙은 스크롤 효과, 색조를 미는 슬라이더 등이 제시됐다. 핵심은 값을 추적하는 ‘JS 배선’을 매번 직접 짜지 않아도 된다는 점이다.
여러 시각
같은 ‘CSS에 동적 값을 넣는다’는 흐름을 네이티브 기능과 견주면 경계가 또렷해진다.
- MDN(@property) — 표준의 관점. CSS Houdini의
@property는 커스텀 속성에syntax·inherits·initial-value를 부여해 타입을 가진 변수로 등록한다. 값의 ‘형식’은 네이티브가 책임지지만, 그 값을 무엇으로 채울지(포인터·시간)는 여전히 외부가 공급해야 한다. - MDN(스크롤 기반 애니메이션) — 네이티브의 진격.
animation-timeline: scroll()·view()는 스크롤 진행도만큼은 JS 없이 CSS가 직접 읽게 만들었다. 즉 ‘스크롤’ 값은 이미 표준이 흡수했지만 ‘포인터·현재 시각’은 아직 빈자리여서, 이 라이브러리가 그 틈을 메운다.
왜 중요한가
이 라이브러리의 진짜 메시지는 기능이 아니라 질문이다 — ‘이건 CSS가 직접 해야 할 일인가’. CSS는 매년 JS의 영역을 흡수해 왔고(스크롤 타임라인, attr(), 곧 나올 if()·sibling-index()), 그럴수록 번들은 가벼워지고 렌더링은 브라우저 최적화 경로를 탄다. 다만 포인터 추적처럼 잦은 갱신을 라이브러리에 맡기면, 보이지 않는 곳에서 매 프레임 JS가 돈다는 비용은 그대로다. 편의와 성능의 트레이드오프를 의식해야 한다.
실무 적용
- 포인터·스크롤 같은 살아있는 값을 한두 군데에서만 쓴다면, 라이브러리 대신 작은 직접 핸들러로 충분하다 — 의존성과 전역 리스너를 늘리지 않는다.
- 타입이 필요한 커스텀 속성은
@property로 등록해 애니메이션·검증을 네이티브에 맡기고, 값 공급만 외부에서 처리한다. - 스크롤 연동 효과는 먼저
animation-timeline: scroll()같은 네이티브로 가능한지 확인하고, 안 되는 값(포인터·시간)에만 JS를 얹는다.
Kenny의 관점
프론트엔드 관점에서 이런 ‘마법 같은’ 라이브러리는 늘 양날의 검이다. 코드가 짧아져 좋지만, 매 pointermove마다 변수를 갱신하는 비용은 저사양 기기에서 먼저 드러난다. 나는 ‘CSS로 표현, JS로 측정’의 경계를 명확히 긋고, 측정 비용이 큰 값은 requestAnimationFrame으로 묶거나 갱신 빈도를 떨어뜨린다. 그리고 영리함보다 ‘다음 사람이 이 변수가 어디서 오는지 5초 안에 아는가’를 우선한다. 편리한 추상은 그 출처가 투명할 때만 부채가 아니다.
출처
이 글은 아래 원문을 바탕으로 Kenny가 한국어로 요약·정리한 큐레이션입니다.
원문 보기 — CSS-Tricks ↗