Is Position: Static Identical to Position: Relative, with No Other Properties Specified

Is position: static identical to position: relative, with no other properties specified?

The answer is no, both are different

position: static; means nothing but default position, you cannot use top, right, bottom, left unless and until you use position: relative, absolute or fixed, you need to use margins, moreover, position: relative; comes in real action when the child elements are positioned absolute, so that all elements can float inside the position: relative; div, if you just keep it static, they will go out of the document...

Take a look at the examples

Demo1 (Keeping the div static and using top, left has no effect)

Demo2 (Making it position: relative; does effect top, left)

Demo3 (Keeping the parent div static, child will flow out if it's positioned absolute)

Demo4 (Child div positioned absolute will measure top, right, bottom, left from its parent div positioned relative)

This 1 is short and very simple but powerful tutorial video to clear out your doubts

And a short article on CSS positioning

Difference between static and relative positioning

Static positioning is the default positioning model for elements. They are displayed in the page where they rendered as part of normal HTML flow. Statically positioned elements don't obey left, top, right and bottom rules:

statically-positioned elements obey normal HTML flow.

Relative positioning allows you to specify a specific offset (left, top etc) which is relative to the element's normal position in HTML flow. So if I have a textbox inside a div I could apply relative positioning on the textbox to have it display at specific place relative to where it would normally be placed within the div:

relatively-positioned elements obey HTML flow, but provide the ability to adjust their position relative to their normal position in HTML flow.

There is also absolute positioning - whereby you specify the exact location of the element relative to the entire document, or the next relatively positioned element further up the element tree:

absolutely-positioned elements are taken out of HTML flow and can be positioned at a specific place in the document...

And when a position: relative is applied to a parent element in the hierarchy:

...or positioned relative to the first parent element in the HTML tree that is relatively positioned.

Note how our absolutely-position element is bound by the relatively-positioned element.

And lastly there is fixed. Fixed positioning restricts an element to a specific position in the viewport, which stays in place during scroll:

fixed-positioned elements are also taken out of HTML flow, but are not bound by the viewport and will not scroll with the page.

You may also observe the behaviour that fixed-positioned elements do not cause scroll because they are not considered to be bound by the viewport:

fixed-positioned elements have no effect on scroll.

Whereas absolutely-positioned elements are still bound by the viewport and will cause scrolling:

absolutely-positioned elements are still affected by the boundaries of the viewport, unless overflow is used on a parent element.

..unless of course your parent element uses overflow: ? to determine the behaviour of the scroll (if any).

With absolute positioning and fixed positioning, the elements are taken out of HTML flow.

Why does absolute position ignore elements with static positions?

For one thing, the premise is incorrect. There are situations where a statically positioned element can provide the containing block of an absolutely positioned element. position, transform, will-change and contain are all properties that will cause an element to establish an absolute positioning containing block

For example:

.outer {
width:50vw;
height:50vh;
background-color:lightblue;
margin: 25vh 25vw;
transform:translateX(0);
}
.inner {
position:absolute;
width:100px;
height:50px;
inset: 0;
background-color:red;
}
  <div class="outer">
<div class="inner"></div>
</div>

Understanding relative position in css

"Normal position" is in the context of the DOM, and refers to Normal flow:

First of all, individual element boxes are laid out by taking the elements' content, then adding any padding, border and margin around them.

By default, a block level element's content is 100% of the width of its parent element, and as tall as its content. Inline elements are as tall as their content, and as wide as their content.

This is explained in further detail in the CSS flow layout:

Normal Flow, or Flow Layout, is the way that Block and Inline elements are displayed on a page before any changes are made to their layout. The flow is essentially a set of things that are all working together and know about each other in your layout. Once something is taken out of flow it works independently.

In normal flow, inline elements display in the inline direction, that is in the direction words are displayed in a sentence according to the Writing Mode of the document. Block elements display one after the other, as paragraphs do in the Writing Mode of that document. In English therefore, inline elements display one after the other, starting on the left, and block elements start at the top and move down the page.


It's worth noting that all elements have static positioning by default:

Static positioning is the default that every element gets — it just means "put the element into its normal position in the document layout flow — nothing special to see here."

And relative positioning simply allows for modification of the position:

This is very similar to static positioning, except that once the positioned element has taken its place in the normal layout flow, you can then modify its final position.

Fixed position but relative to container

Short answer: no. (It is now possible with CSS transform. See the edit below)

Long answer: The problem with using "fixed" positioning is that it takes the element out of flow. thus it can't be re-positioned relative to its parent because it's as if it didn't have one. If, however, the container is of a fixed, known width, you can use something like:

#fixedContainer {
position: fixed;
width: 600px;
height: 200px;
left: 50%;
top: 0%;
margin-left: -300px; /*half the width*/
}

http://jsfiddle.net/HFjU6/1/

Edit (03/2015):

This is outdated information. It is now possible to center content of an dynamic size (horizontally and vertically) with the help of the magic of CSS3 transform. The same principle applies, but instead of using margin to offset your container, you can use translateX(-50%). This doesn't work with the above margin trick because you don't know how much to offset it unless the width is fixed and you can't use relative values (like 50%) because it will be relative to the parent and not the element it's applied to. transform behaves differently. Its values are relative to the element they are applied to. Thus, 50% for transform means half the width of the element, while 50% for margin is half of the parent's width. This is an IE9+ solution

Using similar code to the above example, I recreated the same scenario using completely dynamic width and height:

.fixedContainer {
background-color:#ddd;
position: fixed;
padding: 2em;
left: 50%;
top: 0%;
transform: translateX(-50%);
}

If you want it to be centered, you can do that too:

.fixedContainer {
background-color:#ddd;
position: fixed;
padding: 2em;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}

Demos:

jsFiddle: Centered horizontally only

jsFiddle: Centered both horizontally and vertically

Original credit goes to user aaronk6 for pointing it out to me in this answer

css - parent's position is absolute and child's position is relative and vice versa

Read more about absolute, relative, and fixed position and how they differ here, but I'll try to answer your question about relationships specifically.

position: absolute will position that element to its nearest parent with a position other than static. Static is the default for everything.

position: relative is a little weird because it really affects that element's children, not its own position. It's just saying to its child elements, "position yourself relative to me if you have position: absolute." A position of fixed or absolute does the same thing (meaning its positioned children will position themselves relative to its boundaries), but these styles also affect their own position on the page. An element with position: relative won't look any different, but its children might.

So consider a situation like this:

<div class="parent">
<div class="child">
<div class="grandchild"></div>
</div>
</div>

If grandchild has position: absolute, it will position itself relative to the browser window because there is no parent with a position other than the default of static.

If parent also has position of relative, absolute, or fixed, grandchild will position itself relative to the boundaries of parent.

However, if child also has a position of relative, absolute, or fixed, the grandchild will position itself relative to child's boundaries, because it is the nearest parent with a position other than static.

In summary, relative affects an element's children, while absolute and fixed affect the element itself as well as its children.

And remember that position: fixed bypasses all relative and absolute parents and always positions itself relative to the browser window.

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