UI 상태 재고: CSS Range Syntax vs Class Toggling
Source: Dev.to
전통적인 패턴: JavaScript가 시각적 상태를 제어
사용자가 시작일과 종료일을 선택하는 캘린더를 상상해 보세요. 일반적인 구현은 다음과 같습니다:
days.forEach(day => {
const value = Number(day.dataset.day);
if (value >= start && value 12
이제 CSS가 Range Syntax를 사용해 비교를 수행합니다:
.day-now {
background-color: if(
style(--day-start <= --day <= --day-end): #8b0000;
else: rgba(255, 255, 255, 0.05);
);
}
반복문도, 클래스 토글도, DOM 변형도 없습니다. JavaScript는 상태를 업데이트하고; CSS는 프레젠테이션을 평가합니다.
실시간 데모 (CSS Range Syntax)
이 버전에서는 JavaScript가 --day-start와 --day-end만 업데이트합니다. CSS가 범위 조건을 직접 평가합니다. Chrome 142+(실험적 지원)가 필요합니다. JS 패널에서 start와 end 값을 바꿔보고 UI가 어떻게 반응하는지 확인해 보세요.
왜 이것이 아키텍처적으로 흥미로운가
JavaScript
- 상호작용을 처리
- 상태 값을 업데이트
CSS
- 시각적 조건을 평가
- 상태에 따라 렌더링
무언가가 어떻게 보이는지를 결정하는 로직이 제자리를 찾습니다 – 바로 CSS에 있습니다.
DOM 리팩터링이 덜 깨지기 쉬워짐
전통적인 접근 방식에서는 JS가 다음과 같은 선택자에 의존할 수 있습니다:
document.querySelectorAll('.calendar .row .day');
DOM 구조를 재구성하면 해당 로직이 깨질 수 있습니다. CSS‑주도 모델에서는 JS가 구조에 신경 쓰지 않고 --day-start와 --day-end만 설정합니다. 각 날짜가 --day를 노출하기만 하면 스타일링이 동작하므로 구조적 결합도가 낮아집니다.
브라우저 지원 – 그리고 실용적인 폴백
Range Syntax는 아직 초기 단계이며 안정적인 브라우저에서 완전하게 지원되지 않습니다. 그러나 아키텍처 패턴 자체는 그것에 의존하지 않습니다. 오늘은 clamp()와 사용자 정의 속성을 이용해 비슷한 로직을 흉내낼 수 있습니다:
.day-now {
--gte-start: clamp(0, calc(var(--day) - var(--day-start) + 1), 1);
--lte-end: clamp(0, calc(var(--day-end) - var(--day) + 1), 1);
--in-range: calc(var(--gte-start) * var(--lte-end));
background-image: linear-gradient(
rgba(139, 0, 0, var(--in-range)),
rgba(139, 0, 0, var(--in-range))
);
}
무슨 일이 일어나고 있나요
- 0 이하 값은
0으로, 1 초과 값은1로 클램프됩니다. - 곱셈은 논리적 AND를 시뮬레이션합니다.
- 결과가 투명도를 제어합니다.
이 폴백은 Range Syntax보다 더 장황하지만 현재는 완전히 작동합니다. Range Syntax는 주로 가독성을 높여줍니다.
실시간 데모 (Clamp 폴백)
동일한 아키텍처 패턴을 오늘 clamp()를 사용해 구현했습니다. JavaScript는 여전히 상태 값만 업데이트합니다.
트레이드‑오프와 제약
이 패턴이 언제나 더 좋은 것은 아닙니다. 다음을 고려하세요:
- 가독성 – 일부 팀은 클래스 토글이 CSS 연산보다 더 명확하다고 생각할 수 있습니다.
- 디버깅 – 조건 로직이 CSS 안에 있으면 명령형 흐름에 익숙한 개발자에게는 낯설 수 있습니다.
- 대규모 상태 – UI 상태가 깊게 얽히거나 복잡해지면 JavaScript가 여전히 더 나은 조정 레이어가 될 수 있습니다.
핵심은 “JS를 CSS로 대체한다”가 아니라 어떤 레이어가 무엇을 담당할지 재정의한다는 점입니다.
더 넓은 방향
사용자 정의 속성, 컨테이너 쿼리, :has(), 스크롤‑구동 애니메이션, 고급 attr() 등 CSS는 점점 더 표현력을 얻고 있습니다. Range Syntax는 그 흐름에 맞춰 등장한 기능입니다. JavaScript를 완전히 없애지는 않지만, 시각적 상태 관리를 위해 JavaScript를 필요로 하는 빈도를 줄여줍니다. 그리고 그것은 재고해 볼 가치가 있습니다.