화면 밖에 있는 요소의 렌더링을 건너뛰어도 된다고 브라우저에 알려 주는 CSS 속성. auto를 주면 뷰포트에서 멀리 있는 요소의 레이아웃·페인트를 생략하므로, 긴 페이지의 첫 렌더링과 스크롤이 빨라진다.
| 값 | 동작 |
|---|---|
visible(기본) | 평소처럼 렌더링 |
auto | 화면 근처에 올 때만 내용을 렌더링 |
hidden | 내용을 렌더링하지 않음. 렌더링 상태는 캐시해 둬서 다시 보일 때 빠르다 |
.card {
content-visibility: auto;
contain-intrinsic-size: auto 300px; /* 렌더링 전 예상 높이 */
}contain-intrinsic-size가 필요한 이유
내용을 건너뛴 요소는 높이가 0인 것처럼 계산된다. 그러면 스크롤바 크기가 엉망이 되고, 스크롤하다 요소가 렌더링되면서 위치가 튄다. contain-intrinsic-size는 렌더링 전에 쓸 자리 크기를 정해 준다. 앞에 auto를 붙이면 한 번 렌더링된 뒤에는 실제 크기를 기억한다. 값은 대략이면 충분하다. DevTools에서 몇 개 재 보고 평균을 넣고, 빠르게 스크롤했을 때 크게 튀지 않으면 된다.
동작 원리와 주의점
content-visibility: auto는contain: layout style paint를 함께 건다. 요소 안의 변화가 밖에 영향을 주지 않는다고 보장하는 CSS Containment이고, 그래서 리플로우가 바깥으로 번지지 않는다.contain만 따로 써도 레이아웃 스래싱의 범위를 줄일 수 있다hidden은display: none과 달리 렌더링 상태를 버리지 않아 탭 UI처럼 자주 바뀌는 곳에 좋다- 건너뛴 내용도 DOM(Document Object Model)과 접근성 트리(Accessibility Tree)에 남아 있어 페이지 내 찾기·앵커 이동·폼 제출이 동작한다
body같은 최상위가 아니라 반복되는 섹션·카드 단위에 건다- 화면에 들어오고 나갈 때
contentvisibilityautostatechange이벤트가 온다. 화면 밖 애니메이션이나 rAF 루프를 멈추는 데 쓴다
가상화와 비교
DOM 노드는 그대로 두고 계산만 건너뛰므로 CSS 한 줄로 끝나지만, 수만 개 항목처럼 DOM 자체가 너무 크면 한계가 있다. 그때는 보이는 항목만 DOM에 두는 리스트 가상화(List Virtualization)가 낫다. 수백~수천 개 정도면 content-visibility로 충분한 경우가 많다.
지원: Chrome·Edge 85+, Firefox 125+, Safari 18+(2026 기준). 지원하지 않는 브라우저는 무시하므로 점진적으로 적용해도 안전하다.