CSS Contain 속성으로 브라우저 최적화 지원

게시 됨: 2022-03-10
빠른 요약 ↬ CSS contain 속성은 브라우저에 레이아웃을 설명하는 방법을 제공하므로 성능을 최적화할 수 있습니다. 그러나 레이아웃 측면에서 몇 가지 부작용이 있습니다.

이 기사에서는 W3C 권장 사항이 된 CSS 사양을 소개합니다. CSS 포함 사양은 단일 속성인 contain 을 정의하며 레이아웃의 어떤 부분이 독립적이고 레이아웃의 다른 부분이 변경되는 경우 다시 계산할 필요가 없는지 브라우저에 설명하는 데 도움이 될 수 있습니다.

이 속성은 성능 최적화를 위해 존재하지만 페이지 레이아웃에도 영향을 줄 수 있습니다. 따라서 이 기사에서는 혜택을 받을 수 있는 다양한 억제 유형과 사이트의 요소에 contain 을 적용할 때 주의해야 할 사항에 대해 설명합니다.

레이아웃 재계산 문제

JavaScript를 사용하여 로드한 후 요소를 동적으로 추가하거나 변경하지 않는 간단한 웹 페이지를 구축하는 경우 CSS Containment가 해결하는 문제에 대해 걱정할 필요가 없습니다. 브라우저는 페이지가 로드될 때 레이아웃을 한 번만 계산하면 됩니다.

Containment가 유용한 곳은 사용자가 페이지를 다시 로드할 필요 없이 페이지에 요소를 추가하려는 경우입니다. 내 예에서는 큰 이벤트 목록을 만들었습니다. 버튼을 클릭하면 첫 번째 이벤트가 수정되고 float된 요소가 추가되고 텍스트가 변경됩니다.

첫 번째 항목의 일부 콘텐츠를 변경할 수 있는 버튼이 있는 항목 목록
(CodePen의 초기 예제 참조)

상자의 내용이 변경되면 브라우저는 요소가 변경되었을 수 있음을 고려해야 합니다. 브라우저는 일반적으로 발생하는 일반적인 일이므로 일반적으로 이를 잘 처리합니다. 즉, 개발자로서 각 구성 요소가 독립적인지, 하나를 변경해도 다른 구성 요소에 영향을 미치지 않는다는 것을 알게 될 것이므로 CSS를 통해 브라우저에 이를 알릴 수 있다면 좋을 것입니다. 이것이 포함 및 CSS contain 속성이 제공하는 것입니다.

점프 후 더! 아래에서 계속 읽기 ↓

봉쇄가 어떻게 도움이 됩니까?

HTML 문서는 DevTools로 요소를 검사할 때 볼 수 있는 트리 구조입니다. 위의 예에서 JavaScript를 사용하여 변경하려는 항목 하나를 식별한 다음 내부를 일부 변경합니다. (즉, 해당 목록 항목에 대한 하위 트리 내부의 항목만 변경한다는 의미입니다.)

내부 요소를 볼 수 있도록 확장된 추천 항목의 목록 항목이 있는 DevTools
DevTools에서 목록 항목 검사

요소에 contain 속성을 적용하면 변경 사항이 해당 요소의 하위 트리로 범위가 지정되어 브라우저가 가능한 최적화를 수행할 수 있다는 것을 브라우저에 알립니다. 특정 브라우저가 할 수 있는 일은 엔진에 달려 있습니다. CSS 속성은 이 레이아웃의 개발자이자 전문가로서 이를 알릴 수 있는 기회를 제공합니다.

대부분의 경우 바로 가서 contain 속성을 사용하는 것이 안전할 것이지만, 다른 값에는 사이트의 요소에 속성을 추가하기 전에 이해할 가치가 있는 몇 가지 잠재적인 부작용이 있습니다.

봉쇄 사용

contain 속성은 세 가지 다른 유형의 포함을 설정할 수 있습니다.

  • layout
  • paint
  • size

참고 : 레벨 2 사양에는 style 값이 있습니다. 레벨 1에서 제거되었으므로 권장 사항에 나타나지 않으며 Firefox에서 구현되지 않습니다.

형세

레이아웃 억제는 가장 큰 이점을 제공합니다. 레이아웃 포함을 켜려면 다음 스니펫을 사용하세요.

 .item { contain: layout; }

