Positioning

The term positioning means to put an element in a place on the screen - usually in a place that is different from where the normal flow layout would place it. In the early days of CSS, there were three primary ways to position elements - float, absolute and fixed positioning. In this section, we'll look at all three. In many respects, they have now been at least partially superseded by modern flexbox and grid, but these three techniques still have their place - and are still the the right technique in some situations.

Float Positioning

Float positioning is perhaps the most graceful of the positioning techniques. Ultimately, float is used when you are little less concerned about the exact positioning of an element, and instead more concerned about moving it out of the main body of content.

Let's see a simple example. Below is some text in a p element, with a span of text floated out to the left.

span {
    float:left;
    border: 1px solid red;
}
<p>
The this text is going to wrap around the text that is floated out.  <span>I'm floating.</span>  The floating text is moved out of the line box of the surrounding text.
</p>

Simple float left

This doesn't seem that useful, but we are going to add more in a moment. Before doing so though, let's make very clear what float is doing:

  1. The float property only applies to the element it is specified on - which we will call the floated element(=). It is not really affecting the siblings, children, or parent. However, where necessary, siblings will need to move to accommodate the floated element's new position.
  2. The floated element will always be positioned within it's parent. This means, the parent will grow / shrink to accommodate wherever a floated element needs to be.
  3. The floated element is pulled out of the flow layout at the vertical position it normally would render, and moved to the left or right. This has important implications - for example, if there is no content below the floated element in the first place, it's quite unlikely you will see much of an effect from float!

That third point trips students up, often. Let's change the example up a bit, and instead of using a span element, let's use an img element. Images have heights that don't correspond to line boxes per se, so they visually make a little more sense as floated elements than just a couple of floating words:

img {
    float:left;
}
<p>
    <img src="red-square.png" />
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. 
    Phasellus imperdiet, nulla et dictum interdum, nisi lorem 
    egestas odio, vitae scelerisque enim ligula venenatis dolor. 
    Maecenas nisl est, ultrices nec congue eget, auctor
    vitae massa. <img src="green-square.png" />Fusce luctus 
    vestibulum augue ut aliquet. Mauris ante ligula, facilisis sed 
    ornare eu, lobortis in odio. Praesent convallis urna a lacus 
    interdum ut hendrerit risus congue. Nunc sagittis dictum nisi, 
    sed ullamcorper ipsum dignissim ac...<img src="blue-square.png" />
</p>

Vertical positioning

Look closely at the rendered result - the red square's top is precisely aligned with the top of the first line box, since it was supposed to be on the first line. The green square's top is precisely aligned with the same line box as the words "massa" and "Fisce" from the lorem ipsum text, because that's the same line box it should have been in. Finally, the blue square is aligned with the last line box.

That example worked out really nicely, since the line boxes the images were appearing in were naturally vertically distant enough from each other that there was room to float the images out, and have them nicely spaced out. That was luck though. What happens when that's not the case?

<p>
    <img src="red-square.png" />
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. 
    Phasellus imperdiet, nulla <img src="green-square.png" />
    et dictum interdum, <img src="blue-square.png" /> nisi lorem 
    egestas odio, vitae scelerisque enim ligula venenatis dolor. 
    Maecenas nisl est, ultrices nec congue eget, auctor
    vitae massa. Fusce luctus 
    vestibulum augue ut aliquet. Mauris ante ligula, facilisis sed 
    ornare eu, lobortis in odio. Praesent convallis urna a lacus 
    interdum ut hendrerit risus congue. Nunc sagittis dictum nisi, 
    sed ullamcorper ipsum dignissim ac...
</p>

Yuck

In a word... yuck. float did as promised. It took each image out of it's line box, drifted it to the left, and aligned it's top with the top of the line box it came from. However, because the green and blue square's line box isn't low enough, it needed to create more room to the right of the red square. Likewise, since the blue and green squares are from the same line box, they are lined up horizontally - since their tops need to line up with the line box.

The rendering above is a fixed image, but if you had something live in your browser, you'd notice that as you changed the dimensions of the screen, text wrapping would still be occurring. If skinny enough, the squares would float out vertically separated as before. If wide enough, all three would be on the same line.
Skinny Skinny

