그라데이션 하나 스르륵 바뀌게 하려고, 자바스크립트가 1초에 예순 번 색을 계산해 덮어쓴다 — 색과 각도에 '타입'을 달아 CSS가 스스로 사이를 채우게 하는 @property의 시대

그라데이션 하나 스르륵 바뀌게 하려고, 자바스크립트가 1초에 예순 번 색을 계산해 덮어쓴다 — 색과 각도에 '타입'을 달아 CSS가 스스로 사이를 채우게 하는 @property의 시대
CSS 변수에 타입을 등록해 색과 그라데이션이 부드럽게 변화하는 @property 개념 일러스트

CSS 변수는 브라우저에게 그냥 '글자'였다

요즘 웹사이트는 색을 --brand: #14b8a6 같은 CSS 변수에 담아 쓴다. 편하다. 그런데 이 변수에는 오래된 한계가 하나 있었다. 브라우저는 그 값을 색으로 이해하지 않고, 그저 글자 뭉치로 받아 적었다. 그래서 변수 값을 A에서 B로 바꿔도 브라우저는 중간을 채울 줄 몰랐다. 색이 서서히 번지는 대신 툭 하고 갈아 끼워졌다.

그 결과가 우리가 흔히 보던 풍경이다. 버튼에 그라데이션을 부드럽게 입히거나 테두리 빛이 천천히 도는 효과를 넣으려면, 자바스크립트가 1초에 수십 번 색을 계산해 스타일을 덮어썼다. 장식 하나에 코드 한 뭉치와 배터리가 따라붙었다.

@property는 변수에 '신분증'을 달아 준다

@property는 브라우저에게 이렇게 알려 주는 문법이다. "이 변수는 글자가 아니라 이다", "이건 각도다", "이건 길이다." 타입을 등록하는 순간 브라우저는 값과 값 사이를 스스로 계산할 수 있게 된다.

등록에는 세 가지만 적으면 된다. 어떤 타입인지(syntax), 자식에게 물려줄지(inherits), 값이 없을 때 무엇으로 볼지(initial-value). 이 세 줄을 적어 두면 그때부터 그 변수는 transition과 animation의 대상이 된다. 그라데이션이 흐르고, 각도가 돌고, 숫자가 올라간다. 자바스크립트는 손을 뗀다.

작은 회사 웹사이트에서 달라지는 세 장면

개발자용 문법처럼 보이지만, 정작 효과가 드러나는 곳은 손님이 매일 보는 화면이다.

  • 문의 버튼: 마우스를 올리면 그라데이션이 툭 바뀌는 대신 0.3초에 걸쳐 부드럽게 번진다. 같은 버튼인데 '손이 간 티가 나는' 화면이 된다.
  • 강조 카드 테두리: 추천 상품이나 대표 서비스 카드의 테두리 빛이 천천히 한 바퀴 돈다. 각도 변수 하나에 타입을 달아 준 것이 전부다.
  • 숫자 카운트: '시공 1,200건', '재방문율 87%' 같은 숫자가 0에서부터 올라가는 연출도 숫자 타입 변수로 처리할 수 있다. 예전엔 이 하나 때문에 라이브러리를 하나 더 얹었다.

도입 전에 짚어야 할 세 가지

첫째, 폴백을 먼저 그린다. 지원하지 않는 브라우저에서는 애니메이션만 빠지고 최종 색·최종 배치는 그대로 보이도록 짜야 한다. 움직임은 덤이지 본체가 아니다.

둘째, initial-value를 반드시 채운다. 이 값이 비면 브라우저가 중간값을 계산할 기준을 잃어 애니메이션이 조용히 죽는다. 실무에서 가장 흔한 실수가 여기서 난다.

셋째, 움직임을 줄이고 싶은 손님을 존중한다. 기기 설정에서 화면 움직임 최소화를 켠 사용자에게는 회전과 번짐을 꺼 주는 것이 맞다. 어지럼증을 느끼는 사람에게 장식은 방해가 된다.

기술이 아니라 인상의 문제다

손님은 "이 사이트가 @property를 썼구나"라고 생각하지 않는다. 다만 버튼 하나가 부드럽게 반응하는 화면에서 '여기는 대충 만든 곳이 아니구나'를 읽는다. 반대로 색이 툭툭 끊기는 화면에서는 이유를 설명하지 못한 채 어딘가 허술하다고 느낀다. 신뢰는 그런 0.3초에 쌓인다.

중요한 건 효과를 많이 넣는 것이 아니라, 꼭 필요한 한두 곳에만 쓰고 나머지는 조용히 두는 판단이다. CYAN은 웹사이트를 만들 때 이런 최신 CSS 문법을 '멋 부리기'가 아니라 자바스크립트를 덜어 내 화면을 가볍게 만드는 수단으로 쓴다. 코드가 줄면 페이지가 빨라지고, 빨라진 화면은 결국 손님이 떠나지 않는 이유가 된다.