Table of Contents
Various usages of contain attribute
size contains
layout contains
paint contains
Various combinations of included
Performance Advantages
Layout once, draw twice
An interesting accidental discovery
Summarize
Home Web Front-end CSS Tutorial Let's Take a Deep Dive Into the CSS Contain Property

Let's Take a Deep Dive Into the CSS Contain Property

Apr 06, 2025 am 10:30 AM

Let's Take a Deep Dive Into the CSS Contain Property

Modern browsers are significantly more efficient in rendering complex HTML, CSS, and JavaScript code of web pages, converting code into available pages in just a few milliseconds.

So, how can front-end developers further improve browser rendering speed? In addition to those best practices that are easily forgotten (especially when we have limited control over the generated code), such as streamlining the CSS selector, keeping the HTML structure flat, and being careful to manipulate HTML and CSS in JavaScript, we can also take advantage of contain properties of CSS.

contain property allows developers to specify to what extent an element and its content is independent of the rest of the document tree. This enables the browser to recalculate layouts, styles, drawings, sizes, or any combination of them only for a limited area of ​​the DOM (rather than the entire page), resulting in a significant performance improvement.

Simply put, contain attribute can provide a prompt for the browser about the relationship between the elements on the page, which are usually container elements that contain content, even if the content is dynamic. For example, in single page applications (SPA), dynamic content is often inserted and deleted in the page, often independent of other content on the page.

The browser cannot predict future layout changes that may result from JavaScript insertion and deletion of page content. Even simple operations, such as adding class names to elements, animate DOM elements, or getting element sizes, can lead to page rearrangement and redrawing, which are expensive and should be avoided or reduced as much as possible.

Developers can predict possible future changes based on the user experience of the page design. For example, when a user clicks a button, the call data will be inserted into a div element in the current view. We know this is possible, but the browser doesn't. We also know that inserting data into the div element will most likely not change the visual effects or other aspects of other elements on the page.

Browser developers have spent a lot of time optimizing their browsers to handle this situation. While there are various ways to help the browser handle this situation more efficiently, more direct tips can be more helpful. contain property provides us with a way to provide these hints.

Various usages of contain attribute

contain attribute has three values, which can be used alone or in combination: size , layout , and paint . It also has two abbreviation values ​​for common combinations: strict and content . Let's understand what each value means.

It should be noted that many rules and edge cases for each value are covered in the specification. In most cases, these rules may not attract much attention. However, if you get unexpected results, a quick look at the specification may be helpful.

There is also a style that contains types in the specification, which will not be introduced in this article. The reason is that the current style inclusion types are considered to be of little value and are currently at risk of being removed from the specification.

size contains

size contains is easy to explain. When the container containing this includes participates in layout calculations, the browser can skip a considerable portion of the calculations because it ignores the child elements of the container. The container is expected to have a set height and width; otherwise, it will collapse, and that is the only factor to consider in the page layout. It is considered as having nothing.

Note that child elements may affect the size of their container, depending on the style of the container. This must be considered when calculating the layout; using size inclusion, it is likely not to be considered. Once the container has been determined relative to the page size, the layout of its child elements will be calculated.

size inclusion itself does not provide much optimization. It is usually used in combination with other values.

However, one benefit it can provide is to help deal with JavaScript that changes container child elements based on container size, such as container query type. In some cases, changing the child element according to the size of the container may cause the container to change the size after making changes to the child element. Since the change in container size may trigger another change to the child element, you may end up with a change loop. size contains can help prevent this loop.

Here is a completely artificial example about this resize loop concept: (A code example should be inserted here showing how size contains how to prevent resize loops)

layout contains

layout contains a layout that tells the browser that external elements do not affect the internal layout of the container element, nor does it affect the internal layout of the container element affect the external elements. Therefore, when the browser does layout calculations, it can assume that having the various elements contained in layout will not affect other elements. This can reduce the amount of computations that need to be performed.

Another benefit is that if the container is off-screen or blocked, the relevant calculations can delay or reduce priority. An example provided by the specification is:

[…] For example, if the include box is near the end of the block container and you are looking at the beginning of the block container

A container with layout contains becomes a containing block of absolute or fixed position child elements. This is the same as applying the relative position to the container. So remember how to affect the child elements of the container when applying this type of inclusion.

Likewise, the container gets a new stacking context, so z-index is used in the same way as the application is relative, absolute, or fixed. However, setting top , right , bottom , or left attributes has no effect on the container.

Here is a simple example: (A code example should be inserted here showing how layout contains affects layout and stacking context)

paint contains

paint contains telling the browser that the child elements of the container will never be drawn outside the boundary of the container box size. This is similar to setting overflow: hidden; on a container, but with some differences.