Float leaves most of the control to the browser. It's graceful in that it lets the browser do it's thing - aside from asking it to float the element out. The rule of thumb on where things will float to:

  1. Where is the element supposed to be?
  2. Simply move the element out to the left or right, at the same vertical position.
  3. Allow all the remaining content to flow around it.

Working Effectively with Float

Float may seem, so far, pretty limited. None of the examples look all that nice. However, there's a lot you can actually accomplish, by combining float with margins and by clearing out space above and beneath as necessary.

Let's take a look at another example, with just two images. We'll also add some margins to the floated elements, which is now being accomplished by assigning a class to the element, so it can apply to any type.

.left {
    float: left;
    margin-right: 1rem;
    margin-block: 1rem;
}

The result at first is confusing. There appears to be enough vertical space to have the two images right on top of each other. However, the margins we've applied prevent this - and so the second images gets pushed to the right. Usually, this isn't what we want. Getting rid of the margin-block could be an option, but we probably do want some natural spacing between the squares.

Margin

There's one way to accomplish this, and it starts us on the path of better usage of float itself - and that't the clear property. Setting an element's clear property to either left, right, or both instructs the browser to always push that element below an element floated to it's left, right, or either side. So, let's add clear:left to the left class.

.left {
    float: left;
    margin-right: 1rem;
    margin-block: 1rem;
}

Clear

The clear:left directive tells the browser to push any .left class element below elements floated to it's left. The result - a lot like what we wanted (probably)!

Float Strengths

Float is a great way to pull content out of the main content area, and slide it left or right. The browser honors margins and padding, and allows text to flow around the elements nicely. The greatest advantage of float is that it preserve the vertical position of the floated element. This means, it will appear vertically on the page in the same location as it would have appeared if it wasn't floated. This makes float perfect for images, where the surrounding text is discussing it.

Float Limitations

Let's try the same example now, but add some text before and after - so the floated elements are within a larger text structure.

Wraparound

That looks a lot like how something might appear in a textbook! With margins applied, the text naturally flows around the images without getting too crowded. But what if we wanted the images to be in a sidebar - where the text wasn't flowing around the images - but there was a nice margin to the left instead.

Well, HTML has an aside element. You may first think, let' put all the images in an aside, and float the aside. That solution can be fine - but it doesn't allow the images to be located at specific positions based on the text - which is really a big part of the value of floats. Moreover, the height of the aside will be just large enough for the images - so you haven't really created the clearing you wanted. The only solution here would be to set aside to have height:100%.

<p>
    <aside class="left">
        <img src="red-square.png" />
        <img src="green-square.png" />
    </aside>
    Sed ut perspiciatis unde omnis iste natus error sit 
    voluptatem accusantium doloremque laudantium, totam 
    rem aperiam, eaque ipsa quae ab illo inventore veritatis et 
    quasi architecto beatae vitae dicta sunt explicabo. Nemo 
    enim ipsam voluptatem quia voluptas sit aspernatur aut odit 
    aut fugit, sed quia consequuntur  magni dolores eos 
    qui ratione voluptatem sequi nesciunt. Neque porro 
    quisquam est, qui dolorem ipsum quia dolor sit amet, 
    consectetur, adipisci velit, sed quia non  numquam 
    eius modi tempora incidunt ut labore et dolore 
    magnam aliquam quaerat voluptatem. Ut enim ad minima 
    veniam, quis nostrum exercitationem ullam corporis 
    suscipit laboriosam, nisi ut aliquid ex ea commodi 
    consequatur? Quis autem vel eum iure reprehenderit qui 
    in ea voluptate velit esse quam nihil molestiae consequatur, 
    vel illum qui dolorem eum fugiat quo voluptas nulla pariatur? 
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. 
    Phasellus imperdiet, nulla et dictum interdum, nisi lorem 
    egestas odio, vitae scelerisque enim ligula venenatis dolor....
</p>

Aside

The clear isn't the right solution here either. We could wrap all the text, and assign that element to have clear-left, but then that would simply push all the text below the images.

What we really need is a true margin to the left, where the floated elements can live. Let's try that, but giving the paragraph a left margin large enough to fit the images.

