4
头图

Before introducing the new CSS property contain , readers first need to understand what page redrawing and rearrangement are.

I have described it many times before. If you don’t know much about it, you can take a look at this improve the performance of CSS animation.

OK, enter the topic of this article below,

contain ?

contain attribute allows us to specify a specific DOM element and its child elements so that they can be independent of the entire DOM tree structure. The purpose is to enable the browser to have the ability to redraw and rearrange only part of the elements without having to target the entire page every time.

The contain property allows an author to indicate that an element and its contents are, as much as possible, independent of the rest of the document tree. This allows the browser to recalculate layout, style, paint, size, or any combination of them for a limited area of the DOM and not the entire page.

contain Syntax

Take a look at its syntax:

{
  /* No layout containment. */
  contain: none;
  /* Turn on size containment for an element. */
  contain: size;
  /* Turn on layout containment for an element. */
  contain: layout;
  /* Turn on style containment for an element. */
  contain: style;
  /* Turn on paint containment for an element. */
  contain: paint;

  /* Turn on containment for layout, paint, and size. */
  contain: strict;
  /* Turn on containment for layout, and paint. */
  contain: content;
}

Excluding none , there are 6 more values. Let's take a look at them one by one.

contain: size

contain: size: contain: size set will not be affected by the content of its child elements.

The value turns on size containment for the element. This ensures that the containing box can be laid out without needing to examine its descendants.

I started to see that this definition was also at a loss, and it was difficult to understand what it meant by just looking at the definition. Need some practice:

Suppose we have the following simple structure:

<div class="container">
   
</div>
.container {
    width: 300px;
    padding: 10px;
    border: 1px solid red;
}

p {
    border: 1px solid #333;
    margin: 5px;
    font-size: 14px;
}

And, with the help of jQuery, add a <p>Coco</p> structure every time the container is clicked:

$('.container').on('click', e => {
    $('.container').append('<p>Coco</p>')
})

Then you will get the following result:

containsize

It can be seen that .container will increase with the increase of elements, which is a normal phenomenon.

At this moment, when we add a contain: size .container , the above will also appear: The rendering of the element with 0609b5183d357a set to contain: size will not be affected by the content of its child elements .

.container {
    width: 300px;
    padding: 10px;
    border: 1px solid red;
+   contain: size
}

Let's see what happens again:

containsize2

Normally, the height of the parent element will be increased due to the increase of child elements, but now, the change of the child element no longer affects the style layout of the parent element, this is the role of contain: size

contain: style

Next, contain: layout talk about contain: style , 0609b5183d35f9, contain: paint . Take a look at contain: style first.

As of the writing of this article, contain: style been temporarily removed.

CSS Containment Module Level 1: Drop the at-risk “style containment” feature from this specification, move it Level 2。

Well, the official rhetoric is because there are certain risks, it has been temporarily removed, and it may be redefined in the second edition of the specification, so this attribute should be put aside for the time being.

contain: paint

contain: paint: contain: paint set the layout restriction, which means that the user agent is informed that the child elements of this element will not be displayed outside the boundary of this element. Therefore, if the element is not on the screen or Setting it as invisible in other ways can also ensure that its descendants are invisible and will not be rendered.

This value turns on paint containment for the element. This ensures that the descendants of the containing box don’t display outside its bounds, so if an element is off-screen or otherwise not visible, its descendants are also guaranteed to be not visible.

This is a little easier to understand, let's look at the first feature first:

The child elements of the element with contain: paint set will not be displayed outside the boundary of this element

  • The child elements of the element with contain: paint set will not be displayed outside the boundary of this element

This feature is somewhat similar to overflow: hidden , which means that the user agent is clearly informed that the content of the child element will not exceed the boundary of the element, so the excess part does not need to be rendered.

A simple example, assuming the element structure is as follows:

<div class="container">
    <p>Coco</p>
</div>
.container {
    contain: paint;
    border: 1px solid red;
}

p{
    left: -100px;
}

Let's take a look, contain: paint is set and when it is not set:

containsize3

CodePen Demo -- contain: paint Demo

The element with contain: paint will not be rendered when it is off the screen

By using contain: paint , if the element is off-screen, the user agent will ignore rendering these elements, so that other content can be rendered faster.

contain: layout

contain: layout: contain: layout set the layout restriction, that is to say, inform the user agent that the style change inside this element will not cause the style change outside the element, and vice versa.

This value turns on layout containment for the element. This ensures that the containing box is totally opaque for layout purposes; nothing outside can affect its internal layout, and vice versa.

Enabling contain: layout can potentially reduce the number of elements that need to be rendered per frame to a few, instead of re-rendering the entire document, saving the browser a lot of unnecessary work and significantly improving performance.

Using contain:layout , developers can specify that any changes to any descendants of this element will not affect the layout of any external elements, and vice versa.

Therefore, the browser only calculates the position of the internal element (if it is modified), and the rest of the DOM remains unchanged. Therefore, this means that the layout process in the frame rendering pipeline will speed up.

The problem

The description is very good, but in the actual Demo test process (as of April 27, 2021, Chrome 90.0.4430.85), just using contain:layout alone did not verify the above-mentioned beautiful results.

sets the contain: layout . Any changes to any descendants of the changed element will still affect the layout of any external element . Clicking the red box will add a <p>Coco<p> element and insert it into container :

The simple code is as follows:

<div class="container">
    <p>Coco</p>
    ...
</div>
<div class="g-test"></div>
html,
body {
    width: 100%;
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    flex-direction: column;
    gap: 10px;
}

.container {
    width: 150px;
    padding: 10px;
    contain: layout;
    border: 1px solid red;
}

.g-test {
    width: 150px;
    height: 150px;
    border: 1px solid green;
}

CodePen Demo -- contain: layout Demo

At present, contain: layout is not so obvious. For more about its usage, you can read this article: CSS-tricks-contain

contain: strict | contain: content

These two attributes are a little bit special, and the effect is the aggregation effect of the several attributes described above:

  • contain: strict : Turn on the functions of layout, style, paint and size at the same time, which is equivalent to contain: size layout paint
  • contain: content : Turn on the functions of layout, style and paint at the same time, which is equivalent to contain: layout paint

Therefore, it is also mentioned here that the contain attribute can define several at the same time.

Can i Use -- CSS Contain

As of 2021-04-27, the CSS Contain compatibility on Can i Use can already be used:

references

At last

Okay, this concludes this article, I hope it helps you :)

More wonderful CSS technical articles are summarized in my Github - iCSS , which will be updated continuously. Welcome to click a star to subscribe to the collection.

If you have any questions or suggestions, you can exchange more, original articles, limited writing style, and lack of knowledge. If there are any irregularities in the article, please let me know.


chokcoco
12.3k 声望18.5k 粉丝