레이아웃 포함이 활성화되면 브라우저는 요소 외부의 어떤 것도 내부 레이아웃에 영향을 줄 수 없으며 요소 내부의 어떤 것도 외부의 레이아웃에 대해 아무 것도 변경할 수 없다는 것을 알고 있습니다. 이는 이 시나리오에 대해 가능한 최적화를 수행할 수 있음을 의미합니다.

레이아웃 포함이 활성화되면 몇 가지 추가 작업이 발생합니다. 이것들은 이 상자와 내용이 나머지 트리와 독립적임을 보장하는 모든 것입니다.

상자는 독립적인 서식 컨텍스트 를 설정합니다. 이렇게 하면 상자의 내용이 상자에 유지됩니다. 특히 부동 소수점이 포함되고 여백이 상자를 통해 축소되지 않습니다. 이것은 내 기사 "CSS 레이아웃 및 블록 형식 지정 컨텍스트 이해"에서 설명한 대로 display: flow-root 를 사용할 때 켜는 것과 동일한 동작입니다. 플로트가 상자 밖으로 튀어나와 다음 텍스트가 플로트 주위로 흐를 수 있는 경우 요소 외부의 레이아웃을 변경하여 격리 대상이 되지 않는 상황이 될 수 있습니다.

포함 상자는 절대 위치 또는 고정 위치 하위 항목에 대한 포함 블록 역할을 합니다. 이것은 당신이 적용한 상자에 position: relative 를 사용한 것처럼 작동한다는 것을 의미 contain: layout .

상자는 또한 스택 컨텍스트 를 만듭니다. 따라서 z-index 은 이 요소에서 작동하고 이 요소의 자식은 이 새 컨텍스트를 기반으로 누적됩니다.

이번에는 contain: layout 을 사용하여 예제를 보면 부동 요소가 도입될 때 더 이상 상자의 바닥을 찌르지 않는다는 것을 알 수 있습니다. 이것은 float를 포함하는 작동 중인 새로운 블록 형식 지정 컨텍스트입니다.

항목 목록, 부동 요소는 상위 상자의 경계 내부에 포함됩니다.
포함 사용: float가 포함된 레이아웃(CodePen의 레이아웃 포함 예제 참조)

페인트

페인트 봉쇄를 켜려면 다음을 사용하십시오.

 .item { contain: paint; }

페인트 포함이 활성화되면 레이아웃 포함에서 볼 수 있는 것과 동일한 부작용이 발생합니다. 포함 상자는 독립적인 서식 컨텍스트가 되고, 배치된 요소에 대한 포함 블록이 되고, 스택 컨텍스트가 설정됩니다.

페인트 포함이 하는 일은 포함 블록 내부의 요소가 해당 상자의 경계 외부에서 표시되지 않는다는 것을 브라우저에 표시하는 것입니다. 내용은 기본적으로 상자에 잘립니다.

우리는 간단한 예를 통해 이것이 일어나는 것을 볼 수 있습니다. 카드에 높이를 지정하더라도 플로트가 흐름에서 제거된다는 사실 때문에 플로트된 항목은 여전히 ​​상자 바닥을 찌릅니다.

포함 상자의 바닥을 파고 있는 떠 있는 상자
목록 항목에 부동 소수점이 포함되어 있지 않습니다.

페인트 포함이 켜져 있으면 떠 있는 항목이 이제 상자 크기로 잘립니다. contain: paint 적용된 요소의 경계 외부에는 아무 것도 칠할 수 없습니다.

상자를 벗어나는 부분이 잘린 내부에 떠 있는 상자가 있는 상자
상자의 내용이 상자 높이에 맞게 잘립니다(CodePen의 페인트 예제 참조).

크기

크기 억제는 작동 방식을 완전히 인식하지 못하는 경우 문제를 일으킬 가능성이 가장 높은 값입니다. 크기 억제를 적용하려면 다음을 사용하십시오.

 .item { contain: size; }

크기 억제를 사용하는 경우 브라우저에 상자의 크기를 알고 있으며 변경되지 않을 것임을 알리는 것입니다. 즉, 블록 차원에서 자동 크기 조정되는 상자가 있는 경우 콘텐츠에 크기가 없는 것처럼 처리되므로 상자가 콘텐츠가 없는 것처럼 축소됩니다.