.left {
    float: left;
    margin-right: 1rem;
    margin-block: 1rem;
}
p {
    /* This value is based on the size of the image */
    margin-left:100px;
}

Margin

Unfortunately, that doesn't work. The p element's margin is set just fine, but the elements that are floated are within the border of the p element, since the floated elements are still children of the p element.

The bottom line is this: float fully honors all element's padding and margins. You cannot have an element positioned within another element's padding, and you can't encroach on any element's margin. As we will see in a moment, the effect of having a pure margin along the entire text is achieveable, but not with float.

The other limitations with float are associated with it's strength - you aren't controlling everything. For situations that are simply, like floating an image out of text, that's a strength not a limitation. For situations where you need more control... well, that's where float becomes harder to deal with, and we'll have better solutions!

Positioning

Float elements are still technically part of the flow layout. They are not technically considered positioned. Let's move on now, and start talking about really positioning elements. The first rule in positioning elements on the screen is that they are always positioned relative to something.

The position attribute controls whether or not an element is considered positioned. It has five possible values, and poorly named ones at that:

position:static - Not Positioned

static - is the default value for the position property, and it means the element is not positioned. The element's position is simply controlled by the standard flow layout of the page. All of the elements we've used up until now have position:static, including the floated elements. There's not much to say here - more than this: static positioned elements do not play a role whatsoever in any of the other positioning mechanisms.

position:relative - Positioned Relative to the Normal Flow Layout

relative is the most misunderstood value of the five! An element whose position is relative is positioned relative to where it normally would appear in the flow layout. With just position:relative, this rule actually has no effect on the location of the element - as you haven't defined an offset from the normal location.

To modify the element's position, we can use any combination of the following. In each, the anchor is considered what we are positiioning relative to - and in the case of postion:relative, we are positioning relative to the normal location of the element.
left - a CSS length, sets the left margin of the element to be the specified distance from the anchor's left margin. right - a CSS length, sets the right margin of the element to be the specified distance from the anchor's right margin. top - a CSS length, sets the top margin of the element to be the specified distance from the anchor's top margin. bottom - a CSS length, sets the bottom margin of the element to be the specified distance from the anchor's bottom margin.

Note that if we specify both left and right, then width must be calculated to accommodate those specifications. If we set only left, or only right, then width will be calculated as it normally would - the content requirements. Same goes for top and bottom, if one is specified, then the height is simply dependent on the content, if both are specified, then height will be the difference betwene the two (and you may need to consider overflow).

Here's an example of a relatively positioned span, that has been shifted -10px up, and 20px to the right:

.just-relative {
    position: relative;
    border: 1px solid red;
}

.up-and-right {
    position: relative;
    top: -10px;
    left: 20px;
    border: 1px solid blue;
}
<p>
    Sed ut perspiciatis unde omnis iste natus error sit voluptatem
    accusantium doloremque laudantium, totam rem aperiam, eaque ipsa
    quae ab illo inventore veritatis et quasi architecto beatae vitae
    dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas
    sit aspernatur aut odit aut fugit, sed quia consequuntur magni
    dolores eos qui <span class="just-relative"> ratione voluptatem </span>
    sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum
    quia dolor sit amet, consectetur adipisci velit, sed quia non
    numquam eius modi tempora incidun ut labore et dolore magnam
    aliquam quaerat voluptatem. Ut enim ad minima
    <span class="up-and-right">veniam</span>, quis
    nostrum exercitationem ullam corporis suscipit laboriosam,
    nisi ut aliquid ex ea commodi consequatur? Quis autem vel
    eum iure reprehenderit qui in ea voluptate velit esse
    quam nihil molestiae consequatur, vel
    illum qui dolorem eum fugiat quo voluptas nulla pariatur?</span>
</p>

Relative

Two things of note: (1) the element that was positioned and moved up and to the right did so over other elements. We'll talk about controlling things like z-index to do this more predictably - but it's important to see that positioned elements break free of constraints associated with padding and margins. The second (2) note is that the space originally used to render the element is preserved. Content is flowing around where the element should have been.

Relative is useful unto itself, but it is a bit special, in that it can play a role when positioning other elements. Relative position, in the absence of left, right, top, or bottom has the effect of positioning the element, but not altering it's location. This is critical for our next position option - absolute positioning.

