CSS architecture, utility frameworks, and animation performance Compiled for immediate developer deployment.
calendar_todaysummarizeWeek 12-2026
article
CSS의 대확장
TAG: CSS 플랫폼
새로운 CSS 기능들이 압축 기준 총 322 kB 이상의 JavaScript 라이브러리를 대체하고 있습니다. CSS Anchor Positioning은 anchor-name과 position-try 폴백을 통해 브라우저가 직접 툴팁 위치를 처리하게 하여 Floating UI와 Popper.js를 대체합니다. Popover API는 라이트 디스미스 오버레이에서 Radix와 Headless UI를 대체하며, 네이티브 dialog 요소는 포커스 트랩 모달을 처리합니다. animation-timeline: scroll() 및 view()를 사용하는 스크롤 기반 애니메이션은 컴포지터 스레드에서 실행되어 GSAP ScrollTrigger를 대체합니다. View Transitions, appearance: base-select를 활용한 커스터마이즈 가능한 select, CSS scroll-state 쿼리, field-sizing: content, 그리고 곧 출시될 if() 함수까지, 이 모든 기능들이 일반적인 SPA에서 44~146 kB의 JavaScript를 절감할 수 있는 플랫폼 전환을 이끌고 있습니다.
기존에 색상 값에만 적용되던 CSS light-dark() 함수가 이미지 값도 지원하도록 확장되고 있습니다. 이제 배경 이미지, 마스크, 로고를 다크 모드에서 교체하기 위해 @media (prefers-color-scheme: dark) 블록을 작성할 필요가 없습니다. background-image: light-dark(url(light.png), url(dark.png)) 선언 하나로 로컬 color-scheme 오버라이드도 존중하며 처리할 수 있습니다. Chrome 150과 Firefox 150에서 지원이 추가되었으며, Safari는 아직 미지원 상태입니다. @supports (background-image: light-dark(none, none))를 통해 기능 감지가 가능합니다. 인수는 두 개의 색상 또는 두 개의 이미지여야 하며, CSS 파서의 파싱 시점 타입 해석 방식 때문에 혼용은 허용되지 않습니다.
기존의 스켈레톤 화면 구현은 실제 컴포넌트마다 별도의 미러 컴포넌트를 수작업으로 제작해야 했으며, 하드코딩된 너비, 높이, border-radius는 실제 레이아웃이 변경될 때마다 깨지는 문제가 있었습니다. 이 글에서는 DOM 측정 방식의 구현을 단계별로 설명합니다. 모킹 데이터로 실제 컴포넌트를 렌더링하고, opacity나 visibility 대신 color: transparent로 텍스트를 숨긴 뒤, getBoundingClientRect()를 사용하여 img, h1-h6, p, span, button 등 각 리프 요소를 컨테이너 기준으로 측정합니다. getComputedStyle()로 각 요소의 border-radius를 캡처하고, 텍스트 요소에는 4px 폴백을 적용합니다. background-size: 200%를 사용하는 CSS @keyframes shimmer 애니메이션이 절대 위치 블록 위로 반투명 그라디언트를 흐르게 합니다. React에서는 useLayoutEffect가 브라우저 페인트 전에 동기적으로 측정을 실행하여 투명 콘텐츠의 깜빡임을 방지합니다.
CSS contrast-color() 함수는 유효한 색상 값을 입력받아 해당 색상 대비 더 높은 대비율을 제공하는 black 또는 white를 반환합니다. 이를 통해 디자인 시스템에서 수동 WCAG 대비율 확인, JavaScript 계산, 변형별 텍스트 색상 선언이 불필요해집니다. 브라우저의 알고리즘은 일반 텍스트 기준 WCAG AA의 4.5:1 최소 기준을 충족해야 하며, 동률일 경우 white가 반환됩니다. 이 함수는 CSS Color Level 6에서 개발 중이던 더 풍부한 기능의 color-contrast()를 단순화한 MVP로, Level 5에 contrast-color()라는 이름으로 이식되었습니다. 현재는 임의의 후보 색상이 아닌 black 또는 white만 반환합니다. color-mix() 및 style 쿼리와 자연스럽게 결합하여 틴티드 대비 변형을 생성할 수 있습니다.
toastOptions에서 unstyled: true 모드를 설정하면 Sonner의 모든 기본 스타일이 제거되어 개발자가 전체 제어권을 갖게 됩니다. 각 토스트는 li 요소이며, div[data-icon], div[data-content], button[data-cancel], button[data-action]이 직접 형제로 나란히 위치하는 평면적 DOM 구조를 이해하는 것이 올바른 flex 레이아웃 구현에 핵심입니다. 변형별 스타일링은 classNames 키인 success, error, info를 사용하며, 기본 border 단축 속성을 재정의하려면 border-l-*에 !important가 필요합니다. 로딩 상태는 특별한 처리가 필요합니다. .sonner-loader는 기본적으로 position: absolute로 설정되어 있어 static으로 재설정해야 합니다. 애니메이션 속도는 --toast-animation-duration CSS 커스텀 프로퍼티로 제어하며, 인라인 transition 스타일을 재정의할 때는 !important가 필요합니다. data-type, data-expanded, data-front, data-visible 등의 데이터 속성을 통해 JavaScript 없이 세밀한 CSS 타겟팅이 가능합니다.
BMP와 TIFF(파일 크기가 크고 웹 활용이 제한적이어서 D/C 티어)부터 GIF(256색 제한, 투명도 미흡, 큰 파일 크기로 D 티어), PNG(무손실, 완전한 알파 채널, 그러나 파일 크기가 커서 C 티어)까지 웹 이미지 형식을 순위별로 비교합니다. JPEG는 8x8 블록의 손실 압축을 적용하여 BMP 대비 약 25배의 크기를 줄이면서도 눈에 띄는 화질 저하는 거의 없지만, 현대적인 대안들 때문에 C 티어에 머뭅니다. 2010년 Google이 출시한 WebP는 동일 화질에서 JPEG보다 뛰어난 압축률을 제공하며 투명도와 애니메이션을 지원합니다. 동일한 PNG 대비 최대 10배 더 작은 용량을 달성할 수 있습니다. AV1 코덱 기반의 AVIF(S 티어)는 WebP보다 20-30% 더 나은 압축률을 제공하고, 광색역 및 HDR 지원을 추가했으며 브라우저 지원율이 96%에 달합니다. AVIF를 기본으로 사용하고 WebP를 폴백으로 사용하는 전략을 권장합니다.
Kevin Powell은 CSS @keyframes를 더 간결하게 작성하기 위한 두 가지 실용적인 팁을 소개합니다. 첫 번째로, 동일한 키프레임 정지점(예: 25%, 75%)을 쉼표로 구분하면 중복 선언이 제거되고 값 하나만 수정해도 두 정지점이 동시에 업데이트됩니다. 두 번째로, 필요하지 않을 때 from(0%)과 to(100%) 키프레임을 생략하면, lean-left 또는 lean-right 클래스로 이미 transform이 적용된 요소에서 발생하는 애니메이션 시작 시 버벅임을 방지할 수 있습니다. CSS 개별 속성인 rotate와 translate를 transform과 함께 결합하면 독립적인 회전 및 이동 애니메이션이 충돌 없이 겹쳐져, 각 요소가 원점으로 되돌아가는 대신 자신의 시작 위치에서 애니메이션을 실행할 수 있습니다.
새로운 CSS 기능들이 압축 기준 총 322 kB 이상의 JavaScript 라이브러리를 대체하고 있습니다. CSS Anchor Positioning은 anchor-name과 position-try 폴백을 통해 브라우저가 직접 툴팁 위치를 처리하게 하여 Floating UI와 Popper.js를 대체합니다. Popover API는 라이트 디스미스 오버레이에서 Radix와 Headless UI를 대체하며, 네이티브 dialog 요소는 포커스 트랩 모달을 처리합니다. animation-timeline: scroll() 및 view()를 사용하는 스크롤 기반 애니메이션은 컴포지터 스레드에서 실행되어 GSAP ScrollTrigger를 대체합니다. View Transitions, appearance: base-select를 활용한 커스터마이즈 가능한 select, CSS scroll-state 쿼리, field-sizing: content, 그리고 곧 출시될 if() 함수까지, 이 모든 기능들이 일반적인 SPA에서 44~146 kB의 JavaScript를 절감할 수 있는 플랫폼 전환을 이끌고 있습니다.
BMP와 TIFF(파일 크기가 크고 웹 활용이 제한적이어서 D/C 티어)부터 GIF(256색 제한, 투명도 미흡, 큰 파일 크기로 D 티어), PNG(무손실, 완전한 알파 채널, 그러나 파일 크기가 커서 C 티어)까지 웹 이미지 형식을 순위별로 비교합니다. JPEG는 8x8 블록의 손실 압축을 적용하여 BMP 대비 약 25배의 크기를 줄이면서도 눈에 띄는 화질 저하는 거의 없지만, 현대적인 대안들 때문에 C 티어에 머뭅니다. 2010년 Google이 출시한 WebP는 동일 화질에서 JPEG보다 뛰어난 압축률을 제공하며 투명도와 애니메이션을 지원합니다. 동일한 PNG 대비 최대 10배 더 작은 용량을 달성할 수 있습니다. AV1 코덱 기반의 AVIF(S 티어)는 WebP보다 20-30% 더 나은 압축률을 제공하고, 광색역 및 HDR 지원을 추가했으며 브라우저 지원율이 96%에 달합니다. AVIF를 기본으로 사용하고 WebP를 폴백으로 사용하는 전략을 권장합니다.
Kevin Powell은 CSS @keyframes를 더 간결하게 작성하기 위한 두 가지 실용적인 팁을 소개합니다. 첫 번째로, 동일한 키프레임 정지점(예: 25%, 75%)을 쉼표로 구분하면 중복 선언이 제거되고 값 하나만 수정해도 두 정지점이 동시에 업데이트됩니다. 두 번째로, 필요하지 않을 때 from(0%)과 to(100%) 키프레임을 생략하면, lean-left 또는 lean-right 클래스로 이미 transform이 적용된 요소에서 발생하는 애니메이션 시작 시 버벅임을 방지할 수 있습니다. CSS 개별 속성인 rotate와 translate를 transform과 함께 결합하면 독립적인 회전 및 이동 애니메이션이 충돌 없이 겹쳐져, 각 요소가 원점으로 되돌아가는 대신 자신의 시작 위치에서 애니메이션을 실행할 수 있습니다.
기존에 색상 값에만 적용되던 CSS light-dark() 함수가 이미지 값도 지원하도록 확장되고 있습니다. 이제 배경 이미지, 마스크, 로고를 다크 모드에서 교체하기 위해 @media (prefers-color-scheme: dark) 블록을 작성할 필요가 없습니다. background-image: light-dark(url(light.png), url(dark.png)) 선언 하나로 로컬 color-scheme 오버라이드도 존중하며 처리할 수 있습니다. Chrome 150과 Firefox 150에서 지원이 추가되었으며, Safari는 아직 미지원 상태입니다. @supports (background-image: light-dark(none, none))를 통해 기능 감지가 가능합니다. 인수는 두 개의 색상 또는 두 개의 이미지여야 하며, CSS 파서의 파싱 시점 타입 해석 방식 때문에 혼용은 허용되지 않습니다.
기존의 스켈레톤 화면 구현은 실제 컴포넌트마다 별도의 미러 컴포넌트를 수작업으로 제작해야 했으며, 하드코딩된 너비, 높이, border-radius는 실제 레이아웃이 변경될 때마다 깨지는 문제가 있었습니다. 이 글에서는 DOM 측정 방식의 구현을 단계별로 설명합니다. 모킹 데이터로 실제 컴포넌트를 렌더링하고, opacity나 visibility 대신 color: transparent로 텍스트를 숨긴 뒤, getBoundingClientRect()를 사용하여 img, h1-h6, p, span, button 등 각 리프 요소를 컨테이너 기준으로 측정합니다. getComputedStyle()로 각 요소의 border-radius를 캡처하고, 텍스트 요소에는 4px 폴백을 적용합니다. background-size: 200%를 사용하는 CSS @keyframes shimmer 애니메이션이 절대 위치 블록 위로 반투명 그라디언트를 흐르게 합니다. React에서는 useLayoutEffect가 브라우저 페인트 전에 동기적으로 측정을 실행하여 투명 콘텐츠의 깜빡임을 방지합니다.
CSS contrast-color() 함수는 유효한 색상 값을 입력받아 해당 색상 대비 더 높은 대비율을 제공하는 black 또는 white를 반환합니다. 이를 통해 디자인 시스템에서 수동 WCAG 대비율 확인, JavaScript 계산, 변형별 텍스트 색상 선언이 불필요해집니다. 브라우저의 알고리즘은 일반 텍스트 기준 WCAG AA의 4.5:1 최소 기준을 충족해야 하며, 동률일 경우 white가 반환됩니다. 이 함수는 CSS Color Level 6에서 개발 중이던 더 풍부한 기능의 color-contrast()를 단순화한 MVP로, Level 5에 contrast-color()라는 이름으로 이식되었습니다. 현재는 임의의 후보 색상이 아닌 black 또는 white만 반환합니다. color-mix() 및 style 쿼리와 자연스럽게 결합하여 틴티드 대비 변형을 생성할 수 있습니다.
toastOptions에서 unstyled: true 모드를 설정하면 Sonner의 모든 기본 스타일이 제거되어 개발자가 전체 제어권을 갖게 됩니다. 각 토스트는 li 요소이며, div[data-icon], div[data-content], button[data-cancel], button[data-action]이 직접 형제로 나란히 위치하는 평면적 DOM 구조를 이해하는 것이 올바른 flex 레이아웃 구현에 핵심입니다. 변형별 스타일링은 classNames 키인 success, error, info를 사용하며, 기본 border 단축 속성을 재정의하려면 border-l-*에 !important가 필요합니다. 로딩 상태는 특별한 처리가 필요합니다. .sonner-loader는 기본적으로 position: absolute로 설정되어 있어 static으로 재설정해야 합니다. 애니메이션 속도는 --toast-animation-duration CSS 커스텀 프로퍼티로 제어하며, 인라인 transition 스타일을 재정의할 때는 !important가 필요합니다. data-type, data-expanded, data-front, data-visible 등의 데이터 속성을 통해 JavaScript 없이 세밀한 CSS 타겟팅이 가능합니다.
12주차는 네이티브 CSS가 무거운 JavaScript 라이브러리의 필요성을 점차 대체하고 있다는 강력한 근거를 제시했습니다. GitButler의 "The Great CSS Expansion"은 CSS Anchor Positioning이 Floating UI와 Popper.js를, Popover API와 네이티브 dialog가 Radix/Headless UI를, animation-timeline: scroll() 및 view()를 사용하는 Scroll-Driven Animations가 GSAP ScrollTrigger를 대체하면서 일반 SPA에서 44~146 kB의 JavaScript를 절감할 수 있음을 정리했습니다. 두 가지 새로운 컬러 함수도 플랫폼 역량을 확장합니다. light-dark()는 색상 값을 넘어 이미지 값까지 지원하도록 확장되어(Chrome 150, Firefox 150) 로고나 배경 교체를 위한 @media prefers-color-scheme 블록이 불필요해지며, contrast-color()는 임의의 입력 색상 대비 더 높은 대비율의 black 또는 white를 자동으로 반환해 디자인 시스템에서 수동 WCAG 대비율 확인을 제거합니다.
실용적인 측면에서는 shimmer 스켈레톤 화면에 대한 심층 분석이 getBoundingClientRect()와 getComputedStyle()을 사용하는 DOM 측정 방식을 소개했습니다. 수작업 미러 컴포넌트 없이 항상 최신 상태를 유지하는 스켈레톤을 생성하고, React의 useLayoutEffect로 페인트 깜빡임을 방지합니다. Sonner 토스트 커스터마이징은 unstyled: true를 통해 탐구되었으며, data-type, data-expanded 등의 데이터 속성이 핵심 타겟팅 메커니즘임이 밝혀졌습니다. Kevin Powell은 쉼표로 구분된 keyframe 정지점과 사전 변환된 요소에서 버벅임을 방지하기 위한 불필요한 from/to 키프레임 생략 등 @keyframes 명확화 팁을 공유했습니다. 이미지 포맷 가이드는 AVIF(S 티어, WebP 대비 20~30% 더 나은 압축률, 96% 브라우저 지원)를 WebP 폴백과 함께 권장 웹 이미지 전략으로 선정했습니다.
Key Takeaways
CSS Anchor Positioning, Popover API, 네이티브 dialog, Scroll-Driven Animations를 조합하면 일반 SPA에서 Floating UI, Popper.js, Radix, GSAP ScrollTrigger 등 압축 기준 322 kB 이상의 JavaScript 라이브러리를 제거할 수 있습니다.
light-dark()는 Chrome 150과 Firefox 150에서 이미지 값을 지원하고, contrast-color()는 WCAG AA 기준에 부합하는 black 또는 white를 자동 반환하여 두 기능 모두 디자인 시스템에서 JavaScript 의존성을 줄여줍니다.
AVIF는 현재 권장 웹 이미지 포맷(WebP 대비 20~30% 더 나은 압축률, 96% 브라우저 지원)이며, WebP를 폴백으로 사용하는 것이 최선의 전략입니다.