프로그래밍/HTML, Javascript, CSS

CSS content-visibility 기준

포도알77 2026. 8. 14. 12:33

CSS content-visibility는 브라우저가 요소의 내부 렌더링 작업을 언제까지 미룰 수 있는지 알려주는 속성입니다. 긴 문서, 검색 결과 목록, 대시보드의 아래쪽 패널처럼 처음 화면에 보이지 않는 영역이 많을 때 초기 렌더링 비용을 줄이는 데 쓰입니다.

결론부터 말하면 성능 개선 목적으로는 대부분 content-visibility: autocontain-intrinsic-size를 함께 검토합니다. auto만 붙이면 브라우저가 화면 밖 내용을 건너뛸 수 있지만, 아직 그리지 않은 영역의 크기를 어떻게 잡을지 정하지 않으면 스크롤 중 레이아웃 이동이 생길 수 있습니다.

content-visibility는 무엇을 줄일까

웹 페이지를 화면에 보여주려면 브라우저가 스타일 계산, 레이아웃, 페인트 같은 렌더링 작업을 처리해야 합니다. content-visibility는 요소의 subtree가 지금 사용자에게 필요한지에 따라 그 내부 작업을 생략하거나 늦출 수 있게 합니다.

MDN과 CSS Containment Module Level 2 기준으로 content-visibility의 값은 visible, hidden, auto입니다. 이 중 성능 최적화에서 핵심이 되는 값은 auto입니다.

.article-section {
  content-visibility: auto;
  contain-intrinsic-size: auto 640px;
}

위 코드는 각 섹션이 화면 밖에 있을 때 브라우저가 내부 렌더링을 늦출 수 있게 하고, 아직 실제 크기를 계산하지 않은 상태에서는 대략 640px 높이의 자리표시자를 사용할 수 있게 합니다.

auto는 hidden과 어떻게 다를까

visible은 기본값입니다. 특별한 최적화 힌트를 주지 않고 요소의 내용을 평소처럼 렌더링합니다. 기존 동작을 바꾸고 싶지 않다면 이 상태가 기준입니다.

hidden은 요소의 내용을 건너뜁니다. MDN은 이 값의 skipped contents가 찾기, 탭 순서, 선택, 포커스 같은 사용자 에이전트 기능에 노출되지 않아야 하며 display: none을 준 것과 비슷하다고 설명합니다. 다만 display와 같은 속성 자체는 아니므로 UI 상태를 보존하면서 숨기는 목적에 쓰일 수 있습니다.

auto는 성격이 다릅니다. 요소에 layout, style, paint containment를 적용하고, 해당 요소가 사용자에게 relevant하지 않으면 내부 렌더링을 건너뛸 수 있습니다. 이때 화면 밖 내용도 DOM과 접근성 트리에 남고, 페이지 내 찾기나 탭 이동 같은 기능에서는 정상적으로 다뤄져야 합니다.

주 용도 주의할 점
visible 기본 렌더링 성능 최적화 힌트가 없음
auto 화면 밖 영역의 렌더링 비용 절감 크기 예약을 함께 설계해야 함
hidden 내용을 의도적으로 숨기는 상태 관리 찾기, 포커스, 선택 대상에서 제외되는 성격을 고려해야 함

contain-intrinsic-size는 왜 같이 쓸까

content-visibility: auto는 화면 밖 내부 내용을 나중에 그릴 수 있게 합니다. 문제는 그 내부를 아직 레이아웃하지 않았다면 브라우저가 실제 높이를 알기 어렵다는 점입니다. 이때 대체 크기가 없으면 스크롤 위치가 흔들리거나, 뒤늦게 내용이 그려지면서 아래쪽 요소가 밀릴 수 있습니다.

contain-intrinsic-size는 이런 상황에서 사용할 가상의 고유 크기를 제공합니다. MDN 예시는 contain-intrinsic-size: auto 500px처럼 작성해 섹션마다 기본 크기를 주고, 실제 렌더링 후에는 계산된 크기를 재사용하는 형태를 보여줍니다.

무난한 기준은 실제 콘텐츠 평균 높이에 가까운 값을 잡는 것입니다. 카드 목록이라면 카드 한 줄 또는 몇 줄의 높이를 기준으로 삼고, 문서 섹션이라면 대표 섹션의 높이를 측정해 너무 작거나 크게 잡지 않는 편이 좋습니다.

어디에 적용하는 것이 좋을까

content-visibility: auto는 독립적인 큰 블록에 잘 맞습니다. 예를 들어 긴 기술 문서의 섹션, 제품 목록의 아래쪽 묶음, 댓글 목록, 접힌 상태가 아닌 대시보드 하단 위젯처럼 각 영역이 어느 정도 독립되어 있으면 효과를 기대할 수 있습니다.

반대로 작은 버튼, 입력 필드, 헤더, 내비게이션, 화면 첫 영역처럼 항상 즉시 보여야 하는 요소에는 보통 맞지 않습니다. 영역이 작으면 생략할 렌더링 비용도 작고, 핵심 인터랙션 요소에 containment를 걸면 디버깅할 지점만 늘어날 수 있습니다.

상황 판단 이유
긴 문서의 아래쪽 섹션 검토 가능 초기 화면 밖 렌더링을 늦출 수 있음
반복 카드 목록 검토 가능 묶음 단위로 비용을 줄이기 쉬움
상단 내비게이션 부적합 항상 즉시 필요하고 영역이 작음
폼 입력 영역 신중 포커스, 검증, 자동완성 흐름을 확인해야 함