position:absolute - Positioned Relative to another element

The section heading might be misleading - absolute positioning might make it sound like we can position elements "absolutely" - but that's a misnomer. Absolute positioning allows us to specify the position of an element, absolutely, relative to some parent element. The absolutely part of that sentance is actually pointing towards a big difference between this (positioned elements, not just absolute) and floating elements. We are fully specifying the position of the element - the browser isn't going to do any work for us anymore.

The name also stems from the notion that you can position relative to the body, which has the effect of positioning the element absolutely, as if not relative to anything. The name is poor.

The most important rule to understand is with absolute positioning, you are positioning the element relative to the nearest ancestor that is also positioned. An element is positioned if it's position value is not static. That means, an element can be the anchor of an element with absolute position if it meets the following conditions:

  1. It is an ancestor of the element to be absolutely positioned.
  2. It has position either relative, absolute, fixed, or sticky.

Let's take a look at a simple example, with the same paragraph as before:

p {
    /* We set p to relative so it's an anchor to the span
       elements that are absolutely positioned. If we 
       didn't, the spans would be positioed relative 
       to the entire page */
    position: relative;
}
span {
    background-color: yellow;
}
.down-and-right {
    position: absolute;
    top: 10px;
    left: 20px;
    border: 1px solid blue;
}
.more {
    position: absolute;
    top: 50px;
    left: 75px;
    border: 1px solid blue;
}
<p>
    Important - the elements are absolutely positioned relative
    to their ancestor - <span class="down-and-right">paragraph
    elements. </span> If paragraph elements weren't positioned, 
    then all of the spans on this page would be relative to the body, 
    and so both <code>down-and-right</code> spans would be in the same
    location.
</p>
<p>
    Sed ut perspiciatis unde omnis iste natus error sit voluptatem
    accusantium doloremque laudantium, totam rem aperiam, eaque ipsa
    quae ab illo inventore veritatis et quasi architecto beatae vitae
    dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas
    sit aspernatur aut odit aut fugit, sed quia consequuntur magni
    dolores eos qui <span class="more"> ratione voluptatem </span>
    sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum
    quia dolor sit amet, consectetur adipisci velit, sed quia non
    numquam eius modi tempora incidun ut labore et dolore magnam
    aliquam quaerat voluptatem. Ut enim ad minima
    <span class="down-and-right">veniam</span>, quis
    nostrum exercitationem ullam corporis suscipit laboriosam,
    nisi ut aliquid ex ea commodi consequatur? Quis autem vel
    eum iure reprehenderit qui in ea voluptate velit esse
    quam nihil molestiae consequatur, vel
    illum qui dolorem eum fugiat quo voluptas nulla pariatur?</span>
</p>

Absolute

Important - elements that are absolutely positioned also cede their position within the normal flow layout. Unlike relative elements, there is no gap and spacing left within the original content. Ultimately, this inconsistency works well for developers - because often relative positioned elements simply serve as anchors, and not leaving a gap for them would cause lots of complications. It's one of those situations where the inconsistency feels odd, but in practice it does make sense.

Armed with this new tool, let's revisit the text from the float section, and see if we can get our side bar to work. Recall, the goal was to have a left hand margin along the text with plenty of space for images. We wanted the images to appear in the same vertical position as they would normally. We can accomplish this by using absolute, and setting the parent's padding.