First, the container is handled the same way as it is under layout inclusion: it becomes a containing block with its own stacking context. Therefore, the child elements positioned in paint include will respect the container in terms of position. If we want to copy the above layout include demo but use paint include instead, the result will be roughly the same. The difference is that when the application contains, the purple line does not overflow the container, but is clipped at the border of the container.

Another interesting benefit of paint includes is that if the browser can detect that the container itself is not visible in the viewport, it can skip the drawing calculation of the child elements of that element. If the container is not in the viewport or is obstructed in some way, then its children are guaranteed to be invisible. For example, consider a navigation menu that is usually located off the screen on the left side of the page, which slides in when the button is clicked. When the menu is in its normal off-screen state, the browser simply skips trying to draw its contents.

Various combinations of included

These three include different methods that affect the rendering calculations performed by the browser. size contains telling the browser that this container should not cause position offset on the page when its content changes. layout contains telling the browser that child elements of this container should not cause layout changes in elements outside of its container, and vice versa. paint contains telling the browser that the contents of this container will never be drawn outside the container size and that if the container is blocked, the contents will not be drawn at all.

Since each include provides different optimizations, it makes sense to combine some of the include together. The specification actually allows this. For example, we can use layout and paint as the value of contain property as follows:

 .el {
  contains: layout paint;
}
Copy after login

Since this is a very obvious thing, the specification actually provides two abbreviation values:

content value will be the most commonly used value in a web project, containing many dynamic elements, such as large multiple containers that change content over time or user activity.

strict value is useful for containers with defined sizes that never change sizes (even if the content changes). Once in place, it will maintain the expected size. A simple example is a div containing third-party external advertising content, whose dimensions are defined by the industry and have nothing to do with any other DOM elements on the page.

Performance Advantages

This part of the article is difficult to explain. The problem is that there are not many visual effects on performance advantages. Most of the benefits are behind-the-scenes optimizations, helping the browser decide what to do when layout or drawing changes.

To show the performance advantages of the contain attribute, I made a simple example, which changed the font size of an element with multiple child elements. This change usually triggers a relay, which also causes the page to be redrawn. This example covers contain values ​​of none , content and strict . (Code examples and performance test results should be inserted here)

Layout once, draw twice

Please listen to my explanation patiently. I promise it will make sense.

I'll use the above demonstration as the basis for the following description. If you wish to continue learning, visit the full version of the demo and open DevTools. Note that after running the performance tool, you have to turn on the details of the "frame" instead of the "main" timeline to see what I'm about to describe.

I'm actually taking screenshots from the "fullpage" version, because DevTools works better in that version. That said, the regular version of "full" should provide roughly the same idea.

In the event log of the task that is not included, the drawing event is triggered only once. Typically, events do not take too long, ranging from 0.2 milliseconds to 3.6 milliseconds. The deeper details are where it becomes interesting. In these details, it states that the drawing area is the entire page. In the event log, DevTools even highlights the drawn page area if you hover over the draw event. In this case, the size will be the size of the browser viewport. It will also notice the layer root drawn.

Note that the page area to the left of the image is highlighted, even outside the purple box. On the right side, is the size drawn to the screen. In this case, it is approximately the size of the viewport. For future comparisons, please note #document as the layer root.

Remember that the browser has layer concepts for certain elements to help draw. Layers are often used for elements that may overlap with each other due to the new stacking context. An example is applying position: relative; and z-index: 1; to an element will cause the browser to create the element as a new layer. contain property has the same effect.

There is a section in DevTools called "rendering" which provides various tools to see how the browser renders the page. When selecting a checkbox called "Layer borders", we can see different contents depending on the inclusion. When included is none , you should not see layers beyond the typical static web page layer. Select content or strict and you can see that the purple box converts to its own layer and the rest of the page changes accordingly. (Screenshots should be inserted here to show layers under different inclusion types)

As I mentioned before, both content and strict cause the draw event to be fired twice. This is because two different drawing processes are performed for two different reasons. In my demo, the first event is for the purple box and the second event is for the contents of the purple box.

Typically, the first event will draw a purple box and report the dimensions of that box as part of the event. The box is now its own layer and enjoys the benefits it applies.

The second event is used for the content of the box because they are scrolling elements. As the specification explains; because the stacking context is guaranteed, the scrolling element can be drawn into a single GPU layer. The higher size reported in the second event is the height of the scroll element. Probably even narrower to make room for scroll bars.

Note the difference in the dimensions to the right of these two images. Additionally, the layer roots of both events are main.change instead of the #document seen above. The purple box is a main element, so only that element is drawn instead of the entire document. You can see the highlighted box instead of the entire page.

