跪拜 Guibai
← Back to the summary

CSS Positioning Isn't About Coordinates — It's About Who Keeps the Seat

Foreword

Writing a webpage is a lot like arranging a stage performance: some people come on stage in order, some need to move a little from their original spot, some need to stand directly in the center of the stage, and some need to stay at the edge of the screen no matter how the page scrolls.

CSS positioning layout solves the problem of "where an element should appear." To truly understand it, you don't need to rush to memorize properties. First, you need to clarify three key points: how elements are originally arranged, what they use as a reference when positioning, and whether they still occupy their original space after moving.

1. Document Flow

When the browser has no special layout rules, the page layout defaults to an arrangement from top to bottom and left to right, presenting a flow-like arrangement, and content is arranged in the order in which HTML elements appear. This default arrangement order is called the document flow.

You can imagine the page as an orderly queue:

The value of the document flow is that it gives the page a natural ability to stretch. When text increases, the container is pushed open; when a module becomes taller, the content behind it automatically moves down. Developers don't need to calculate precise coordinates for every element; the browser can handle most basic typesetting.

What is Leaving the Document Flow

If an element leaves the document flow, other elements will ignore the space it originally occupied when typesetting.

This is like a person leaving a queue they were standing in: they might still be standing where everyone can see them, but the people behind have already moved forward to fill the gap and will not continue to leave space for them. Therefore, elements that leave the document flow easily overlap with other content.

When judging a layout method, you can first ask two questions:

  1. After the element moves, is its original position still retained?
  2. Do the following elements still need to make room for it?

As long as you think these two questions through, the subsequent positioning concepts will become much easier.

1. Block-level Elements: One Person Occupies a Whole Row

Block-level elements usually occupy a whole row by themselves. Even if it doesn't fill the entire row itself, the following block-level element will generally start arranging from the next line.

Its main characteristics include:

Common block-level tags are div, p, and h1. They default to starting on a new line, suitable for building page structure or carrying large blocks of content.

You can think of a block-level element as an audience member who books an entire row of seats: they might only sit in a small area of it, but the next audience member still has to go to the next row.

2. Inline Elements: Follow Along with the Text

Inline elements do not actively occupy a whole row by themselves. Instead, like words in a sentence, they are arranged continuously from left to right. Only when the current line runs out of space do they naturally wrap to the next line.

Its main characteristics include:

Common inline tags are span, a, and strong. They are suitable for embedding inside sentences and will not force a line break just because they appear.

Inline elements are like people sitting on the same row of a bench: each person only takes the space they need, and as long as there is room on the bench, later arrivals can continue to sit next to them.

3. Inline-block Elements: Can Share a Row and Control Dimensions

Inline-block elements combine some characteristics of the previous two types. In terms of arrangement, they are like inline elements and can stay on the same line as other elements; in terms of dimension control, they are like block-level elements and can have explicit width and height set.

Its main characteristics include:

Form controls like button, input, and select usually exhibit behavior similar to inline-block elements, able to be arranged on the same line while also having controllable dimensions.

If block-level elements are "one person per row," and inline elements are "everyone squeezed on a bench," then inline-block elements are like a row of fixed-size independent seats: each seat has a clear size and can be neatly arranged in the same row.

The three types can be compared as follows:

Element Type Usually Occupies a Whole Row? Can Width/Height Be Directly Controlled?
Block-level Yes Yes
Inline No Usually No
Inline-block No Yes

It should be noted that the element type mainly determines how it arranges within the document flow; positioning layout further determines whether it can deviate from its original position, what it uses as a reference, and whether it leaves the document flow. The two cooperate with each other but are not the same concept.

The default display type of a tag can also be changed via the display property in CSS, such as:

display: block;         // Indicates setting as a block-level element
display: inline;        // Indicates setting as an inline element
display: inline-block;  // Indicates setting as an inline-block element

Therefore, how an element participates in layout should be judged by its current display mode.

2. Four Major Positioning Layout Types

Common positioning methods in CSS include relative positioning, absolute positioning, fixed positioning, and sticky positioning. When understanding them, don't just memorize the names; observe three dimensions simultaneously: reference object, document flow, and use case.

1. Relative Positioning: Move a Little from Your Own Seat

position: relative; Relative positioning uses the element's original position in the document flow as a reference. The element can be offset up, down, left, or right from its original position. Take the following HTML code as an example:

<style>
        *{
            margin: 0;
        }
        .box1{
            width: 100px;
            height: 100px;
            background-color: #e237cb;
            position: relative;  // Set to relative layout
            /* Offset relative to the original position in the document flow */
            left: 200px;   // Offset 200px to the right
            top: 100px;    // Offset 100px downward
        }
        .box2{
            width: 200px;
            height: 200px;
            background-color: #252577;
        }
 </style>

<body>
    <div class="box1"></div>
    <div class="box2"></div>
</body>

image.png

We know that box1 and box2 are both div block-level elements and should occupy a whole row each. After we set box1 to positioning layout, the purple block represented by box1 moved to the right and down respectively, but it can also be seen that the document flow position it originally occupied still exists.

This is also the most distinctive feature of positioning layout: although the element has moved visually, the space it originally occupied is still retained. The following elements are still arranged according to its position before moving. That is, relative positioning does not cause leaving the document flow.

This is like a person standing up from their own seat: others can see their position has changed, but their seat is still occupied, and others cannot sit in it.

Relative positioning usually has two types of uses:

The second use is particularly common, and I will give an example in the "Absolute Positioning" section. Often, a parent element enables relative positioning not to move itself, but to tell its child elements: "If you want to use absolute positioning, use me as the reference."

2. Absolute Positioning: Leave the Queue, Find Coordinates in the Designated Room

Absolute positioning causes an element to leave the document flow. Other elements no longer reserve a position for it when typesetting, so it may cover normal content above, or be covered by other elements. Take the following HTML code as an example:

<style>
        .box{
            width: 300px;
            height: 300px;
            border: 2px solid #000;
            position: relative;  // Enable positioning
        }
        .wrapper{
            background-color: #8d1e80;
            position: absolute;  // Set to absolute positioning
            left: 50%;           // Relative to "box", offset right by 50% of "box"'s width
            top: 50%;            // Relative to "box", offset down by 50% of "box"'s height
            transform: translate(-50%, -50%)   // Relative to "wrapper" itself, offset right and down by 50% of its own width and height
        }
 </style>
 
 <div class="box">
        <div class="wrapper">hello</div>
        <div class="name">zmjjkk</div>
 </div>
 <h2>Title</h2>

image.png

Absolute positioning does not simply use its own original position as a reference. It looks outward for the nearest ancestor element that has positioning enabled (in this example, we set the parent element box of wrapper and name to relative positioning) and uses this ancestor as the positioning scope. If no suitable positioned ancestor is found, it usually uses body as the reference.

And it leaves the original document flow, so we can see that wrapper and name are both block-level elements. Originally, wrapper and name should each occupy a row within box, and wrapper should be above name, but now wrapper occupies the position originally belonging to name.

You can think of it as an actor who got a special pass: they no longer follow the ordinary queue onto the stage, but go directly to their position according to coordinates within the designated stage. Which parent element provides the stage depends on who the nearest positioned ancestor is.

Absolute positioning is suitable for the following scenarios:

It is not suitable for undertaking the regular layout of an entire page. Because once a large number of elements leave the document flow, it becomes difficult for them to automatically push each other apart when content changes, and the page is prone to overlap and misalignment.

3. Fixed Positioning: Pinned to the Browser Window

Fixed positioning usually uses the browser's viewport as a reference, and it leaves the document flow.

When the page scrolls, normal content follows the page movement, while the position of a fixed positioning element in the viewport usually remains unchanged. It's like a sticky note attached to the browser glass: the page behind the glass can scroll, but the sticky note always stays in front of your eyes. As shown in the HTML below:

<style>
        body{
            height: 1000px;
        }
        .box{
            width: 100px;
            height: 100px;
            background-color: red;
            position: fixed;   // Set to fixed positioning
            bottom: 10px;      // 10px from the bottom
            right: 10px;       // 10px from the far right
        }
</style>
 
<body>
    <div class="box"></div>
    <h2>hello</h2>
</body>

image.png

Fixed positioning is commonly used for:

When using fixed positioning, special attention must be paid to content occlusion issues. Because it has left the document flow, other content will not actively make room for it. A floating element that looks appropriately sized on a desktop screen might block body text or action buttons on a mobile screen.

4. Sticky Positioning: Move with the Queue First, Stick When Reaching the Line

Sticky positioning can be understood as a combination of relative positioning and fixed positioning.

When the element has not yet scrolled to the specified boundary, it follows the page's normal movement; when it is about to cross the set adsorption position, it temporarily stays at the edge of the scrolling area; when the boundary of its containing block arrives, it is again restricted by the container's scope. As shown in the HTML code below:

<style>
        body{
            height: 200vh;
        }
        .box1{
            width: 500px;
            height: 500px;
            background-color: rgb(172, 106, 159);
        }
        .box2{
            height: 100px;
            background-color: aqua;
            position: sticky; // Set to sticky positioning
            top: 0;           // When this element scrolls to a position 0px from the top of the scrolling container, don't scroll up any further, stick here
        }

  </style>
    
<body>
    <div class="box1"></div>
    <div class="box2"></div>
</body>

image.png

It's like a magnet placed on a whiteboard: it usually moves along with the whiteboard, temporarily sticks when it hits a specified edge, but it can never leave the whiteboard it belongs to.

Sticky positioning usually does not leave the document flow, and the originally occupied space continues to be retained, making it very suitable for creating:

Finally, a table summarizes the four positioning methods:

Positioning Method Main Reference Object Leaves Document Flow? Core Impression
Relative Positioning Its own original position No The person moved, the seat is still there
Absolute Positioning Nearest positioned ancestor Yes Left the queue, finds coordinates in the designated room
Fixed Positioning Browser viewport Yes Pinned to the browser window
Sticky Positioning Scrolling area and containing block No Moves with the page first, sticks when reaching the line

3. When Positioned Elements Overlap: Understanding z-index

After elements are positioned, they easily overlap each other. At this point, besides "where to put them," you also need to decide "who appears on top." This is the problem that stacking order solves.

Normally, elements with larger z-index values are closer to the observer. However, simply understanding it as "the one with the bigger number is on top" is not accurate, because z-index comparison is limited by the stacking context.

A stacking context can be imagined as independent buildings. Child elements can only first arrange their floors inside their own building, and which of two buildings is in front depends first on the order of the buildings themselves. Even if a child element lives on the ten-thousandth floor in its own building, it may not necessarily cover another building that is entirely in front.

When understanding stacking order, you can remember the following points: