TL;DR
- CSS
progress()는 값이 시작점과 끝점 사이에서 차지하는 위치를 0~1 범위로 반환하며, 미지원 브라우저에서는 값 유형과 단위에 맞춰 대체 계산식을 구성함. - 단위 없는 숫자에는
clamp()와calc()로(현재값 - 시작값) / (끝값 - 시작값)을 직접 계산함. - 같은 단위를 사용하는 값에는
tan(atan2())트릭을 적용할 수 있으며, 별도의 사용자 지정 속성 등록이 필요하지 않음. - 단위가 섞이면
@property로 값을<length>로 등록해 픽셀로 계산되게 하며, 여러 비픽셀 단위에서는 오프셋과 범위를 각각 등록함. progress()의 클램프되지 않은 동작을 흉내 내려면clamp()를 제거하며, 네이티브 지원이 보편화되기 전까지 단위에 맞는 대체 방식을 선택함.
`progress()` 계산 원리
- CSS의 새
progress()함수는 값이 시작 경계와 끝 경계 사이에서 어디에 놓이는지 계산해 단위 없는 0~1 사이의 숫자를 반환함. - 브라우저 지원이 확대되기를 기다리는 동안 계산을 직접 구현할 수 있으며, 기본 계산식은
(현재값 - 시작값) / (끝값 - 시작값)임. - 이 계산은 정규화(normalization)라고도 하며, 사용할 값의 유형에 따라 간단한
calc()부터 더 복잡한 CSS 기법까지 적용 방식이 달라짐.
단위 없는 숫자
- 값이 모두 단위 없는 숫자라면
calc()에 계산식을 직접 넣을 수 있으며,progress()의 기본 동작과 맞추려면clamp()를 사용함. - 예를 들어 50이 10과 100 사이에서 차지하는 위치는
clamp(0, (50 - 10) / (100 - 10), 1)로 계산함.
단위가 있는 값
- 결과는 단위 없는 값으로 유지하면서
px,rem,vw같은 단위를 사용하려면 형식이 지정된 산술(typed arithmetic)을 지원하는 브라우저에서 다음 계산이 동일한 결과를 내야 함. clamp(0, (100vw - 20rem)/(100rem - 20rem), 1)progress(100vw, 20rem, 100rem)- 이 방식은 아직 모든 브라우저에서 지원되지 않으며, 특히 Firefox에서 호환성 문제가 있음.
atan2(y, x)는 두 값을 나누는 계산을 이미 수행하므로progress()계산의 오프셋(값 - 시작점)을 첫 번째 인수로, 범위(끝점 - 시작점)를 두 번째 인수로 전달할 수 있음.- 모든 값의 단위가 같다면 단위를 바꾸지 않고 바로 적용할 수 있음. 예를 들어
tan(atan2(500px - 320px, 1200px - 320px))로 계산함.
단위 혼합
- 실제로는 단위가 일치하지 않는 경우가 많으며,
atan2()가 혼합 단위를 처리하는 브라우저도 있지만 브라우저 간 호환성을 확보하려면 추가 처리가 필요함. - 유동형 타이포그래피에서는 뷰포트 너비
100vw를 하한과 상한인320px,1200px과 비교해 진행 값을 계산함. vw와px를 함께 사용하므로, 모든 브라우저에서 계산이 가능하도록100vw를 픽셀로 변환해야 함.- 뷰포트 너비를 초기값이
100vw인<length>사용자 지정 속성으로 등록하면 브라우저가100vw를 이에 해당하는 픽셀 값으로 해석함. - 이렇게 하면
atan2()에 전달되는 모든 값의 단위가 같아지며, 계산식은clamp(0, tan(atan2(var(--vw) - 320px, 1200px - 320px)), 1)이 됨.
견고한 방식
- 경계값에
rem을 사용하려는 경우<length>로 등록한 사용자 지정 속성은 픽셀로 해석되므로,rem단위로 해석되도록 지정할 수 없음. - 단위 혼합을 피하려면 각 값을 모두 픽셀로 해석되게 등록할 수 있지만, 값·시작점·끝점을 각각 등록할 필요는 없음.
atan2()에 전달되는 두 값인 오프셋과 범위만 사용자 지정 속성으로 만들고@property에<length>로 등록하면 됨.- 예를 들어 오프셋은
calc(100vw - 20rem), 범위는calc(80rem - 20rem)으로 설정하고,clamp(0, tan(atan2(var(--offset), var(--span))), 1)로 계산함. - 이 방식은
progress()와 같은 계산을 제공하면서 브라우저 지원 범위를 넓힘. progress()의 클램프되지 않은 버전을 흉내 내려면clamp()를 제거함.
어떤 방식을 선택할까?
- 단위 없는 숫자만 사용한다면
calc()또는clamp()로 값을 직접 계산함. - 단위가 있는 값을 사용한다면
tan(atan2())트릭을 적용함. - 값의 단위가 하나뿐이라면 사용자 지정 속성을 등록할 필요가 없음.
- 픽셀과 비픽셀 단위 하나를 함께 사용한다면 비픽셀 값을
<length>로 등록함. 이는 유동형 타이포그래피에서 가장 흔한 경우임. - 여러 비픽셀 단위를 함께 사용한다면 오프셋과 범위를 사용자 지정 속성으로 만들고, 둘 다
<length>로 등록한 뒤atan2()에 전달함. progress()는 이미 최신 브라우저에서 사용할 수 있으며, 걱정 없이 네이티브로 쓰기까지 오래 걸리지 않을 전망임. 그때까지는 상황에 맞는 가장 단순한 대체 방식을 선택할 수 있음.
댓글 (0)
로그인하면 이 기사에 내 생각을 남길 수 있어요