CSS를 사용하여 할인된 가격을 계산하고 표시하기
요약
CSS의 최신 수학 기능과 개선된 `attr()` 함수를 사용하여 JavaScript 없이 할인된 가격을 계산하고 표시하는 방법을 소개합니다. HTML의 `data-*` 속성에 저장된 값을 숫자로 파싱하여 브라우저 자체적으로 계산을 수행함으로써 지연 시간과 리소스 소모를 줄일 수 있습니다.
핵심 포인트
- CSS의 수학 기능을 활용하면 스크립트 없이도 동적인 수치 계산이 가능함
- 개선된 `attr(<name> <type>)` 구문을 통해 HTML 속성값을 다양한 데이터 타입(number 등)으로 파싱 가능
- JavaScript를 사용하지 않음으로써 지연 시간(latency)을 제거하고 브라우저 리소스를 절약할 수 있음
- `:has()` 선택자와 결합하여 사용자 상호작용(체크박스 등)에 따른 실시간 UI 변화 구현 가능
CSS 수학(CSS math)은 단순히 요소가 어떻게 보이는지에 관한 것만이 아닙니다! 유용한 수치 정보를 계산하는 데에도 사용될 수 있습니다. 예를 들어, 할 일 목록(to-do list)에서 완료된 작업의 백분율을 CSS로 계산하여 보여줌으로써 사용자가 진행 상황을 추적할 수 있도록 도울 수 있습니다. 스크립트(script)나 서버 계산이 필요 없습니다. 지연 시간(latency)도 없습니다. 추가적인 브라우저 리소스도 사용하지 않습니다.
수학을 다루는 작업은 훨씬 더 간단하고 유연해졌습니다. 저는 기본 가격(base price)과 할인율(discount)이 제공될 때마다 CSS를 사용하여 할인된 가격을 계산하고 표시하는 예시를 보여드리려고 합니다. 이는 이커머스(e-commerce) 사이트에서 제품의 정가, 할인 금액, 그리고 할인가를 보여주기 위해 무거운 자바스크립트(JavaScript)를 사용하는 것과 유사한 작업입니다.
우리는 CSS로 이를 완벽하게 수행할 수 있습니다:
이는 아직 더 많은 브라우저 지원을 기다리고 있는 최첨단 기능(bleeding-edge features)들에 의존하긴 하지만, 우리가 궁극적으로 이러한 기능들을 어떻게 실무에 적용하고 일상적인 업무에서 사용할 수 있게 될지 깊이 파고드는 것은 여전히 좋은 연습이라고 생각합니다.
제가 이를 어떻게 구성했는지 소개합니다.
초기 마크업 (The initial markup)
이 특정 데모의 인터페이스는 사용자가 선택할 수 있는 스트리밍 서비스 목록(Netflix, Disney+, HBO, HBO Now, HBO Go, HBO Max 등)을 표시합니다. 각 구독 항목에는 정가에서 일정 비율을 차감하는 학생 할인 혜택이 있습니다.
<li>
<!-- 서비스 이름, 기본 가격, 그리고 선택 토글 -->
<label>
...
기본 가격과 할인율은 가격을 표시하는 요소의 data-* 속성(attributes)에 포함되어 있습니다. 할인은 "학생 할인 적용(Apply Student Discount)"을 선택했을 때만 적용되며, 그 후에 할인이 적용된 가격이 얼마인지 확인할 수 있다는 점을 기억하세요.
가격 인하 계산하기 (Calculating the price cut)
할인이 적용될 때, 첫 번째 단계는 기본 가격에 취소선을 그어 가격을 삭감하는 것입니다.
/* .ott 컨테이너 내부의 .is-ott-discounted가 체크되었을 때 */
.ott:has(.is-ott-discounted:checked) {
/* 원래 가격에 취소선 긋기 */
...
다음으로, data-price와 data-discount 값을 사용하여 새로운 할인된 가격을 계산해 보겠습니다.
.ott:has(.is-ott-discounted:checked) {
.ott-price {
text-decoration: line-through;
...
attr(<name> <type>) 구문은 비교적 최신 기능입니다. 이전에는 이 함수가 content 속성에서만 작동했지만, 이제는 모든 CSS 속성을 지원하며, 이전에는 항상 문자열 (strings)로 파싱되었던 값들을 다양한 데이터 타입 (data types)으로 파싱합니다.
해당 인자들(arguments):
<name>: 우리가 확인하고자 하는 HTML 속성의 이름입니다 (href,data-count, 또는title등).<type>: CSS가 값을 어떻게 "읽을지"를 알려줍니다 (color,number, 또는length등). 이것이 바로 우리가 여기서 수행하는 작업을 가능하게 만드는 새로운 강력한 기능입니다.
우리의 경우, 이 함수를 사용하여 data-price와 data-discount를 모두 numbers로 파싱한 다음, CSS의 수학적 기능 (math-iness)을 사용하여 가격에서 할인을 뺍니다.
업그레이드된 attr()은 매우 멋지지만, 이 글을 쓰는 시점에서는 아직 Baseline(브라우저 호환성 기준)에 도달하지 않았으므로 주의 깊게 살펴보시기 바랍니다.
할인된 가격 표시하기
할인이 적용되었을 때 업데이트된 가격을 표시하는 방법은 다음과 같습니다:
.ott:has(.is-ott-discounted:checked) {
.ott-price {
text-decoration: line-through;
...
counter() 함수는 --n 변수의 숫자 값을 content 문자열로 변환하는 데 도움을 줍니다. CSS 카운터 (counters)는 소수점 (decimals)을 처리할 수 없으므로 (기본적으로 값을 반올림함), 소수점 앞뒤의 숫자를 별개의 카운터로 취급한 다음, 그 사이에 점을 찍어 문자열로 결합합니다.
calc(round(down, var(--n)))는 변수--n을 가져와 내림 (round down) 하여 전체 달러 금액을 구합니다 (counter(a)에 저장).calc((mod(var(--n), 1)) * 100)는mod()함수를 사용하여 소수점 이하 부분을 분리한 다음,100을 곱하여 센트 (cents)를 구합니다 (counter(b)에 저장).content속성은 두 카운터 앞에 달러 기호를 삽입한 다음 점으로 이들을 연결합니다.
우리는 calc()가...
많은 브라우저에서 지원됩니다. 그리고 놀라운 소식은, mod() 함수가 새롭게 Baseline에 포함되었다는 점입니다!
이는 소수점 등이 필요할 때의 이야기입니다. 만약 가격을 반올림하는 것이 목적이라면, 다음만으로도 충분합니다:
counter-set: price calc(var(--n));
content: counter(price);
데모를 다시 한번 확인해 보세요:
마무리
이렇게 해서 우리는 스크립트 없이도 수많은 웹사이트에서 볼 수 있는 기능을 구현하기 위해, 최신 CSS 기능(업그레이드된 attr() 함수), CSS 수학 함수 (mod(), round()), 그리고 커스텀 카운터 (custom counters)를 조합하여 작동하는 결과물을 만들어냈습니다. 모든 브라우저에서 attr()의 데이터 타입 (data types) 지원이 이루어진다면, 이는 여러분의 일상적인 업무에서 바로 사용할 수 있는 기술이 될 것입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 CSS-Tricks의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기