The advantage of this is that when scrolling elements are usually made to be drawn when they enter the field of view. The scroll elements in the containment have been drawn, so they are not necessary to be drawn again when entering the field of view. So we also get some rolling optimizations.

Again, this can be seen in the demo. (Screenshots should be inserted here to show the scrolling performance under different inclusion types)

An interesting accidental discovery

I had an interesting problem when I tried the demo above and understood how the drawing and scrolling performance aspects work. In one test, I have a simple box in the center of the page, but with minimal style. It is essentially a scrolling element with a lot of text content. I applied the contents to the container elements, but I didn't see the scrolling performance advantages described above.

The container is marked with a "repaints on scroll" overlay and the drawing flicker is the same as if the included is not applied, even if I know that the content contains is actually applied to the container. So I started comparing my simple tests to the more styling-rich version discussed above.

I ended up finding that if background-color of the container is transparent, there is no inclusion scrolling performance advantage.

I ran a similar performance test where I will change the font size of the content to trigger relayout and redraw. The results of the two tests are roughly the same, the only difference is that background-color of the first test is transparent and background-color of the second test is the appropriate color. From the numbers, behind-the-scenes calculations are still more efficient; only the plotting events are different. It seems that elements do not become their own layer in the drawing calculation with transparent background-color .

The first test run has only one draw event in the event log. The second test run has two plot events, as I expected. Without that background color, the browser seems to decide to skip the included layer aspects. I even found that forging transparency by using the same color as the one behind the element also works fine. My guess is that if the background of the container is transparent, then it must depend on anything below, which makes it impossible to separate the container into its own drawing layer. (Screenshots should be inserted here to show different results under transparent background colors and opaque background colors)

I made another version of the test demo that changed background-color of the container element from transparent to the same color as the body background color. Here are two screenshots of using the various options in the "Rendering" panel in DevTools. (Screenshots should be inserted here to show different results under transparent background colors and opaque background colors)

Summarize

This article introduces the basics of CSS contain properties, including their values, benefits, and potential performance improvements. There are some benefits to applying this attribute to certain elements in HTML; which elements need to apply this attribute is up to you. At least, that's what I understand, because I don't know any specific guidance. The general idea is to apply it to containers of other elements, especially those with some dynamic aspect.

Some possible scenarios: grid areas of the CSS grid, elements containing third-party content, and containers with dynamic content based on user interaction. There should be no harm in using this property in these cases, assuming you are not trying to include an element that actually depends on another element outside of that include.

Browser support is very powerful. Safari is the only browser that is not supported at present. Anyway, you can still use the property because if the browser doesn't understand the property or its value, it simply skips the code without error.

So feel free to start including your content!

The above is the detailed content of Let's Take a Deep Dive Into the CSS Contain Property. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Vue 3 Vue 3 Apr 02, 2025 pm 06:32 PM

It's out! Congrats to the Vue team for getting it done, I know it was a massive effort and a long time coming. All new docs, as well.

Can you get valid CSS property values from the browser? Can you get valid CSS property values from the browser? Apr 02, 2025 pm 06:17 PM

I had someone write in with this very legit question. Lea just blogged about how you can get valid CSS properties themselves from the browser. That's like this.

A bit on ci/cd A bit on ci/cd Apr 02, 2025 pm 06:21 PM

I'd say "website" fits better than "mobile app" but I like this framing from Max Lynch:

Stacked Cards with Sticky Positioning and a Dash of Sass Stacked Cards with Sticky Positioning and a Dash of Sass Apr 03, 2025 am 10:30 AM

The other day, I spotted this particularly lovely bit from Corey Ginnivan’s website where a collection of cards stack on top of one another as you scroll.

Using Markdown and Localization in the WordPress Block Editor Using Markdown and Localization in the WordPress Block Editor Apr 02, 2025 am 04:27 AM

If we need to show documentation to the user directly in the WordPress editor, what is the best way to do it?

Comparing Browsers for Responsive Design Comparing Browsers for Responsive Design Apr 02, 2025 pm 06:25 PM

There are a number of these desktop apps where the goal is showing your site at different dimensions all at the same time. So you can, for example, be writing

Why are the purple slashed areas in the Flex layout mistakenly considered 'overflow space'? Why are the purple slashed areas in the Flex layout mistakenly considered 'overflow space'? Apr 05, 2025 pm 05:51 PM

Questions about purple slash areas in Flex layouts When using Flex layouts, you may encounter some confusing phenomena, such as in the developer tools (d...

How to Use CSS Grid for Sticky Headers and Footers How to Use CSS Grid for Sticky Headers and Footers Apr 02, 2025 pm 06:29 PM

CSS Grid is a collection of properties designed to make layout easier than it’s ever been. Like anything, there's a bit of a learning curve, but Grid is

See all articles