JavaScript와 충돌할 수 있을까

성능 이득은 브라우저가 내부 렌더링을 실제로 건너뛸 수 있을 때 생깁니다. 그런데 코드가 화면 밖 subtree의 레이아웃 정보를 강제로 읽으면 브라우저는 계산을 미룰 수 없습니다. 예를 들어 특정 영역의 크기나 위치를 계속 측정하는 코드가 있으면 기대한 만큼의 개선이 나오지 않을 수 있습니다.

따라서 적용 전후로 성능 측정을 해야 합니다. Chrome DevTools의 Performance 패널, Core Web Vitals, 실제 사용자 환경의 Interaction to Next Paint 같은 지표를 확인해 초기 렌더링과 상호작용 비용이 줄었는지 봐야 합니다. 공식 문서의 설명은 동작 원리이고, 실제 개선 폭은 페이지 구조와 스크립트 사용 방식에 따라 달라집니다.

접근성에서는 무엇을 확인할까

content-visibility: auto의 화면 밖 내용은 DOM과 접근성 트리에 남는 것이 핵심 차이입니다. 성능 최적화를 하면서도 찾기나 키보드 탐색이 가능한 구조를 유지하려는 목적에 맞습니다.

다만 화면 밖에 있는 콘텐츠 내부에 원래 display: none이나 visibility: hidden으로 숨긴 보조 요소가 있다면 주의가 필요합니다. MDN은 오프스크린 콘텐츠의 스타일이 아직 렌더링되지 않은 상태에서는 의도적으로 숨긴 요소가 접근성 트리에 나타날 수 있으므로, 접근성 트리에서 제외하려면 aria-hidden="true" 같은 명시적 처리를 검토하라고 설명합니다.

전환 효과에도 쓸 수 있을까

MDN 기준으로 content-visibility는 CSS transition에서 다룰 수 있지만, discrete transition이므로 transition-behavior: allow-discrete가 필요합니다. display 전환처럼 시작 스타일을 별도로 다뤄야 하는 경우와는 차이가 있습니다.

.panel {
  transition:
    opacity 160ms ease,
    content-visibility 160ms allow-discrete;
}

.panel.is-closed {
  opacity: 0;
  content-visibility: hidden;
}

전환 효과 목적으로 사용할 때도 기준은 같습니다. 단순한 표시 전환인지, 상태를 보존해야 하는지, 접근성 트리에서 제외되어야 하는지 먼저 정해야 합니다. 시각적으로만 숨겨야 하는 상황과 사용자 에이전트 기능에서도 제외해야 하는 상황은 같은 문제가 아닙니다.

브라우저 지원은 어떻게 봐야 할까

MDN은 content-visibility를 Baseline 2024로 표시하며, 2024년 9월 이후 최신 주요 브라우저에서 사용할 수 있는 기능으로 설명합니다. 다만 Baseline 표시는 최신 기기와 브라우저 기준이므로 오래된 WebView, 사내 브라우저, 구형 모바일 환경까지 포함한다면 실제 지원 범위를 따로 확인해야 합니다.

호환성이 중요한 서비스에서는 content-visibility 없이도 문서가 정상적으로 보이도록 작성한 뒤, 지원되는 환경에서 성능 힌트로만 작동하게 두는 방식이 안전합니다. 이 속성은 의미 구조를 대체하는 기능이 아니라 렌더링 최적화 힌트에 가깝게 다루는 편이 좋습니다.

자주 묻는 질문

content-visibility: auto만 붙이면 충분할까

대개 충분하지 않습니다. 화면 밖 내용을 늦게 그릴 수는 있지만, 그 영역의 예상 크기를 함께 잡지 않으면 스크롤 중 레이아웃 이동이 생길 수 있습니다. 그래서 contain-intrinsic-size를 같이 검토합니다.

display: none을 대체해도 될까

항상 대체할 수 있는 속성은 아닙니다. display: none은 요소를 레이아웃에서도 제거합니다. content-visibility는 렌더링 작업 생략과 containment에 초점이 있으므로, 숨김의 의미와 접근성 요구를 먼저 구분해야 합니다.

모든 섹션에 적용하면 성능이 좋아질까

그렇지 않습니다. 큰 오프스크린 영역이 많을수록 유리하고, 작거나 항상 보이는 요소에는 효과가 작습니다. 적용 전후 성능 측정 없이 전역 규칙으로 넣는 것은 피하는 편이 좋습니다.

정리

content-visibility는 브라우저가 지금 필요하지 않은 내부 렌더링 작업을 건너뛸 수 있게 하는 CSS 속성입니다. 성능 최적화에는 auto가 중심이고, 레이아웃 이동을 줄이려면 contain-intrinsic-size를 함께 설계해야 합니다.

실무 기준은 세 가지입니다. 첫째, 긴 문서나 반복 목록처럼 큰 독립 블록에 먼저 적용합니다. 둘째, 크기 예약 없이 auto만 넣지 않습니다. 셋째, 접근성, 찾기, 포커스, JavaScript 측정 코드가 실제 페이지에서 어떻게 동작하는지 확인한 뒤 유지 여부를 결정합니다. 이 글은 2026년 8월 14일 기준 MDN, CSS Containment 사양, web.dev 문서를 바탕으로 정리했습니다.

반응형
페이스북으로 공유카카오톡으로 공유카카오스토리로 공유트위터로 공유URL 복사