아래 예에서는 li 에 높이를 지정하지 않았습니다. 그들은 또한 다음을 contain: size 적용되었습니다. 내용이 전혀 없는 것처럼 모든 항목이 축소되어 매우 독특한 목록을 만드는 것을 볼 수 있습니다!

첫 번째 항목의 일부 콘텐츠를 변경할 수 있는 버튼이 있는 항목 목록
(CodePen의 크기 예 참조)

상자에 높이를 지정하면 contain: size 가 사용됩니다. 단독으로 크기 포함은 새 서식 컨텍스트를 생성하지 않으므로 레이아웃 및 페인트 포함에서와 같이 부동 소수점 및 여백을 포함하지 않습니다. 혼자 사용할 가능성은 적습니다. 대신, 가장 가능한 억제를 얻을 수 있도록 다른 값의 contain 과 함께 적용할 가능성이 큽니다.

약칭 값

대부분의 경우 두 가지 약식 값 중 하나를 사용하여 격리를 최대한 활용할 수 있습니다. 레이아웃 및 페인트 포함을 켜려면 contain: content; , 가능한 모든 억제 기능을 켜려면(크기가 없는 항목은 축소된다는 점을 염두에 두십시오), contain: strict 을 사용하십시오.

사양은 다음과 같이 말합니다.

" contain: content 가 광범위하게 적용하기에 합리적으로 "안전"합니다. 그 효과는 실제로 매우 미미하며 대부분의 콘텐츠는 제한 사항을 위반하지 않습니다. 그러나 크기 제한을 적용하지 않기 때문에 요소는 여전히 콘텐츠의 크기에 응답할 수 있으며, 이로 인해 레이아웃 무효화가 원하는 것보다 트리 위로 더 많이 침투할 수 있습니다. 가능한 한 많은 격리를 얻으려면 가능한 한 contain: strict 하십시오."

따라서 항목의 크기를 미리 모르고 float와 margin이 포함될 것이라는 사실을 알고 있다면 contain: content 를 사용하십시오. 격리의 다른 부작용에 대해 만족하는 것 외에도 항목의 크기를 알고 있다면 contain: strict 을 사용합니다. 나머지는 브라우저에 달려 있습니다. 레이아웃이 작동하는 방식을 설명하여 약간의 작업을 완료했습니다.

지금 격리를 사용할 수 있습니까?

CSS Containment 사양은 이제 W3C 권장 사항으로, 우리가 때때로 웹 표준 이라고 부르는 것입니다. 사양이 이 단계에 도달하려면 Firefox와 Chrome 모두에서 볼 수 있는 기능의 두 가지 구현이 필요했습니다.

Can I Use에 대한 억제에 대한 브라우저 지원 정보의 스크린샷
억제를 위한 브라우저 지원(출처: Can I Use)

이 속성은 사용자에게 투명하므로 지원하지 않는 브라우저에 방문자가 많더라도 모든 사이트에 추가하는 것이 완전히 안전합니다. 브라우저가 억제를 지원하지 않는 경우 방문자는 일반적으로 얻는 경험을 얻고 지원하는 브라우저에 있는 방문자는 향상된 성능을 얻습니다.

구성 요소 또는 패턴 라이브러리에서 생성하는 구성 요소에 추가하는 것이 좋습니다. 이러한 방식으로 작업하는 경우 각 구성 요소가 다른 요소에 영향을 주지 않는 독립적인 것으로 설계될 가능성이 높습니다. 페이지, contain: content 를 유용한 추가 기능으로 만듭니다.

따라서 로드 후 DOM에 콘텐츠를 추가하는 페이지가 있다면 시도해 보는 것이 좋습니다. 흥미로운 결과를 얻으면 댓글로 알려주세요!

관련 리소스

다음 리소스는 억제 구현 및 잠재적인 성능 이점에 대한 세부 정보를 제공합니다.

  • "CSS 속성 contain ", MDN 웹 문서
  • Google 개발자 , "Chrome 52의 CSS 포함"
  • "CSS Containment Module Level 1", W3C 권장 사항
  • "CSS 포함에 대한 소개", Manuel Rego Casasnovas