목차13개 항목
출처와 참고
Rachel Andrew의 「CSS 그리드로 미지원 브라우저 지원하기」(2018.01)·「CSS 그리드 레이아웃을 지금 사용해도 정말 괜찮을까」(2017.11)와 Daniel Tonon의 「IE에서 CSS 그리드 사용하기」 시리즈(2018~2020, 웹액츄얼리 번역)를 바탕으로 재구성한 노트다. 지원 등급은 Yahoo의 「Graded Browser Support」와 Filament Group의 「Grade components, not browsers」(2013)를 바탕으로 더했다.
점진적 향상이란
점진적 향상(Progressive Enhancement)은 모든 브라우저에 쓸 만한 기본 경험을 주고, 새 기능을 지원하는 브라우저에는 더 나은 경험을 얹는 방식이다. 출발점은 "지원"의 뜻을 정하는 것이다.
| "지원"의 뜻 | 결과 |
|---|---|
| 모든 브라우저에서 똑같이 보인다 | 새 기능은 가장 오래된 대상 브라우저가 지원할 때까지 못 쓴다 |
| 모든 브라우저에서 콘텐츠를 무리 없이 쓸 수 있다 | 새 기능을 지금 쓰고, 옛 브라우저에는 단순한 레이아웃을 준다 |
모든 브라우저에서 똑같아야 한다면 그 기능을 쓰지 않는다. 새 기능은 이전에 불가능했던 일을 하려고 쓰는 것이지, 옛 디자인을 똑같이 재현하려고 쓰는 것이 아니다.
CSS 그리드·플렉스박스는 이제 모든 주요 브라우저가 지원한다. 같은 원칙이 지금은 지원 시기가 엇갈린 새 기능에 그대로 적용된다. Baseline 연도는 Chrome·Edge·Firefox·Safari가 모두 지원하게 된 해다(Newly available). 그로부터 30개월이 지나면 Widely available이 된다.
| 기능 | Baseline |
|---|---|
캐스케이드 레이어 @layer | 2022 |
컨테이너 크기 쿼리 @container, 서브그리드, :has(), 네이티브 중첩, oklch(), color-mix() | 2023 |
상대 색상 문법(oklch(from …)), light-dark(), font-size-adjust, @property, @starting-style·transition-behavior, popover 속성, 블록 레이아웃의 align-content, round() | 2024 |
같은 문서 뷰 트랜지션(document.startViewTransition(), View Transitions), @scope, abs()·sign() | 2025 |
앵커 위치 지정(팝오버와 앵커 위치 지정), shape(), text-box-trim | 2026 |
text-wrap: pretty, 그리드 레인(display: grid-lanes, 메이슨리) | 아직 아님 (2026년 10월 기준 pretty는 Firefox 미지원, 그리드 레인은 Safari 26.4만 정식 지원) |
최신 상태는 web.dev Baseline과 Can I use에서 확인한다.
지원 대상 정하기
- 추측하지 말고 실제 방문자 분석 데이터를 본다. 모바일에서 못 쓰는 사이트라면 모바일 방문이 적게 잡혀 데이터가 왜곡된다.
- 데이터가 없으면 Can I Use의 지역별 사용 통계나 Baseline(웹 플랫폼 기능이 모든 주요 브라우저에서 쓸 수 있는지 표시하는 기준)을 참고한다.
- 사이트의 대상 지역을 잊지 않는다. 저사양 기기와 데이터 절약형 브라우저가 많은 시장에서는 새 기능 지원이 늦다.
지원 등급: 브라우저가 아니라 컴포넌트에 매긴다
지원 범위를 문서로 정하는 고전적인 틀은 Yahoo의 등급별 브라우저 지원(Graded Browser Support) 이다. 「지원」을 똑같은 경험이 아니라 등급으로 나눴다.
| 등급 | 받는 것 | QA |
|---|---|---|
| A | 전체 경험(스타일·스크립트·고급 기능) | 모두 테스트하고 버그를 고친다 |
| C | 시맨틱 HTML만으로 된 핵심 콘텐츠와 기능 | 대표 브라우저 한두 개, 또는 CSS·JS를 끈 최신 브라우저로 테스트 |
| X | 알 수 없는·드문 브라우저. 유능하다고 가정하고 A와 같은 것을 준다 | 테스트하지 않는다 |
C 등급은 블랙리스트, A 등급은 화이트리스트로 브라우저를 미리 분류했다. 막 나온 A 등급 브라우저의 새 버전은 아직 테스트 전이라 X 등급이다.
브라우저 단위 등급에는 한계가 있다. 지금 방문자 대부분은 A 등급이고, 한 브라우저가 어떤 기능은 지원하고 어떤 기능은 지원하지 않는다. 지원 범위는 사다리가 아니라 산점도다. 그래서 컴포넌트마다 등급을 매긴다.
- 컴포넌트마다 기본 경험과 향상된 경험(필요하면 중간 단계)을 정한다. 예: 데이터 시각화는 기본이 HTML 표, 향상이 Canvas 차트. 내비게이션은 기본이 페이지 이동 링크, 향상이
fetch+history.pushState로 부분 갱신. - 어느 단계를 줄지는 브라우저 이름이 아니라 그 컴포넌트가 쓰는 기능의 지원 여부(
@supports,'x' in window)로 정한다. - 과거에는 페이지 전체를 두 등급으로 가르는 컷 더 머스터드(Cut the Mustard) 검사를 많이 썼다.
'querySelector' in document && 'addEventListener' in window처럼 몇 가지 기능이 있으면 향상 스크립트를 싣고 없으면 HTML만 준다. 지금은<script type="module">을 이해하는 브라우저에만 최신 번들을 싣는 것이 같은 역할을 한다. - UA로 브라우저를 판별하는 것은 기능 감지가 불가능한 마지막 경우에만 쓴다.
CSS가 이미 가진 두 가지 장치
1. 모르는 CSS는 무시된다
브라우저는 이해하지 못하는 속성과 값을 건너뛴다. 그래서 옛 방식으로 먼저 쓰고 그 아래에 새 방식을 쓰면, 옛 브라우저는 앞부분만, 새 브라우저는 둘 다 읽는다. 같은 선언 안에서도 통한다.
.card {
background: #3a7; /* 폴백 */
background: oklch(65% 0.15 160); /* 지원하면 이 값이 이긴다 */
}2. 새 레이아웃은 옛 레이아웃을 안다
명세에 "그리드·플렉스 아이템이 되면 무엇이 무효가 되는지"가 정의돼 있다. 대부분의 폴백이 자동으로 꺼진다.
| 폴백으로 쓴 것 | 부모가 display: grid가 되면 |
|---|---|
float, clear | 무시된다 |
display: inline-block | 아이템에 효과가 없다 |
display: table-cell | 그리드 아이템이 되어 테이블처럼 동작하지 않는다 |
vertical-align | 무시된다. 대신 박스 정렬(align-self 등)을 쓴다 |
flex, flex-grow 등 | 무시된다 |
다단 column-count, column-width | 무시된다 |
피처 쿼리로 틈새 메우기
자동으로 꺼지지 않는 값도 있다. 대표적인 것이 아이템에 준 너비다. float 폴백에서 width: 33%를 줬다면, 그리드에서는 이 33%가 컨테이너가 아니라 그리드 영역 기준이 되어 아이템이 셀의 3분의 1만 차지한다.
피처 쿼리(@supports)는 미디어 쿼리처럼 동작하되, 화면 크기 대신 브라우저가 특정 CSS를 지원하는지 묻는다.
/* 1. 폴백: 모든 브라우저가 읽는다 */
.item { float: left; width: 33.333%; }
/* 2. 새 레이아웃 */
.wrapper { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; }
/* 3. 틈새로 새는 폴백 값만 되돌린다 */
@supports (display: grid) {
.item { width: auto; }
}
/* 선택자 지원 여부도 물을 수 있다 */
@supports selector(:has(> img)) {
.card:has(> img) { grid-template-rows: auto 1fr; }
}피처 쿼리 안에는 새 코드 전체가 아니라 "되돌리거나 덧붙일 값"만 넣는다. @supports not (…)으로 미지원 브라우저 전용 규칙을 쓸 수도 있다. 폴리필도 핵도 아닌, 명세에 정의된 CSS만으로 처리하는 방법이다.
무거운 폴리필을 피하는 이유
- 레이아웃 전체를 계산하는 기능을 자바스크립트로 흉내 내면 높이·위치를 다시 계산하느라 로딩이 불안정해진다.
- 미지원 브라우저는 대개 오래되거나 느린 기기다. 가장 약한 기기에 가장 무거운 스크립트를 얹는 셈이다.
- 줄어들 사용자층 때문에 개발·테스트 시간이 크게 는다.
동작 범위가 좁고 가벼운 폴리필은 예외가 될 수 있다.
변환 도구의 한계
PostCSS·Autoprefixer·Lightning CSS 같은 도구는 접두사를 붙이거나 새 문법을 옛 문법으로 바꿔 준다(예: 네이티브 중첩 → 펼친 선택자, 논리 속성 → 물리 속성). 도구는 문법을 옮길 뿐 동작까지 옮기지는 못한다. 대응 문법이 없는 기능은 조용히 깨지므로 경고를 읽고 결과를 실제 브라우저에서 확인한다.
폴백 테스트
- 확실한 방법은 기능을 지원하지 않는 실제 브라우저로 보는 것이다. 구버전 브라우저(자동 업데이트를 끈 설치본)나 BrowserStack 같은 원격 테스트 서비스를 쓴다.
@supports (display: gridx)처럼 일부러 틀린 값으로 미지원 상태를 흉내 내지 않는다. 피처 쿼리 밖의 새 코드는 여전히 적용돼 거짓 양성이 나기 쉽다.- 테스트 대상은 "지원 / 미지원" 두 묶음이면 충분하다.
도입을 설득하는 근거
| 근거 | 내용 |
|---|---|
| 개발 시간 | 새 기능이 복잡도를 줄여 지금과 이후 유지보수 시간을 아낀다 |
| 디자인 | 새 기능 없이는 견고하게 만들 수 없는 디자인이다 |
| 성능 | 무거운 레이아웃 프레임워크나 스크립트를 걷어낼 수 있다 |
| 지원 추세 | 에버그린 브라우저는 자동 업데이트되어 미지원 비율이 빠르게 준다 |
역사
과거에는 IE10·11이 그리드 초기 명세를 -ms-grid 접두사로만 지원했다. 자동 배치·gap·auto-fill이 없어 아이템을 하나씩 배치하고 간격을 빈 트랙으로 흉내 냈으며, Autoprefixer의 그리드 변환 옵션으로 grid-template-areas를 옮기기도 했다. IE는 2022년 지원이 끝나 이런 우회법은 필요 없다. 피처 쿼리도 IE만 지원하지 않았다.
정리
- "지원"은 똑같이 보이는 것이 아니라 쓸 수 있는 것이다.
- 폴백을 먼저 쓰고 새 기능을 아래에 쓴다. 모르는 CSS는 무시되고, 새 레이아웃은 옛 레이아웃을 덮어쓴다.
- 새어 나오는 값만
@supports안에서 되돌린다. 선택자 지원은@supports selector()로 묻는다. - 무거운 폴리필 대신 단순한 경험을 준다. 변환 도구 결과는 실제 브라우저로 확인한다.
관련 노트: CSS 그리드 레이아웃, Float와 Flexbox 레이아웃, CSS 커스텀 속성으로 색상 체계 짜기, 반응형 디자인과 다국어 타이포그래피, PostCSS와 CSS 변환 도구, CSS Houdini: 렌더링 엔진에 끼어드는 API
원본 기록11
- 원문 (새 창) webactually.com/2018/01/19/css-그리드로-미지원-브라우저-지원하기/
- 원문 (새 창) webactually.com/2017/11/30/css-그리드-레이아웃을-지금-사용해도-정말-괜찮을까요/
- 원문 (새 창) webactually.com/2020/01/29/ie에서의-css-그리드-사용하기-일반적인-ie-그리드-오해를/
- 원문 (새 창) webactually.com/2018/10/02/ie에서-css-그리드-사용하기-css-그리드와-autoprefixer/
- 원문 (새 창) webactually.com/2018/11/13/ie에서-css-그리드-사용하기-간격으로-자동-배치/
- 원문 (새 창) webactually.com/2020/07/27/ie에서-css-그리드-사용하기-중복된-그리드-영역-이름/
- 원문 (새 창) web.dev/baseline
- 원문 (새 창) web.dev/blog/same-document-view-transitions-are-now-baseline-newly-available
- 원문 (새 창) developer.mozilla.org/en-US/docs/Web/CSS/anchor-name
- GitHub 원문 (새 창) github.com/yui/yui3/wiki/Graded-Browser-Support
- 원문 (새 창) www.filamentgroup.com/lab/grade-the-components.html