필사 모드: 웹 플랫폼 2025 완전 정복: Container Queries·:has()·CSS Nesting·Subgrid·Popover API·Anchor Positioning·WebGPU·WASI·Speculation Rules·Baseline 2024-2025 — Season 6 Ep 5
한국어프롤로그 · 플랫폼이 커지면 프레임워크는 가벼워진다
2014-2020년, React·Vue·Angular가 필요했던 이유는 브라우저가 많이 부족했기 때문이다. 컴포넌트·상태관리·애니메이션·라우팅·레이아웃·인터랙션 모두 JS로 해결해야 했다.
2024-2025년은 다르다. **브라우저가 대부분을 한다**.
- **Container Queries**로 컴포넌트 자체 반응형
- **`:has()`**로 JS 없이 부모 기반 선택
- **CSS Nesting·Subgrid**로 SCSS 필요성 감소
- **Popover API·Dialog**로 모달 라이브러리 필요 최소화
- **Anchor Positioning**으로 Floating UI 네이티브화
- **View Transitions**로 페이지 전환 네이티브
- **WebGPU**로 고성능 그래픽·ML
- **Speculation Rules**로 프리렌더·프리페치
Next.js·React를 여전히 쓰지만, **"플랫폼에 맡길 수 있는 건 플랫폼에"** 는 2025년의 원칙이다. 이번 글은 그 지도.
1장 · Baseline — 호환성의 새 언어
Baseline이란?
2023-2024년 **Web DX Community Group**이 만든 브라우저 기능 호환성 라벨 체계. "이 기능은 지금 써도 안전한가?" 에 답.
3단계
**Baseline Newly available**
- 가장 최근 주요 브라우저들(Chrome·Edge·Firefox·Safari)에 도달
- 최신 버전 대상
**Baseline Widely available**
- 위 상태 후 **30개월** 경과
- 사실상 모든 활성 브라우저 지원
- 안심하고 사용 가능
**Limited availability**
- 주요 브라우저 한둘만 지원
- 프로덕션 사용 주의
실전 사용
- **MDN·caniuse·web.dev**에 Baseline 라벨 표시
- Next.js·Astro·Vite가 **target: baseline-2024** 같은 옵션 도입
- 사내 코딩 가이드에 "Baseline widely available만 무폴리필" 선언
왜 중요한가
- "IE 지원·모던 브라우저" 같은 모호한 기준 대체
- 팀 내 결정이 빠르고 명확
- 프로덕션 안정성·PWA 품질 기준
2장 · Container Queries — 반응형의 혁명
전통적 문제
미디어 쿼리 `@media`는 **뷰포트 전체** 기준. 그러나 같은 카드 컴포넌트가 어떨 땐 사이드바, 어떨 땐 메인에 배치되면 크기가 다름. 뷰포트는 같아도.
해결: `@container`
.card-grid {
container-type: inline-size;
container-name: grid;
}
@container grid (min-width: 600px) {
.card { display: flex; }
}
이제 카드 그리드 **자체 폭** 기준으로 카드 레이아웃 결정.
단위
- `cqw`, `cqh`: container width/height
- `cqi`, `cqb`: inline/block
- `cqmin`, `cqmax`
2025년 지원
- Chrome 105+·Safari 16+·Firefox 110+ 모두 **Baseline Widely available**
- 사실상 **기본 도구**
사용 패턴
**(1) 자체 반응형 컴포넌트**
- 재사용 위치 무관
**(2) Style Queries** (2024 Chrome/Edge)
- `@container style(--theme: dark)` — 부모 스타일 속성 기반 조건
**(3) 뷰포트 + 컨테이너 조합**
- 페이지 레이아웃은 미디어, 컴포넌트는 컨테이너
3장 · `:has()` — 부모 선택자의 도래
왜 혁명인가
CSS는 항상 **아래로만** 내려가는 선택자였다. 자식 기반 부모 스타일링은 JS 필수. `:has()` 가 이 제한 제거.
사용 예
**(1) 자식 유무에 따른 부모 스타일**
.card:has(img) { padding-top: 0; }
.form:has(input:invalid) { border: 1px solid red; }
**(2) 자식 상태에 따른 전체 스타일**
body:has(dialog[open]) { overflow: hidden; }
**(3) 형제 관계**
label:has(+ input:focus) { color: blue; }
지원
- Chrome 105+, Safari 15.4+, Firefox 121+ — **Baseline Widely**
- 성능 과거 우려 해결됨
실전 임팩트
- JS로 parent 클래스 조작 코드 **대거 삭제 가능**
- 상호작용 상태 UI 훨씬 간결
- React 컴포넌트의 "상태 prop" 다수가 CSS로
4장 · CSS Nesting 네이티브
이전까지
- SCSS·Less·Stylus로 nesting
- 빌드 도구 의존, 학습 곡선
2023-2024 네이티브 Nesting
.card {
padding: 1rem;
& .title {
font-size: 1.5rem;
}
&:hover {
background: #f0f0f0;
& .title { color: #333; }
}
@media (min-width: 768px) {
padding: 2rem;
}
}
주의
- 최신 스펙은 `&` 선택자 **생략 가능** (2024 개정)
- 옛 문법(`& `)과 혼용 주의
- PostCSS Preset-Env로 폴백 트랜스파일
지원
- Chrome 120+·Safari 17.2+·Firefox 117+ — **Baseline 2023-2024**
의미
- SCSS 필요성 크게 감소
- CSS-in-JS 의존성 감소
- **Vanilla CSS의 부활**
5장 · CSS Subgrid
전통 Grid의 한계
- 부모 grid에 자식 grid를 넣어도 **행/열 정렬 안 됨**
- 카드 제목·내용·CTA 정렬 어려움
Subgrid 해결
.parent {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
.child {
display: grid;
grid-template-columns: subgrid; /* 부모 그리드 계승 */
}
이제 자식 grid가 부모 grid의 트랙에 맞춤.
사용 사례
- 카드 리스트의 제목·본문·푸터 자동 정렬
- 멀티 컬럼 폼
- Masonry(조각) 레이아웃
지원
- Firefox 71+ (2019 이래 지원), Safari 16+, Chrome 117+ — **Baseline 2023**
6장 · Popover API·Dialog Element
전통 모달의 문제
- Focus 관리 수동
- 스크롤 잠금 JS
- ESC 닫기 수동
- 접근성 ARIA 직접
`<dialog>` (HTML5)
- 모달·비모달 둘 다
- Native Focus trap
- `showModal()` / `close()` 메서드
- ESC 자동 닫힘
- `::backdrop` 스타일 지원
Popover API (2024-2025)
- `popover` 속성 하나로 팝오버
- 자동 Top Layer 렌더 (z-index 걱정 X)
- Auto-hide (바깥 클릭·ESC)
- `popover="manual"`로 수동 제어
지원
- Chrome 114+·Safari 17+·Firefox 125+ — **Baseline 2024**
실전 영향
- Headless UI·Radix Dialog/Popover 쓸 필요 감소
- **네이티브 + 약간의 CSS/JS**로 충분
7장 · CSS Anchor Positioning
문제: 플로팅 UI
툴팁·드롭다운·팝오버를 특정 요소 기준으로 **정확히 위치**시키기는 복잡.
- Floating UI(Popper.js) 같은 라이브러리 필수
- Resize·Scroll에 따라 JS 재계산
해결: CSS Anchor Positioning (2024-)
툴팁
#btn { anchor-name: --btn; }
[popover] {
position: absolute;
top: anchor(--btn bottom);
left: anchor(--btn left);
}
- **CSS만으로** 앵커 기반 위치
- 자동 Repositioning (fallback)
- 성능·접근성 내장
지원 (2025 4월)
- Chrome 125+: 안정
- Safari: 개발 중 (2025 하반기)
- Firefox: 개발 중
임팩트
- Popper·Floating UI 사용 감소
- React 트리 구조 간소화
- 다만 아직 폴리필 필요 (Safari 대응 전)
8장 · Web Components 2025 현주소
기본 3요소
- **Custom Elements**
- **Shadow DOM**
- **HTML Templates**
2024-2025년 성숙
**(1) Declarative Shadow DOM**
- 서버 렌더 시 Shadow DOM 포함
- SSR 가능
**(2) Form-associated Custom Elements**
- 표준 폼에 자연스럽게 통합
- `formAssociated = true`, ElementInternals API
**(3) CSS `:state()` 의사 클래스**
- 커스텀 상태를 CSS에서 선택
프레임워크 통합
- React 19에서 Custom Elements 지원 개선 (attributes·props 구분)
- Lit·Stencil 성숙
- Vue·Svelte 자연 통합
현실 평가
**장점**
- 프레임워크 중립 (디자인 시스템·임베드 위젯)
- 장수 (브라우저 표준)
**한계**
- React 컴포넌트 수준 생태계 X
- SSR·Hydration 복잡
- 주로 **공유 라이브러리·내장 위젯**에 한정
적합한 용도
- 여러 팀 공유 "Button/Icon 라이브러리"
- 외부 사이트 임베드 위젯 (댓글·채팅)
- Shopify·Wordpress 등 플러그인
9장 · WebGPU 현주소
WebGL의 한계
- OpenGL ES 기반, 구조 오래됨
- 병렬 컴퓨팅 제한
- 게임·AI에 부족
WebGPU (2023-)
- Modern GPU API (Vulkan·Metal·DX12 수준)
- **Compute Shader** 지원 → 범용 GPU 컴퓨팅
- 한 API로 멀티 OS 지원
2024-2025 주요 사용
**(1) AI/ML 브라우저 실행**
- **Transformers.js**: Whisper·Llama 등 브라우저 추론
- **ONNX Runtime Web**: GPU 가속
- **MLC-LLM**: 7B 모델도 브라우저에서
**(2) 고성능 그래픽**
- WebGPU 기반 3D 엔진 (Three.js, Babylon.js)
- 게임·가상전시
**(3) 데이터 시각화**
- 대규모 포인트 클라우드·WebGL 넘어선 성능
지원
- Chrome 113+·Edge 113+ 안정
- Safari 18+·Firefox Nightly (2025 진행)
한계
- 모바일 지원 아직 부분적
- 메모리 관리 복잡
10장 · File System Access API·기타 Local 기능
File System Access API
- 브라우저에서 **로컬 파일 직접 열기/저장**
- 전통 `<input type="file">` 을 넘어 **계속 접근·수정**
- Photopea·VS Code Web·Figma 같은 앱에 필수
주요 새 API 2024-2025
**(1) Clipboard API 고도화**
- 이미지·리치 텍스트 지원
**(2) Web Share API**
- OS 네이티브 공유 시트
**(3) Wake Lock API**
- 화면 꺼짐 방지 (요리·회의 앱)
**(4) Screen Capture·WebCodecs**
- 비디오·오디오 로우 레벨
**(5) Compression Streams**
- gzip·deflate 네이티브
**(6) Web Locks**
- 탭간 뮤텍스·리소스 조정
한계
- 일부는 PWA or 설정 필요
- Safari·Firefox 지원 편차
11장 · WebAssembly·WASI 2025
WASM 현재
- **모바일·데스크톱 다수 브라우저**에서 네이티브급 성능
- JS와 빠른 interop (WASM SIMD, 참조 타입, Exception Handling)
- 언어: Rust, Go, C/C++, AssemblyScript, Zig, Kotlin·Swift 실험
WASI (WebAssembly System Interface)
브라우저 밖·서버 WASM 실행 표준.
- **WASI Preview 2**(2024) — 컴포넌트 모델
- **wasmtime·wasmer·WasmEdge** 런타임
실전 사용
**(1) Serverless 엣지**
- Cloudflare Workers, Fastly Compute@Edge, Vercel WASM
- Cold Start·격리·다중 언어
**(2) 플러그인 시스템**
- Figma Plugins, Shopify Functions, Envoy Proxy
- 사용자 코드를 안전 격리
**(3) 브라우저 내 헤비 연산**
- 이미지·비디오 편집, ML 추론, 에뮬레이터
한국 적용 사례
- 네이버 Whale: WASM 기반 확장
- 카카오 Talk Web: 일부 기능 WASM
- 토스: 보안·핵심 로직 WASM 고려
12장 · Speculation Rules API
목적
- **사용자가 다음에 갈 페이지를 미리 로드**
- prerender·prefetch 표준
예시
{
"prerender": [
{ "source": "list",
"urls": ["/next-page", "/likely-next"] }
],
"prefetch": [
{ "source": "document",
"where": { "href_matches": "/articles/*" } }
]
}
모드
- **prefetch**: 리소스만 가져옴, 실행 X
- **prerender**: 전체 렌더 (가장 빠르지만 비용↑)
2024-2025 현황
- Chrome 121+·Edge 121+ 안정
- Safari·Firefox 개발 중
- **Chrome Prefetch Hints** 데이터 기반 자동 추천
실전 사용
- Next.js·Astro가 백엔드에서 자동 주입 고려
- 대기업 뉴스·이커머스에서 활용 시작
주의
- 비용 (CPU·네트워크)
- 분석 도구의 "가짜 방문" 이슈
13장 · 실전 · "플랫폼 먼저" 체크리스트
새 컴포넌트·기능 만들 때 **프레임워크·라이브러리 전에** 확인.
체크 항목
- **반응형**: Container Queries 가능?
- **상태 스타일**: :has()·:focus-within 로?
- **모달·팝오버**: `<dialog>`·Popover API?
- **툴팁·드롭다운**: Anchor Positioning?
- **폼 유효성**: `:user-invalid`·`:user-valid`?
- **사이드 시트**: `<details>` + 스타일?
- **파일**: File System Access?
- **카운터·숫자 변화**: CSS `@property` 애니메이션?
- **스크롤 효과**: Scroll-driven Animations?
- **페이지 전환**: View Transitions?
판단 순서
1. **웹 플랫폼에 기본 기능이 있나?**
2. **Baseline Widely 지원인가?**
3. **없으면, 경량 라이브러리로 대체?**
4. **여전히 필요하면, 프레임워크 컴포넌트**
14장 · 다음 글 예고 — Season 6 Ep 6: "성능·Core Web Vitals 2025"
웹 플랫폼 기능을 잘 쓰는 건 **성능**을 잘 쓰는 것. Ep 6은 Core Web Vitals와 성능 전반.
- LCP·CLS·INP (FID 후계자)
- Real User Monitoring vs Synthetic Test
- Critical Rendering Path, LCP 최적화
- JS 번들 다이어트 (Rollup·esbuild·swc)
- Image 최적화 (Next/Image·Astro Image·AVIF)
- Font 최적화 (font-display·변수·subset)
- Caching 전략 (Cache-Control·Service Worker)
- Edge·CDN·HTTP/3
- Vercel Speed Insights·CrUX·PageSpeed
- 2025년 모바일 저전력 성능
- 한국 사용자의 네트워크 특성 (지하철·5G)
**"성능은 기능이 아니다. 모든 기능의 조건이다."**
다음 글에서 만나자.
에필로그 · 체크리스트 12
1. **Baseline Widely** 기준으로 기능 사용을 결정하는가?
2. 반응형이 필요할 때 **Container Queries** 를 먼저 고려하는가?
3. 부모 기반 스타일에 **`:has()`** 를 활용하는가?
4. CSS가 빌드 도구 없이 **Nesting** 으로 관리되는가?
5. 복잡한 레이아웃에 **Subgrid** 를 쓰는가?
6. 모달·팝오버를 **네이티브 API**로 구현하는가?
7. 툴팁·드롭다운 위치를 **Anchor Positioning** 으로?
8. Web Components를 **공유 라이브러리**에 활용하는가?
9. **WebGPU**의 기회(AI·시각화)를 탐색하는가?
10. Local 기능(파일·시스템)이 필요하면 **Platform API** 가 먼저인가?
11. **Speculation Rules**로 프리페치/프리렌더 검토했는가?
12. "플랫폼 먼저" 체크리스트를 **새 컴포넌트마다** 적용하는가?
> **"좋은 엔지니어는 플랫폼의 능력을 안다.**
> **위대한 엔지니어는 언제 플랫폼에 맡기고 언제 직접 만들지 안다."**
— Season 6 Ep 5, Fin.
현재 단락 (1/272)
2014-2020년, React·Vue·Angular가 필요했던 이유는 브라우저가 많이 부족했기 때문이다. 컴포넌트·상태관리·애니메이션·라우팅·레이아웃·인터랙션 모두 JS로 해결해...