필사 모드: 웹 표준 & CSS 2026 — Container Queries / View Transitions / Popover / Anchor Positioning / Scroll-driven Animations 심층 가이드
한국어1장 · 2026년 웹 플랫폼 — 마침내 도착한 표준들
10년 전, 우리는 "곧 표준이 될 것"이라고 말하며 폴리필을 깔았다. 2026년, 우리는 **표준이 곧 일상**이 된 시대에 산다.
지금 이 순간, Chrome 130+, Safari 18+, Firefox 130+가 모두 다음을 안정 지원한다.
- **Container Queries** — 컴포넌트 시대의 미디어 쿼리
- **View Transitions API** — 단일 페이지 버전(2023) + 크로스-도큐먼트(2024)
- **Popover API** — 네이티브 모달 (2024년 전 브라우저 안정화)
- **Anchor Positioning** — Chrome 125(2024.4), Safari/Firefox 2025
- **Scroll-driven Animations** — Chrome 115(2023.7), Safari/Firefox 2025
- **CSS Nesting** — 2023년 안정화
- **:has() 선택자** — 보편 지원
- **color-mix() / light-dark()** — 보편 지원
- **@scope / @layer** — Chrome/Safari/Firefox 모두 지원
- **Subgrid** — Chrome 117, Safari 16, Firefox 71 (보편 지원)
- **Speculation Rules API** — 미래 페이지 prerender
- **WebGPU / WebTransport** — 안정화
"오늘 새 프로젝트를 시작한다면 무엇을 써야 할까?"에 대한 답이 마침내 단순해졌다. **표준을 그대로 쓰면 된다.** 이 글은 그 새로운 기본기를 한 장씩 짚는다.
> 이 글의 코드는 한 줄도 폴리필이 필요하지 않다. 2026년 evergreen 브라우저의 최신 안정 버전을 기준으로 작성했다.
2장 · Container Queries — 컴포넌트 시대의 미디어 쿼리
왜 미디어 쿼리는 부족한가
미디어 쿼리는 **뷰포트 기준**이다. 그러나 컴포넌트는 사이드바, 모달, 카드 그리드, 사이드패널 안에서 살아간다. 같은 카드 컴포넌트가 사이드바에 들어가면 좁아지고, 메인 영역에 들어가면 넓어진다. 뷰포트 폭은 똑같다. 컨테이너 폭만 다르다.
.card-container {
container-type: inline-size;
container-name: card;
}
@container card (min-width: 400px) {
.card {
display: grid;
grid-template-columns: 1fr 2fr;
gap: 1.5rem;
}
}
@container card (max-width: 399px) {
.card {
display: flex;
flex-direction: column;
}
}
container-type 세 가지
| 값 | 의미 |
| --- | --- |
| `inline-size` | 가로 폭만 쿼리 가능 (가장 흔함) |
| `size` | 가로/세로 모두 쿼리 가능 (성능 비용 큼) |
| `normal` | 컨테이너 아님 (기본값) |
`size`는 자식의 높이가 부모에 영향을 줄 수 없도록 차단해야 해서 비용이 크다. 99%의 경우 `inline-size`로 충분하다.
Container Query Units
.hero-title {
font-size: clamp(1.5rem, 5cqi, 3rem);
}
`cqi`(container query inline-size), `cqb`(block-size), `cqw`, `cqh`, `cqmin`, `cqmax`. 뷰포트 단위 `vw`/`vh`의 컨테이너 버전이다.
실전 패턴
.product-grid {
container-type: inline-size;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(min(280px, 100%), 1fr));
gap: 1rem;
}
@container (min-width: 900px) {
.product-card .image {
aspect-ratio: 4 / 3;
}
}
@container (max-width: 600px) {
.product-card .price {
font-size: 0.875rem;
}
}
같은 카드가 모달, 사이드바, 메인에 들어가도 자기 컨테이너 폭에 맞춰 자동 적응한다. **컴포넌트가 진짜 컴포넌트가 된다.**
3장 · View Transitions API — 단일 페이지 → 크로스-도큐먼트 (2024)
Same-document 버전 (2023)
상태가 바뀔 때 자동으로 부드러운 전환을 만들어준다.
function updateList(newItems) {
if (!document.startViewTransition) {
renderList(newItems)
return
}
document.startViewTransition(() => renderList(newItems))
}
::view-transition-old(root) {
animation: fade-out 200ms ease-out;
}
::view-transition-new(root) {
animation: fade-in 200ms ease-in;
}
@keyframes fade-out { to { opacity: 0; } }
@keyframes fade-in { from { opacity: 0; } }
명명된 트랜지션
특정 엘리먼트만 별도 전환:
.product-card .image {
view-transition-name: product-image;
}
::view-transition-old(product-image),
::view-transition-new(product-image) {
animation-duration: 400ms;
}
상품 카드를 클릭해서 상세 페이지로 갈 때 **이미지가 그대로 확대되는** 네이티브 모바일 앱 같은 전환이 가능하다.
Cross-document 버전 (2024)
진짜 혁명은 여기다. **MPA(Multi-Page App)에서도 페이지 전환을 매끄럽게** 만들 수 있다.
@view-transition {
navigation: auto;
}
.hero-image {
view-transition-name: hero;
}
이전 페이지의 `.hero-image`와 새 페이지의 `.hero-image`가 같은 이름을 공유하면, 브라우저가 자동으로 두 엘리먼트 사이를 전환한다. SPA 라우터 없이도, Next.js의 `<Link>` 없이도. **그냥 `<a href>` 클릭만으로.**
MPA 트랜지션의 의미
지난 10년간 우리가 SPA를 쓴 가장 큰 이유 중 하나가 "페이지 전환을 부드럽게 하고 싶다"였다. View Transitions API의 cross-document 버전은 그 이유를 사라지게 한다. Next.js, Astro, SvelteKit 모두 자동으로 활용한다.
주의점
- 트랜지션 중에는 사용자 입력이 잠깐 막힐 수 있다 → 짧게(200~300ms)
- `prefers-reduced-motion: reduce` 사용자를 위해 차단 옵션 제공
- `view-transition-name`은 페이지에서 **유일**해야 한다
4장 · Popover API (2024) — 네이티브 모달
왜 우리는 모달에서 매번 실패했나
- 포커스 트랩
- ESC로 닫기
- 외부 클릭으로 닫기
- 백드롭(backdrop)
- z-index 지옥
- 접근성 (role, aria, focus management)
이 모든 것을 **브라우저가 해준다**. 2024년부터.
이것만으로:
- ESC로 닫힘
- 외부 클릭으로 닫힘 (auto 모드)
- 포커스 자동 이동
- 항상 top layer에 렌더 (z-index 무관)
popover 두 가지 모드
| 값 | 동작 |
| --- | --- |
| `auto` (기본) | ESC, 외부 클릭, 다른 popover 열면 닫힘 |
| `manual` | 명시적으로만 닫힘 (토스트, 알림 등) |
백드롭 스타일링
[popover]::backdrop {
background: oklch(0% 0 0 / 0.6);
backdrop-filter: blur(8px);
}
Dialog와의 차이
`<dialog>`는 폼 통합과 modal/non-modal 구분이 있다. Popover는 더 가볍고 임의 엘리먼트에 적용 가능. 일반적으로:
- **풀 모달(폼 제출 등)** → `<dialog>`
- **메뉴, 툴팁, 카드 hover** → popover
5장 · Anchor Positioning (Chrome 125, 2024.4) — 툴팁/팝오버 배치
그 옛날의 악몽
툴팁 라이브러리 하나 쓰려면 Floating UI(이전 Popper.js)를 깔고, viewport 충돌 감지하고, 스크롤 이벤트 듣고, ResizeObserver 걸고… 진짜 미친 짓이었다.
이제는:
Tooltip content
#tooltip {
position-anchor: --my-button;
top: anchor(bottom);
left: anchor(center);
translate: -50% 0;
}
브라우저가 자동으로 트리거 엘리먼트의 위치를 추적한다. 스크롤하든 리사이즈하든 따라온다.
position-try-fallbacks — 자동 viewport 충돌 회피
#tooltip {
position-anchor: --my-button;
position-area: bottom;
position-try-fallbacks: top, right, left;
}
기본은 아래 표시, 공간이 부족하면 위 → 오른쪽 → 왼쪽 순으로 자동 시도. **Floating UI 한 줄 없이.**
position-area — 9분면 단축
#tooltip {
position-area: top span-all;
}
`top`, `bottom`, `left`, `right`, `center`, `span-all`, `start`, `end` 등으로 표현. 9분면 그리드를 머릿속에 두면 직관적이다.
안 되는 것
- 한 엘리먼트가 여러 앵커를 동시에 참조 (CSS Anchor Positioning Level 2에서 검토 중)
- `position: fixed`나 `absolute`가 아니면 동작 안 함
Floating UI의 운명
여전히 유효하다 — 복잡한 충돌 감지, 화살표 자동 위치 같은 고급 기능은 아직 라이브러리가 낫다. 단, 80%의 단순 툴팁/팝오버는 이제 CSS만으로 충분하다.
6장 · Scroll-driven Animations (Chrome 115) — JS 없는 스크롤 효과
두 가지 스크롤 타임라인
| 타임라인 | 의미 |
| --- | --- |
| `scroll()` | 스크롤 컨테이너의 전체 스크롤 진행도 |
| `view()` | 특정 엘리먼트가 뷰포트를 가로지르는 진행도 |
scroll() — 진행 인디케이터
@keyframes grow-progress {
from { transform: scaleX(0); }
to { transform: scaleX(1); }
}
.progress-bar {
position: fixed;
top: 0;
left: 0;
right: 0;
height: 4px;
background: oklch(70% 0.2 250);
transform-origin: left;
animation: grow-progress linear;
animation-timeline: scroll();
}
스크롤하면 자동으로 차오른다. JavaScript 한 줄도 없다.
view() — 뷰포트 진입 페이드인
@keyframes fade-in {
from { opacity: 0; transform: translateY(40px); }
to { opacity: 1; transform: translateY(0); }
}
.card {
animation: fade-in linear;
animation-timeline: view();
animation-range: entry 0% cover 40%;
}
엘리먼트가 뷰포트 하단에 진입할 때 시작해서, 40% 보이면 끝난다. Intersection Observer 코드 한 줄 없이.
prefers-reduced-motion 대응
@media (prefers-reduced-motion: no-preference) {
.card {
animation: fade-in linear;
animation-timeline: view();
}
}
접근성을 잊지 말자.
성능
스크롤-드리븐 애니메이션은 **컴포지터 스레드**에서 실행된다. JavaScript scroll 이벤트와 달리 메인 스레드를 멈추지 않는다. 60fps가 기본이고 120fps도 가능하다.
7장 · CSS Nesting (2023) — Sass 없이 중첩
표준 문법
.card {
padding: 1rem;
border-radius: 0.5rem;
& .title {
font-size: 1.5rem;
font-weight: 600;
}
& .description {
color: oklch(50% 0 0);
}
&:hover {
transform: translateY(-2px);
}
@media (min-width: 768px) {
padding: 1.5rem;
}
}
Sass와의 차이는 미미하다. `&`가 더 자주 필요할 뿐(2023년 초기엔 의무였다가 완화됨).
Sass와의 차이점
- **변수**는 표준이 아님 → CSS Custom Properties(`--var`)를 쓴다
- **mixin**은 아직 검토 중
- **`@extend`**는 표준화 가능성 낮음
마이그레이션
/* Before (Sass) */
.btn {
&.primary { background: blue; }
&.danger { background: red; }
}
/* After (native CSS nesting) */
.btn {
&.primary { background: oklch(60% 0.2 250); }
&.danger { background: oklch(60% 0.25 25); }
}
거의 그대로 동작한다.
8장 · :has() — 부모 선택자
"CSS의 부모 선택자가 없는 이유"는 끝났다
/* 카드에 이미지가 있으면 다른 레이아웃 */
.card:has(img) {
display: grid;
grid-template-columns: 1fr 2fr;
}
/* 폼에 invalid 입력이 있으면 제출 버튼 비활성 스타일 */
form:has(input:invalid) button[type="submit"] {
opacity: 0.5;
pointer-events: none;
}
/* 다크 모드를 선호하지 않고, html에 light 클래스가 없으면 다크 */
html:not(.light) {
color-scheme: dark;
}
실전 패턴
**1) 부모-자식 동시 조건**
.dropdown:has(:focus-visible) {
outline: 2px solid currentColor;
}
**2) 형제 기반 스타일링**
label:has(+ input:required)::after {
content: ' *';
color: oklch(60% 0.25 25);
}
**3) 빈 상태 처리**
.list:not(:has(.list-item)) {
display: none;
}
성능
`:has()`는 brute force가 아니라 invalidation 추적이 있다. 매우 큰 DOM에서도 실용적이다.
9장 · color-mix() / light-dark() — 색상 연산
color-mix() — 두 색을 섞다
.btn {
background: color-mix(in oklch, blue, white 20%);
}
.btn:hover {
background: color-mix(in oklch, blue, white 30%);
}
`in oklch`/`in lab`/`in srgb`/`in hsl` 등 색 공간을 명시. 일반적으로 `oklch`가 가장 자연스럽다(인간 지각에 가까운 균등 공간).
디자인 토큰과 결합
:root {
--brand: oklch(60% 0.2 250);
}
.btn {
background: var(--brand);
}
.btn:hover {
background: color-mix(in oklch, var(--brand), white 15%);
}
.btn:active {
background: color-mix(in oklch, var(--brand), black 15%);
}
색 변형을 일일이 정의할 필요 없이 **하나의 brand로부터 파생**.
light-dark() — 다크 모드 한 줄
:root {
color-scheme: light dark;
--bg: light-dark(white, oklch(15% 0 0));
--fg: light-dark(oklch(15% 0 0), white);
}
body {
background: var(--bg);
color: var(--fg);
}
`prefers-color-scheme` 미디어 쿼리를 두 번 쓸 필요 없이 한 줄. **단, `color-scheme: light dark`를 반드시 선언**해야 동작한다.
OKLCH가 표준이 되는 이유
`#hex`나 `rgb()`는 RGB 색 공간이라 인간 지각과 일치하지 않는다. `oklch(60% 0.2 250)`은:
- L = 명도 (0~100%)
- C = 채도 (0~0.4)
- H = 색상 (0~360)
색상끼리 보간이 자연스럽고, 명도 변화가 직관적이다. 2026년의 디자인 시스템은 OKLCH가 사실상 표준이다.
10장 · @scope / @layer — 캡슐화와 캐스케이드
@scope — CSS의 진짜 스코프
@scope (.card) to (.card-content) {
h2 {
font-size: 1.25rem;
}
}
`.card` 안쪽이지만 `.card-content`까지는 적용 안 됨. **lower boundary**가 있는 진짜 스코프.
@scope (.dark-section) {
a {
color: white;
}
}
`.dark-section` 안의 `<a>`만 흰색.
@layer — 캐스케이드 레이어
@layer reset, base, components, utilities;
@layer reset {
* { margin: 0; padding: 0; }
}
@layer base {
body { font-family: system-ui; }
}
@layer components {
.btn { padding: 0.5rem 1rem; }
}
@layer utilities {
.text-center { text-align: center; }
}
레이어 순서가 늦을수록 우선. **specificity와 무관**하게 작동.
**why 중요한가**: Tailwind/UnoCSS의 utility-first는 specificity 폭주를 일으켰다. `@layer utilities`로 묶으면 항상 마지막 → utility가 specificity 싸움 없이 항상 이긴다.
Cascade Layers + Tailwind 4
Tailwind 4는 내부적으로 `@layer`를 사용한다. 우리 CSS는 다른 레이어에 두면 우선순위가 깔끔하게 정리된다.
11장 · Subgrid — 마침내 보편 지원
문제 정의
카드 안의 제목/설명/버튼이 카드끼리 가로로 **정렬**되길 원한다. 부모 grid의 그리드 라인을 자식이 상속받아야 한다.
Subgrid 해결
.cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 1rem;
}
.card {
display: grid;
grid-template-rows: subgrid;
grid-row: span 3;
}
`grid-template-rows: subgrid`로 부모의 행 구조를 상속. 제목들이 자동으로 같은 높이에 정렬된다.
Subgrid가 해결한 것들
- 카드 그리드의 제목/이미지/버튼 정렬
- 폼 라벨/입력 정렬
- 표 같은 컴포넌트의 칸 정렬
- 디자인 시스템의 일관된 spacing
12장 · Speculation Rules — 미래 페이지 prerender
무엇인가
사용자가 클릭할 것 같은 링크를 **미리 렌더링**한다. prefetch보다 강력하다 — DOM, JavaScript 실행까지 모두.
{
"prerender": [
{
"where": { "href_matches": "/articles/*" },
"eagerness": "moderate"
}
]
}
`/articles/`로 시작하는 모든 링크에 대해, 사용자가 hover/touch start 같은 신호를 보이면 미리 페이지를 렌더링.
eagerness 단계
| 값 | 의미 |
| --- | --- |
| `immediate` | 즉시 (조심해서 써야 함) |
| `eager` | viewport에 보이면 |
| `moderate` | hover 200ms 또는 mousedown |
| `conservative` | mousedown만 |
효과
next-page LCP가 **수 밀리초**로 떨어진다. 사용자 입장에서는 "클릭과 동시에 다음 페이지가 이미 거기 있다."
Next.js와의 관계
Next.js App Router는 자동으로 prefetch한다(코드/데이터). Speculation Rules의 prerender는 **DOM까지** 렌더링하는 것이라 더 강력하다. Next.js 15+에서는 옵트인 가능.
13장 · WebGPU / WebTransport — 안정화
WebGPU
- Chrome 113(2023.5), Safari 18, Firefox 121+에서 안정 지원
- 셰이더 언어: WGSL
- 머신러닝 (transformers.js, MediaPipe, ONNX Runtime Web), 고급 그래픽, GPU 컴퓨트
- WebGL과 달리 컴퓨트 셰이더와 modern GPU 기능 노출
브라우저에서 LLM 추론(WebLLM), 이미지 처리, 시뮬레이션을 GPU 가속으로 돌릴 수 있다. ChatGPT를 브라우저 안에서 로컬로 돌리는 시대가 진짜로 왔다.
WebTransport
- HTTP/3 기반 양방향 통신
- WebSocket의 후계자 (UDP 기반의 신뢰성 옵션)
- 다중 스트림, head-of-line blocking 없음
- 실시간 게이밍, WebRTC 데이터 채널 대안
const transport = new WebTransport('https://example.com/wt')
await transport.ready
const stream = await transport.createBidirectionalStream()
const writer = stream.writable.getWriter()
await writer.write(new TextEncoder().encode('hello'))
그 외 안정화된 것들
- **Custom Highlight API** — 브라우저 selection 외에 사용자 정의 하이라이트
- **content-visibility: auto** — 화면 밖 콘텐츠 렌더링 비용 절감
- **Performance.measureUserAgentSpecificMemory** — 정확한 메모리 측정
- **Storage Access API**, **CHIPS** — 3rd-party 쿠키 시대 대응
14장 · 한국 / 일본 웹 표준 컨텐츠 — 네이버 D2, html5.jp, mizchi
한국
- **네이버 D2** (d2.naver.com) — 웹 표준, 브라우저 내부, 성능 최적화 글이 꾸준히 올라온다. 2024~2025년 View Transitions, Container Queries 관련 분석 글들이 좋다.
- **TOAST UI 블로그** — 표준 + 자체 라이브러리 구현 노하우
- **Frontender 카카오톡 오픈채팅 / Frontier 컨퍼런스** — 한국어로 표준 따라잡기 좋은 커뮤니티
- **MDN 한국어 번역** — 여전히 일부지만, 새 기능들의 한글화가 이전보다 빨라졌다
일본
- **html5.jp** — 오래된 사이트지만 사양 번역이 가장 빠르고 정확
- **mizchi 블로그** — 프런트엔드 트렌드/사양 동향 분석. 비판적 시각이 강해서 표준의 한계를 보여준다
- **Web Developer Conference (Tokyo)** — 매년 표준 관련 발표 풍부
- **CodeGrid** (Pixel Grid) — 유료지만 깊이 있는 CSS 표준 해설
- **MDN 일본어** — 영어판과 거의 동시 업데이트
영어권
- **web.dev** — Google 공식, 새 기능 가이드의 정전
- **CSS Tricks** — 여전히 좋다 (2025년부터 새 글 페이스가 줄긴 했지만)
- **Smashing Magazine** — 깊이 있는 글 다수
- **State of CSS / State of JS** — 매년 트렌드 조사
- **Una Kravets, Adam Argyle, Bramus**의 블로그 — Chrome DevRel의 1차 정보원
일본 표준 활동의 특이점
W3C 일본 노드 활동이 매우 활발하다. 한국과 달리 일본은 사양 번역 문화가 강하고, 사양에 대해 한 문장 한 문장 곱씹는 글이 많다. 표준의 "왜"를 알고 싶다면 html5.jp의 글을 찾아 읽는 것을 권한다.
15장 · 마이그레이션 전략 — 어디부터 도입할까
우선순위
**1티어 — 지금 당장 도입 가능 (보편 지원)**
- Container Queries
- CSS Nesting
- `:has()`
- `color-mix()`, `light-dark()`
- `@layer`
- Subgrid
- Popover API
- View Transitions (same-document)
**2티어 — 점진 도입 (대부분 지원, 그레이스풀 폴백 권장)**
- View Transitions (cross-document)
- Anchor Positioning
- Scroll-driven Animations
- `@scope`
**3티어 — 옵트인 (특정 시나리오)**
- Speculation Rules API
- WebGPU (ML/그래픽)
- WebTransport (실시간)
점진적 향상의 전형
.tooltip {
/* fallback: 기본 absolute positioning */
position: absolute;
top: 100%;
left: 50%;
transform: translateX(-50%);
}
@supports (position-anchor: --x) {
.tooltip {
position-anchor: --trigger;
top: anchor(bottom);
left: anchor(center);
transform: translateX(-50%);
}
}
`@supports`로 분기. 새 기능이 있으면 강화, 없으면 기존 동작.
디자인 시스템 마이그레이션 체크리스트
1. **OKLCH 색상 마이그레이션** — 디자인 토큰부터 `color-mix(in oklch, ...)` 기반으로
2. **모달 라이브러리 → Popover API** — 폼이 들어가면 dialog, 아니면 popover
3. **Floating UI → Anchor Positioning** — 단순 툴팁/팝오버부터 이전
4. **Intersection Observer → Scroll-driven Animations** — fade-in류부터
5. **Tailwind/Sass 변수 → `@layer` 정리** — 우선순위 충돌 끝
6. **반응형 컴포넌트 → Container Queries** — 미디어 쿼리를 컨테이너 쿼리로
7. **SPA 라우터 트랜지션 → View Transitions (cross-document)** — 점진 도입
흔한 함정
- `view-transition-name`은 페이지 내 유일해야 함 → 동적 리스트면 ID 기반
- Anchor Positioning은 `position: absolute/fixed`만 동작
- Scroll-driven Animations에 `prefers-reduced-motion` 분기 필수
- Popover의 `popovertarget`은 ID 참조 → React에서 동적 ID 신중히
- Container Queries는 `container-type`이 layout containment를 강제 → 일부 레이아웃 깨짐 가능
결론 — 2026년의 기본기
이 글의 모든 기능은 **2026년 evergreen 브라우저의 기본기**다. "고급 CSS"가 아니라 그냥 CSS다. 라이브러리를 한 번 더 깔기 전에, "이거 표준에 있지 않을까?"를 한 번 더 확인하자. 대부분 답은 "있다"이다.
> **2026년의 웹 개발은, 표준에 베팅하면 이기는 시대다.**
참고 / References
- MDN Web Docs — [CSS Container Queries](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_containment/Container_queries)
- MDN — [View Transitions API](https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API)
- MDN — [Popover API](https://developer.mozilla.org/en-US/docs/Web/API/Popover_API)
- MDN — [CSS Anchor Positioning](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_anchor_positioning)
- MDN — [CSS Scroll-driven Animations](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_scroll-driven_animations)
- MDN — [CSS Nesting](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_nesting)
- MDN — [`:has()` selector](https://developer.mozilla.org/en-US/docs/Web/CSS/:has)
- MDN — [`color-mix()`](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/color-mix)
- MDN — [`light-dark()`](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/light-dark)
- MDN — [CSS `@scope`](https://developer.mozilla.org/en-US/docs/Web/CSS/@scope)
- MDN — [CSS Cascade Layers (`@layer`)](https://developer.mozilla.org/en-US/docs/Web/CSS/@layer)
- MDN — [CSS Subgrid](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_grid_layout/Subgrid)
- MDN — [Speculation Rules API](https://developer.mozilla.org/en-US/docs/Web/API/Speculation_Rules_API)
- MDN — [WebGPU API](https://developer.mozilla.org/en-US/docs/Web/API/WebGPU_API)
- MDN — [WebTransport API](https://developer.mozilla.org/en-US/docs/Web/API/WebTransport_API)
- MDN — [CSS Custom Highlight API](https://developer.mozilla.org/en-US/docs/Web/API/CSS_Custom_Highlight_API)
- MDN — [`content-visibility`](https://developer.mozilla.org/en-US/docs/Web/CSS/content-visibility)
- web.dev — [Container queries land in stable browsers](https://web.dev/blog/cq-stable)
- web.dev — [Cross-document view transitions](https://developer.chrome.com/docs/web-platform/view-transitions/cross-document)
- web.dev — [Introducing the popover API](https://developer.chrome.com/blog/introducing-popover-api)
- web.dev — [CSS anchor positioning API](https://developer.chrome.com/blog/anchor-positioning-api)
- web.dev — [Scroll-driven animations](https://developer.chrome.com/docs/css-ui/scroll-driven-animations)
- web.dev — [Speculation Rules API](https://developer.chrome.com/docs/web-platform/prerender-pages)
- Bramus van Damme blog — [scroll-driven-animations.style](https://scroll-driven-animations.style/)
- Una Kravets blog — [una.im](https://una.im/)
- Adam Argyle — [nerdy.dev](https://nerdy.dev/)
- 네이버 D2 — [d2.naver.com](https://d2.naver.com/)
- TOAST UI 블로그 — [ui.toast.com/weekly-pick](https://ui.toast.com/weekly-pick)
- html5.jp — [html5.jp](https://www.html5.jp/)
- mizchi blog — [zenn.dev/mizchi](https://zenn.dev/mizchi)
- CodeGrid — [www.codegrid.net](https://www.codegrid.net/)
- State of CSS — [stateofcss.com](https://stateofcss.com/)
- W3C CSS Working Group — [drafts.csswg.org](https://drafts.csswg.org/)
- Baseline (web platform feature status) — [web.dev/baseline](https://web.dev/baseline)
- Can I Use — [caniuse.com](https://caniuse.com/)
현재 단락 (1/450)
10년 전, 우리는 "곧 표준이 될 것"이라고 말하며 폴리필을 깔았다. 2026년, 우리는 **표준이 곧 일상**이 된 시대에 산다.