Difference Between Initial Containing Block and Viewport

Difference between initial containing block and viewport

The initial containing block and the viewport, while related to each other, are two distinct concepts.

The viewport generally refers to the viewable area of a browser window in which a page is rendered on screen. The initial containing block is the logical area within the page in which the root element and everything else is rendered.

The dimensions of the initial containing block are based on those of the viewport (see section 10.1), but when the content is no longer able to fit the viewport, the viewport is made scrollable so the user can continue to access the rest of the content. Additionally, the new vw, vh, vmin and vmax units are called viewport-percentage units, but they are also described as being relative to the size of the initial containing block.

Note that the definition of a viewport may vary depending on the device. For example, the viewport of Safari on iOS is very different from that of a desktop browser.

Can I change the initial containing block size?

The size of the initial containing block is always the same as that of the viewport. You can't change this size (except via the viewport meta tag, which probably isn't what you're looking for).

@Pete Because my page is already styled in vh and vw units, and it's looking OK. But I wan't to fix the viewport size past the certain screen width, so that my design doesn't stretch.

What you want to do is write a media query for when the screen exceeds a certain width, then replace all your dimensions that use viewport units with your desired values.

What is the difference between % and vw in css?

They aren't necessarily interchangeable.

The behavior will mainly depend on the element's position in the DOM, since this will determine what the element's containing block is. If an element has a width of 100%, it will have a width of 100% of the containing block's width. If the element has a width of 100vw, it will have a width of 100% of the viewport's width (the viewport may not be the element's containing element, but viewport-percentage units will always be relative to the viewport).

A strictly percentage based width will always be relative to another element's width, but when using viewport-percentage lengths, an element's width can actually be relative to the viewport's height. For instance, if an element has a width of 100vh, it will have a width of 100% of the viewport's height. This isn't possible when using strictly percentage based widths.

Viewport-percentage length are always going to be relative to their initial containing block, which is the viewport:

5.1.2. Viewport-percentage lengths: the ‘vw’, ‘vh’, ‘vmin’, ‘vmax’ units

The viewport-percentage lengths are relative to the size of the initial containing block. When the height or width of the initial containing block is changed, they are scaled accordingly.

Whereas percentage based units are going to be relative to their parent element (i.e., their containing block), which may happen to be the body/html element, in which case they will be similar to viewport-percentage lengths.

4.3. Percentages: the ‘<percentage>’ type

Percentage values are always relative to another value, for example a length. Each property that allows percentages also defines the value to which the percentage refers. The value may be that of another property for the same element, a property for an ancestor element, or a value of the formatting context (e.g., the width of a containing block). When a percentage value is set for a property of the root element and the percentage is defined as referring to the inherited value of some property, the resultant value is the percentage times the initial value of that property.

what is the containing block of an absolutely positioned element?

You are correct. The containing block is the last positioned element. so if you want to explicitly set the container then give it position:relative. Most browsers get this right. CSS doesn't really have a 'viewport', I think the top is the HTML element though don't hold me to that. IE prior to 7 had an unnamed element above HTML though.

What exactly is a formatting context?

A formatting context is not really an area. It's more a state of a box that defines the set of layout rules that apply to itself and its participant boxes.

Position:fixed element within a position:relative parent. Which browser renders correctly?

This appears to be an interesting case. Let's take a deep dive into the specifications to find out what's going on.


TL;DR: The W3 specification is critically vague/undefined in this area, but it appears that all browsers deviate from the spec, or at least, they made a decision where details were undefined. However, four of the major browsers (Firefox, Chrome, IE, and Opera) are united in that they all seem to deviate from the spec in the same way. Safari is definitely the odd man out here.


This is what the CSS2.1 spec has to say in Chapter 9: Visual formatting model:

  1. 9.1.2 Containing blocks - In CSS 2.1, many box positions and sizes are calculated with respect to the edges of a rectangular box called a containing block. In general, generated boxes act as containing blocks for descendant boxes; we say that a box "establishes" the containing block for its descendants. The phrase "a box's containing block" means "the containing block in which the box lives," not the one it generates.

This just defines what a containing block is.


  1. 9.3 Positioning Schemes - Absolute positioning: In the absolute positioning model, a box is removed from the normal flow entirely and assigned a position with respect to a containing block.

This says absolutely positioned elements are positioned with respect to a containing block.


  1. 9.6 Absolute Positioning - In the absolute positioning model, a box is explicitly offset with respect to its containing block. [...] References in this specification to an absolutely positioned element (or its box) imply that the element's position property has the value absolute or fixed.

This says absolutely positioned elements include position:fixed; elements as well as position: absolute; elements.


  1. 9.6.1 Fixed Positioning - Fixed positioning is a subcategory of absolute positioning. The only difference is that for a fixed position box, the containing block is established by the viewport.

And this says position: fixed; elements have the Viewport (well, not literally the viewport, but a box with the same dimensions and positions as the viewport) as their containing box. This is backed up later by the spec in 10.1 Definition of containing block:

If the element has 'position: fixed', the containing block is established by the viewport [...]

(If you aren't familiar with what the viewport is, it is "a window or other viewing area on the screen through which users consult a document". The viewport's dimensions are the basis for the initial containing block. The entirety of your HTML content (<html>, <body>, etc.) resides within this initial containing block defined by the viewport.)

Therefore, the <div class="nav"> element with position: fixed; applied to it should have a containing block equal to the Viewport, or the initial containing block.


Now that the first step of determining the properties of the .nav element is complete, we can determine how the browsers are supposed to behave.

The CSS2.1 spec has this to say:

  1. 9.7 Relationships between 'display', 'position', and 'float' - Otherwise, if 'position' has the value 'absolute' or 'fixed', the box is absolutely positioned, the computed value of 'float' is 'none', and display is set according to the table below. The position of the box will be determined by the 'top', 'right', 'bottom' and 'left' properties and the box's containing block.

This is basically telling us that, for absolutely positioned elements (position: fixed; or position: absolute;), any float properties are ignored, that <div> elements (among others) are set to display: block;, and that the element is positioned according to its box offset values of top, right, bottom, and/or left in combination with the initial containing block (the viewport).


  1. 9.3.2 Box offsets: 'top', 'right', 'bottom', 'left' - An element is said to be positioned if its 'position' property has a value other than 'static'. Positioned elements generate positioned boxes, laid out according to four properties: top, right, bottom, left.

This just reaffirms the fact that <div class="nav"> should be positioned according to its box offsets.

Although it says in several places that if two opposing offset values are auto, then they are set to zero, CSS2.1 doesn't seem to specify the case for how to position elements with both left and right values of zero. CSS Box Alignment Module Level 3, however, does mention that the value is set to "start", which is defined as:

Aligns the alignment subject to be flush with the alignment container’s start edge.

This should mean the element is positioned at the top-left of the containing block, which, for position: fixed; elements, should be the same as the viewport. However, we can see that, for all major browsers, this is not the case. None of the major browsers seem to be setting the position: fixed;'s containing block to that of the viewport as instructed by the spec. Instead, they are all acting as if behavior should be identical between position: fixed; and position: absolute;.

In summation, when you have this much evidence in the spec's own words, the answer is clear: position: fixed; elements should have a containing block set to the viewport. What's also clear is that the vendors have all decided to fill-in a vague part of the spec in their own way, conflicting with, or outright ignoring this declaration. What is most likely to have happened is that one browser implemented their interpretation (IE7 was the first to support position: fixed;, I believe, followed shortly by Firefox 2.0) and the rest followed.



Related Topics



Leave a reply



Submit