p {
    position: relative;
    padding-left: 10em;
}
.note {
    position: absolute;
    left: 0;
}
<p>
    Sed ut perspiciatis unde omnis iste natus error sit voluptatem
    accusantium doloremque laudantium, totam rem aperiam, eaque ipsa
    quae ab illo inventore veritatis et quasi architecto beatae vitae
    dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas
    sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui
    ratione voluptatem sequi nesciunt. Neque porro quisquam est,
    qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit,
    sed quia non numquam eius modi tempora incidunt ut labore et dolore
    magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum
    exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi
    consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate
    velit esse quam nihil molestiae consequatur, vel illum qui
    dolorem eum fugiat quo voluptas nulla pariatur?
    <img class="note" src="red-square.jpg" />
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus
    imperdiet, nulla et dictum interdum, nisi lorem egestas odio, 
    vitae scelerisque enim ligula venenatis dolor. Maecenas nisl est, 
    ultrices nec congue eget, auctor vitae massa.
    Fusce luctus vestibulum augue ut aliquet. Mauris ante ligula, facilisis sed ornare
    eu, lobortis in odio. Praesent convallis urna a lacus interdum ut hendrerit risus
    congue. Nunc sagittis dictum nisi, sed ullamcorper ipsum dignissim ac...
    At vero eos et accusamus et iusto odio dignissimos ducimus qui
    blanditiis praesentium voluptatum deleniti atque corrupti
    quos <img class="note" src="green-square.png" />
    dolores et quas molestias excepturi sint occaecati cupiditate
    non provident, similique sunt in culpa qui officia deserunt mollitia animi,
    id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita
    distinctio. Nam libero tempore, cum soluta nobis est eligendi optio
    cumque nihil impedit quo minus id quod maxime placeat facere
    possimus, omnis voluptas assumenda est, omnis dolor repellendus.
    Temporibus autem quibusdam et aut officiis debitis aut
    rerum necessitatibus saepe eveniet ut et voluptates repudiandae
    sint et molestiae non recusandae. Itaque earum rerum hic tenetur a
    sapiente delectus, ut aut reiciendis voluptatibus maiores alias
    consequatur aut perferendis doloribus asperiores repellat.
</p>

Absolute margins

Notice something important - the vertical placement of the absolute positioned element corresponds to where they normally would be in the flow layout! This is because we specified neither top nor bottom. The horizontal placement corresponds to 0px from the edge of the left margin of the parent p element (since p is positioned). Since absolute positioning allows you to place elements that encroach on other elements margin and padding, there is no problem placing the images in that empty space created by the padding we put on the p element. The padding-left on the p element is critical here - it's what is creating the space. Note, we could have also used margin, but then we'd need to set the left value to be a negative value, to move it to the left of the left edge of the paragraphs content area.

/* with unaltered HTML, this CSS has the same effect, 
   the note must be positioned offset to the left of 
   the p element now, since the p element is using margin
   instead of padding to create the space on the left side.
*/
p {
    position: relative;
    margin-left: 10em;
}
.note {
    position: absolute;
    left: -10em;
}

Recall however, with cotnrol comes a cost. When using absolute, we don't get any help from the browser. Well, what are we missing?

Here's a demonstration - using the same CSS, but with different HTML content.

<p>
    Quis autem vel eum iure reprehenderit qui in ea voluptate
    velit esse quam nihil molestiae consequatur, vel illum qui
    dolorem eum fugiat quo voluptas nulla pariatur?
    <img class="note" src="red-square.jpg" />
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. 
    At vero eos et accusamus et iusto odio dignissimos ducimus qui
    <img class="note" src="green-square.png" />
    dolores et quas molestias excepturi sint occaecati cupiditate
    non provident, similique sunt in culpa qui officia deserunt mollitia animi,
    id est laborum et dolorum fuga. 
</p>

Absolute yuck

Well, this is a problem! When things are absolutely positioned, the browser makes no attempt to make sure they don't overlap! This is the very nature of absolute positioning however. Ultimately, if you need to ensure this doesn't happen, and you don't have any control over the relative sizes of the content, the things positioned, etc, then you might end up needing client side JavaScript (and honestly, you probably should consider a simpler layout).

z-index

Now is a good time to talk about z-index, since our last example had very clearly overlapping images. Then things get rendered to the same location in the browser, we can use the z-index (think of the z-axis as extending out of the screen, towards you) to control what goes "on top". A larger z-index value will always appear over the top of an element with a lower number. z-index values are typically integers, and they can be positive or negative.

<p>
    Quis autem vel eum iure reprehenderit qui in ea voluptate
    velit esse quam nihil molestiae consequatur, vel illum qui
    dolorem eum fugiat quo voluptas nulla pariatur?
    <img class="note" style='z-index:1' src="red-square.jpg" />
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. 
    At vero eos et accusamus et iusto odio dignissimos ducimus qui
    <img class="note" style='z-index:0' src="green-square.png" />
    dolores et quas molestias excepturi sint occaecati cupiditate
    non provident, similique sunt in culpa qui officia deserunt mollitia animi,
    id est laborum et dolorum fuga. 
