DEV Community

Cover image for Position: Relatively Confused

Posted on

Position: Relatively Confused

The layout of a web page, and how responsive and scalable it is, separates an amateur site from a pro site. One of the first questions on my All Points Bulletin board was related to controlling layout with position:

What does the position property do? What do the values absolute and relative mean?

When first learning the ins and outs of CSS I was easily confused by the number of options to control the layout of a page. There's CSS Grid, Flexbox, floats and pure positioning. I often lost track of what properties belonged to which, trying to use the top property in a flexbox column, or using trial and error to plug in justify-content, align-items, and margin values to center content.

I've learned that a finished website usually has a little bit of everything, and being familiar with the basics is a powerful tool when trying to figure out why an element, or a group of elements, isn’t behaving how you expected.

The Position Property

The position prop specifies the positioning method applied to an element.

There are 5 possible methods:

  • Static
  • Relative
  • Absolute
  • Fixed
  • Sticky

Once an element's position property is set to anything but static (the default setting) it will have access to the top, left, right and bottom properties - what I'll refer to as the positional properties.

1️⃣ Position: Static

By default the elements on a web page are displayed in static position. They appear in the viewport according to the document flow and writing method of the browser. Some browsers display left-to-right, right-to-left, or vertically down the page depending on the selected country and language.

πŸ™‹β€β™‚οΈ In this example we have a client who has asked us to create a simple dating profile page. The finished page uses basic structure - the elements are laid out in a logical order, from top to bottom as we want them to appear. They follow a flow.

A page without CSS to explicitly change the ordering or positioning of elements (a page in default static) is said to be in Normal Flow.

When a page is in Normal Flow, elements are displayed one after another, in block dimension, as they appear in the code. When the page is scrolled the elements scroll with it.

The positional properties (top, bottom, right, and left) do not effect an element that is positioned statically.

2️⃣ Position: Relative

When an element is moved by changing its positioning method (using the position prop rather than display), it's always being moved in reference to something - like another element, or itself.

Applying position: relative sets that reference to where the element would be in Normal Flow. At first it won't look like it did much of anything, that's because the element won't move until a positional property tells it to.

πŸ™‹β€β™‚οΈ Using the same example from above, the client wants us to center his profile image on the page. We could do this by using relative positioning, and a little bit of hackiness.

The image element, with class name profile_pic, was given a relative position and moved 35% to the left of that reference. This isn't the best approach to centering an element, but it works for now.

☝ Keep in mind! The space the element takes in Normal Flow is reserved - surrounding elements will not shift to fit or fill the gap, or make room for the element elsewhere.

3️⃣ Position: Absolute

Applying position: absolute on an element removes it, and the space it would normally take, from the document flow entirely. The point of reference is set to the elements nearest positioned ancestor, and a new stacking context is created. This context gives us access to the z-index property.

If the element has no positioned ancestor (a parent element whose position is anything but static/default), the reference points to the document body (the viewport). This is the first behavior that can confuse a developer and cause bugs in a layout.

πŸ™‹β€β™‚οΈ The client got back to us - he likes where the page is going, but wants to restructure the top of the page. He's requested that the profile element be smaller, and centered at the top of the page.

The image div was set to position: relative, allowing us to center its direct child, the image element, using an absolute positioning trick.

The basic syntax for this trick looks like this:

.parent {
    position: relative;

.child {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
Enter fullscreen mode Exit fullscreen mode

☝ It's important to note that a stacking context is created when using a range of other CSS positioning and layout methods - usually with a default value of 0. This can result in elements falling behind others unexpectedly. We set the z-index of the image div to -1, putting it further from the user, or behind other elements (like the navigation bar) in the stacking order.

☝ If an absolutely positioned element isn't appearing where expected, first make sure the element has a positioned ancestor. Most of the the time we don’t want to use the viewport as the reference, and when we do it’s easier and better practice to use position: fixed as we’ll see in a moment. Then make sure the positioned ancestor is the element you expect - going up or down a layer if needed.

4️⃣ Position: Fixed

Fixed positioning allows an element to be positioned according to the viewport. Like absolute, the element will be completely removed from the document flow. A positional property, usually top, needs to be used to view the element.

πŸ™‹β€β™‚οΈ The client's back! They brought us some more content, and they also want a navigation bar that remains visible at all times. We'll use fixed positioning to achieve this.

First, we gave the nav element additional styling rules, and applied position: fixed, setting the top and left properties. These instruct the browser to display the element as if it were pinned to the top left corner.

☝ Are other elements appearing over a fixed element? Remember, when an element's position property is set to either absolute or relative, a new stacking context is created. Try setting the the z-index of the fixed element to 1 or higher.

☝ It is possible to set the reference of a fixed element to something other than the viewport, though it’s not considered best practice. To achieve this, a containing parent must have the perspective, transform, or filter property set to anything but the default of none.

5️⃣ Position: Sticky

The last positioning method remaining is a bit of a hybrid - acting as both a relatively and a fixed positioned element at different times. An element with position: sticky applied toggles, appearing in Normal Flow until a user scrolls to a certain point, when it then becomes fixed.

πŸ™‹β€β™‚οΈ The client is thrilled with our work so far, as a final touch he wants to add a contact number to the page. He's asked that it's noticeable and easily located by the user. We'll use sticky positioning to make sure the user can always get ahold of Jack.

The phone_number element was added at the top of the document, styled with some Windows 95-flavored subtlety, and given sticky positioning. When the user first comes to the page it will be nestled right below the nav bar, but as they scroll to read more it will sticky itself safely within view.

☝ The sticky value is newer, and because of that it has less cross-browser support. Don’t worry too much about that though, the element will revert to fixed position and scroll with the user in the case that the sticky method isn’t supported. Additionally the WebKit Sticky extension may help.

A Word on Normal Flow

Good document structure is an integral part of accessibility-minded design. A well structured document is crucial for users that will never see our carefully laid out CSS, but it's just as important to those who do.

Normal flow is based on how a reader naturally traverses and consumes content. If an element needs to be moved relatively far from where it appears in normal flow, we should first consider adjusting its position in the document itself instead.

The CSS position prop is a powerful tool to control the layout of elements on a page, but it's not without its hidden nuances than can result in hard to solve bugs and weird behavior. I encourage you to play with the code in the examples, remove position from parent elements, or try new ones to see how they stack.

πŸ” If you're still curious - check out the resources section below! I always come across great articles in the search to answer my own questions.


As always - Thank you for reading πŸ¦„

Top comments (0)