CSS Containment

От переводчика: слог у Пола Льюиса весьма своеобразный, поэтому перевод исходной статьи местами может выглядеть странно. Замечания приветствуются.

Containment (сдерживание) – новое CSS свойство, позволяющее разработчикам ограничить область применения стилей, компоновок и отрисовок для браузера.

image

Свойство поддерживает несколько значений, и его синтаксис выглядит следующим образом:

contain: none | strict | content | [ size || layout || style || paint ]

Свойство уже есть в браузерах Chrome 52+ и Opera40+, а так же оно публично поддерживается Firefox’ом, поэтому дайте ему шанс и расскажите о том, что у вас получилось.

Свойство contain


При создании веб-приложения или сложного сайта ключевая задача достижения высокой производительности – это снижение затрат на применение стилей (styles), уменьшение количества компоновок (layout) и отрисовок (paint). Зачастую DOM-дерево целиком оказывается в области пересчёта (scope), что может произойти при хитрой попытке создания автономного объекта (блока) в веб-приложении: в этом случае изменения в одной части DOM-дерева могут повлиять так же на другие элементы, и у разработчика не будет возможности указать браузеру, что должно быть внутри области пересчёта и что – за её пределами.

Рассмотрим пример, допустим часть вашего DOM-дерева выглядит примерно так:

<section class="view">
  Home
</section>
<section class="view">
  About
</section>
<section class="view">
  Contact
</section>

И затем вы добавляете новый элемент к одному из блоков, за чем последует изменение стилей, компоновка и отрисовка:

<section class="view">
  Home
</section>
<section class="view">
  About
  <div class="newly-added-element">Check me out!</div>
</section>
<section class="view">
  Contact
</section>

Однако в этом случае DOM-дерево целиком окажется в области, которую необходимо изменить, перекомпоновать и заново отрисовать, вне зависимости от того, были ли его элементы задействованы. И чем больше DOM-дерево, тем больше вычислений придётся выполнить, отчего со временем ваше веб-приложение может перестать отвечать пользователю.

На самом деле всё не так уж и плохо, есть и хорошие новости: современные браузеры становятся умнее и стараются ограничить область применения стилей, компоновки и отрисовки автоматически, и вам не приходится ничего делать, чтобы ускорить эти процессы. Но есть новость и получше: появилось новое CSS свойство, вручающее в руки разработчиков полный контроль над областью – Containment.

CSS Containment – новое свойство, принимающим своим значением одно из 4-х ключевых слов:

  • layout
  • paint
  • size
  • style

Каждое из них позволит вам выбрать, как именно ограничить работу браузера во время рендеринга. Давайте взглянем поближе на эти значения.

Layout (contain: layout)


Это значение включает режим сдерживания компоновки элемента. В таком случае компоновка документа гарантированно не взаимодействует с содержащим блоком: ничего за пределами блока не может повлиять на его внутреннюю компановку и наоборот.

Сдерживание компоновки, возможно, можно считать самым выгодным наряду с contain: paint.

Как правило, компоновка затрагивает весь документ, т.е. она пропорциональна размеру вашего DOM-дерева, поэтому если вам захочется изменить свойство left одного из элементов, то изменения могут коснуться каждого элемента DOM. Поэтому потенциально при включении сдерживания мы можем увеличить производительность, позволив браузеру не выполнять ненужную работу, перекомпоновывая небольшое число элементов вместо всего документа.

Paint (contain: paint)


Это свойство включает режим сдерживания отрисовки для элемента. Оно гарантирует, что потомки элемента не будут отображены за его пределами, поэтому если элемент находится за пределами видимости, то и его содержимое так же обязательно будет невидимым.

Отрисовка отдельной области — другое чрезвычайно полезное преимущество сдерживания. Управление отрисовкой фактически обрезает элемент (т.е. содержимое невидимо за границами), что влечет за собой несколько побочных эффектов:

  • Для абсолютно и фиксировано позиционированных элементов данный блок действует как сдерживающий блок. Это означает, что любые дочерние блоки позиционируются на основе элемента со свойством contain: paint, а не каких-либо других элементов или же всего документа.

  • У элемента создается контекст наложения. Свойство z-index будет влиять на элемент, а все потомки элемента будут наложены согласно новому контексту.

  • Также появляется новый контекст форматирования. К примеру, если у вас есть блочный элемент, у которого задано свойство contain: paint, то он будет рассматриваться как новое и независимое окружение компоновки. Это значит, что компоновка извне не повлияет на содержимое сдерживающего элемента.

Size (contain: size)


Это значение включает режим управления размером элемента, что обеспечит данному элементу наложение, не принимая во внимания его потомков.

contain: size запрещает дочерним блокам элемента влиять на его заданные размеры. Следовательно, если вы установили свойство containt со значением size некоторому элементу, не указав при этом его размеры (напрямую или с помощью flex-свойств), то этот элемент будет отображен с размерами 0px на 0px.

В самом деле, управление размером (сдерживание размера) – надежный способ обеспечить независимость размеров элемента от его потомков, но сам по себе он не дает особых преимуществ.

Style (contain: style)


Это значение включает режим управления стилем (сдерживания стилей) элемента. При этом режиме те свойства, которые могут повлиять сразу на несколько элементов и их потомков, не будут использованы за пределами сдерживающего элемента.

Сложно заранее предугадать, какие эффекты от изменения стилей пойдут вверх по DOM-дереву. Одним из примеров такого поведения — нечто вроде вроде CSS счетчиков, где изменение счетчика у дочернего блока может повлиять на значения счетчиков с одноименным названием, используемых в другом месте в документе. С заданным contain: style стили заданного элемента не будут распространены выше по DOM-дереву.

Говоря предельно ясно, чего contain: style не предоставляет вам в отличие от Shadow DOM, так это scoped styling (стили с ограниченной областью видимости). Сдерживание в таком случае подразумевает лишь только ограничение элементов дерева, которые будут рассматриваться при изменении стилей, но не тогда, когда они были объявлены.

Строгое (strict) и содержательное (content) сдерживание


При необходимости вы можете комбинировать значения свойства, к примеру, при contain: layout paint, вы сможете добиться для элемента только таких типов поведения.

Но рассматриваемое в статье свойство так же поддерживает 2 дополнительных значения:

  • contain: strict то же самое, что и contain: layout style paint size
  • contain: content то же самое, что и contain: layout style paint

Использование строгого сдерживания может здорово пригодиться, если вы заранее знаете размеры элемента (или заранее хотите сохранить их), но имейте в виду, что если вы выберете строгое сдерживание без указания размеров из-за предполагаемого размера содержимого, элемент может быть отображен с размерами 0px на 0px.

Сдерживание содержимого, с другой стороны, предлагает значительные улучшения области пересчёта, но не требует от вас знания конкретных размеров элементов заранее. Кстати говоря, contain: content можно использовать по умолчанию.

К более строгим ограничениям прибегайте как к аварийному люку, лишь тогда, когда эффектов от использования contain: content недостаточно в конкретно вашем случае.

Сдерживание – отличный способ указания браузеру, что вы намерены изолировать в пределах вашей страницы. Попробуйте использовать это свойство в Chrome 52+ и расскажите нам, что вы об этом думаете.

Similar posts

Ads
AdBlock has stolen the banner, but banners are not teeth — they will be back

More

Comments 10

    +26

    Без наглядных примеров всё это не понятно что делает. Тем более описано это таким "предельно ясным" языком.


    Чем contain: paint отличается от overflow: hidden? Чем contain: size отличается от простого указания width и height?

      –9
      Добавлен скриншот из исходной статьи. На нём заметна огромная экономия времени работы.
        +14

        Оставьте скриншоты гуманитариям, покажите мне код! :-)

          +3
          На скриншоте показан итог, а не механизм работы.
          +4
          Присоединяюсь!
            0
            Попробовал поэксперементировать с поведением contain: size.
            Поведение почти 1 в 1 как у строго заданных width/height. Однако наткнулся на кое-что странное:
            https://jsfiddle.net/z3x4sev3/
            В Chrome 52.0.2743.116 элемент с display: inline-block и contain: size по умолчанию вертикально выравнен по baseline (слева элемент с contain: size, справа элемент с height: 0, зеленым обозначен их общий родитель):

            А вот как замерить производительность с данным свойством и без него я честно говоря не понимаю.
            При анимации как вызывающих relayout свойств (font-size, padding), так и не вызывающих (background-color) у одного элемента из 6 тысяч время layout и paint примерно одно и то же не зависимо от установки свойства contain: size на анимируемый элемент (у всех элементов фиксированный width и height). Та же ситуация и с анимацией одновременно 2 тысяч элементов (что с contain: size на каждом, что без него, разницы нет)
              0
              Это статья-перевод, просто north-elbrus почему-то это не указала. Почитал оригинал, у Пола Льюса написано не сильно понятней. Полагаю, теперь кому-то надо сделать разбор полетов по этому свойству)
                +2
                Данное свойство нужно для ограничивания стилей в определенном слое.
                Например если у вас есть различные виджеты, подгружаемые с другого сайта. Чтобы стили сайта не распространялись на виджет, можно будет прописать ему contain (contain content)
                Также можно использовать для скрытых на экране элементов, чтобы браузер отрисовывал их только когда они видны (contain paint)
                +1

                CSS-стили, предназначенные исключельно для оптимизации производительности — интересный поворот.

                  0
                  Вообще-то оно для ограничения области применения стилей, о чём написано во втором абзаце статьи.

                Only users with full accounts can post comments. Log in, please.