</p>

Absolute Z-Index

Opacity

We can also control the opacity, or transparency of an element. This can be helpful when we know (and plan for) overlap. Here', let's add opacity: 50% to the red-square, meaning it is 50% transparent.

<img class="note" style='z-index:1; opacity:50%' src="red-square.jpg" />

Absolute Opacity

Note that the entire element (entire red sqare image) is 50% transparent, so it appears lightened on top - allowing the white background to show through. If you need to make only part of an element transparent, you need to get much more sophisticated. CSS does include things like linear-gradient and masking, but these things are beyond our scope here - and not really commonly used.

Ultimately, absolute positioning is a powerful tool - but comes with a cost. When using absolute positioning, we take a lot of responsibility for how things end up getting laid out, and that can be difficult - especially when we consider screen sizes, density, and window resizing. Use absolute position with care!

position:fixed

The position fixed attribute works very similarly to absolute, but solves a different type of problem. Let's say, for example, you want a navigation bar to always be pinned to the top of the screen. You want content to scroll as normal, but you want the navigation bar to always stay at the top. This is easy enough to do with absolute positioning.

nav {
    position: absolute;
    top: 0;
    left: 0;
    right: 0; 
    height: 50px;
    background-color:green;

}
body {
    padding-top: 55px;
    border: 2px yellow solid;
}

The nav element is positioned to sit at the top of the screen. It's full width, since it's left and right are set to match the left and right of the body element (we aren't setting any other elements to be positioned). We've set a height of 50px, and set a body padding of 55px. This is important, because it prevents any other content in the body from being obscured by the nav.

<body>
    <nav>This is a navbar</nav>
    <p> Quis autem vel eum iure reprehenderit qui in ea voluptate
    velit esse quam nihil molestiae.....
    </p>
</body>

Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus imperdiet, nulla et dictum interdum, nisi lorem egestas odio, vitae scelerisque enim ligula venenatis dolor. Maecenas nisl est, ultrices nec congue eget, auctor vitae massa. Fusce luctus vestibulum augue ut aliquet. Mauris ante ligula, facilisis sed ornare eu, lobortis in odio. Praesent convallis urna a lacus interdum ut hendrerit risus congue. Nunc sagittis dictum nisi, sed ullamcorper ipsum dignissim ac... At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.

Give it a try, scroll a bit. It doesn't work, and that's because the top of 0px set as the position of the nav element is relative to the body, and the body is moving as you scroll. 0px relative to the body means it's up above the viewable area when you scroll down.

Intuitive, it may have felt to you that it would work, and fortunately, the concept works - but we need a small fix. The position attribute we are looking for is fixed. fixed tells the browser to compute the position of the element not relative to another element, but instead the viewable area - better known as the viewport. Fixed is a little newer than absolute, and if you search the internet you will find old solutions that use JavaScript to capture the scroll position, and compute new offsets as the user scrolls. Don't do this, fixed is the right solution, and works in all browsers.

By the way, you can also use fixed to fix things to the bottom, left, and right of the viewport - which is especially helpful for the footers to web pages.

Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus imperdiet, nulla et dictum interdum, nisi lorem egestas odio, vitae scelerisque enim ligula venenatis dolor. Maecenas nisl est, ultrices nec congue eget, auctor vitae massa. Fusce luctus vestibulum augue ut aliquet. Mauris ante ligula, facilisis sed ornare eu, lobortis in odio. Praesent convallis urna a lacus interdum ut hendrerit risus congue. Nunc sagittis dictum nisi, sed ullamcorper ipsum dignissim ac... At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.

By the way, if you are looking at the HTML of the demo above, you'll see I didn't actually use fixed. That's because I wanted it to be embedded within the page and text. The demo has the same effect, but it's using absolute, since the nav is actually being pinned to the element.

position:sticky

Finally, we arrive at the newest form of positioning - sticky. Sticky creates a really popular and slick effect of keeping certain elements always on the screen, without changing the layout unless necessary.

Assume you have a long text, with a particular highlighted portion in the first paragraph. As the user scrolls, you don't want them to lose sight of the highlighted position. As the paragraph scrolls above the viewport, you would like the highlighted area to stay on the screen - perhaps stuck to the top left side. If the user scrolls back up, you'd like the highlighted text to move right back into the paragraphs.

Here's how you do it:

p {
    position: relative;
    height: 300px;
    overflow: auto;
}
.sticky {
    v
}
<p>
    Sed ut perspiciatis unde omnis iste natus error sit voluptatem
    accusantium doloremque laudantium, totam rem aperiam, eaque ipsa
    quae ab illo inventore veritatis et quasi architecto beatae vitae
    dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas
    sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui
    ratione voluptatem sequi nesciunt. Neque porro quisquam est,
    qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit,
    sed quia non numquam eius modi tempora incidunt ut labore et dolore
    magnam aliquam quaerat voluptatem. <span class="sticky">Ut enim</span> ad 
    minima veniam, quis nostrum exercitationem ullam corporis 
    suscipit laboriosam, nisi ut aliquid ex ea commodi
    consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate
    velit esse quam nihil molestiae consequatur, vel illum qui
    dolorem eum fugiat quo voluptas nulla pariatur?
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus
    imperdiet, nulla et dictum interdum, nisi lorem egestas odio, 
    vitae scelerisque enim ligula venenatis dolor. Maecenas nisl est, 
    ultrices nec congue eget, auctor vitae massa.
    Fusce luctus vestibulum augue ut aliquet. Mauris ante ligula, facilisis sed ornare
    eu, lobortis in odio. Praesent convallis urna a lacus interdum ut hendrerit risus
    congue. Nunc sagittis dictum nisi, sed ullamcorper ipsum dignissim ac...
    At vero eos et accusamus et iusto odio dignissimos ducimus qui
    blanditiis praesentium voluptatum deleniti atque corrupti
    quos dolores et quas molestias excepturi sint occaecati cupiditate
    non provident, similique sunt in culpa qui officia deserunt mollitia animi,
    id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita
    distinctio. Nam libero tempore, cum soluta nobis est eligendi optio
    cumque nihil impedit quo minus id quod maxime placeat facere
    possimus, omnis voluptas assumenda est, omnis dolor repellendus.
    Temporibus autem quibusdam et aut officiis debitis aut
    rerum necessitatibus saepe eveniet ut et voluptates repudiandae
    sint et molestiae non recusandae. Itaque earum rerum hic tenetur a
    sapiente delectus, ut aut reiciendis voluptatibus maiores alias
    consequatur aut perferendis doloribus asperiores repellat.
</p>

Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur? Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus imperdiet, nulla et dictum interdum, nisi lorem egestas odio, vitae scelerisque enim ligula venenatis dolor. Maecenas nisl est, ultrices nec congue eget, auctor vitae massa. Fusce luctus vestibulum augue ut aliquet. Mauris ante ligula, facilisis sed ornare eu, lobortis in odio. Praesent convallis urna a lacus interdum ut hendrerit risus congue. Nunc sagittis dictum nisi, sed ullamcorper ipsum dignissim ac... At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.

Sticky is a very common UI pattern for navigation bars and page leads. It's an example of how fast CSS has begun to move as well. I'd compare this to box shadows and rounded corners - where for the better part of 10 years developers expended countless resources implementing the effects themselves (poorly). Modern CSS adapts to developer needs faster. When the sticky heading and footing styles became popular, the sticky positioning was added to CSS much more quickly!

You can get a long way with flow layout, float, and occasional positioning. Until 2012, these positioning methods were the only ones that developers had to create layouts. As we will discuss in the next chapter, the need for better layout methods actually drove the adoption of CSS frameworks like Bootstrap. Complex, yet extremely practical and helpful layouts like grids are achievable with the positioning techniques described in this section, but the are difficult, and really difficult to get right for all screen sizes, densities, and window sizes.

Thankfully, in 2012 the CSS standards organization began development on flexbox. Flexbox became widely adopted in 2016, and was a giant leap forward in helping developers create grids and other practical layouts that flow layout struggles with.