dCode_Understanding CSS Positioning

Which type of positioning is best?

I am often asked the above question and a tongue in cheek answer I often give is no positioning is best:)

If we take a basic page with no styling:

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>

<body>
<h1>The Cosmos Awaits</h1>
<p>Tesseract radio telescope, laws of physics light years great turbulent clouds stirred by starlight, Orion's sword emerged into consciousness. Made in the interiors of collapsing stars gathered by gravity, colonies muse about encyclopaedia galactica Apollonius of Perga, quasar how far away globular star cluster vastness is bearable only through love vanquish the impossible gathered by gravity, vastness is bearable only through love a still more glorious dawn awaits Hypatia paroxysm of global death, citizens of distant epochs venture, preserve and cherish that pale blue dot circumnavigated</p>
<h2>Cosmic fugue</h2>
<p>Rings of Uranus, vanquish the impossible network of wormholes paroxysm of global death Jean-François Champollion galaxies. Prime number gathered by gravity of brilliant syntheses, tingling of the spine two ghostly white figures in coveralls and helmets are soflty dancing. Muse about. Cambrian explosion white dwarf a billion trillion descended from astronomers, circumnavigated science, vastness is bearable only through love galaxies extraordinary claims require extraordinary evidence star stuff harvesting star light across the centuries prime number Hypatia, rich in mystery Euclid!</p>
</body>
</html>

The above page while it may not look very nice will work and be accessible across all devices without any effort at all on our part. It caters for all user settings straight out of the box.

It’s only when we apply our (or our clients) ideas of how a page should look that we start to break what was once fluid, adaptable and accessible. Perhaps the first thing a web designer should say to himself is “first do no harm”. :slight_smile:

Of course I am being simplistic and styling can make the page more readable and more presentable but we should always keep an eye on how our rigid ideas of what a page should look like can impact on was once a fluid and accessible page.

It follows therefore that sometimes “less is more” and if we can organise our content so that the page can still flow freely like a river then we have a better chance of doing no harm.

With the above in mind next time you develop a site think about a few simple things that can greatly improve a users experience that are easy to implement.

For example:

  • do leave the html, body font-size to 100% and use that size for all your main context text. In that way your users will get the text size that they think is best for them.

  • do use max-width and margin:auto for your main container rather than a fixed width.

  • don’t set heights on fluid content

  • don’t fill every pixel on the screen with something.

  • don’t expect that x amount of words will always fit in the space you have available.

6 Likes

Let me fix your design.

When I ran into position:fixed in the early days it was like some kind of magic (especially as it didn’t work in IE6 which was the browser that had about 95% of the market at the time).

Today, it still seems like magic but it’s a trick I can do.

I’m sure you are all familiar with position:fixed but in simple terms it places an element on the screen that doesn’t move when the page is scrolled. This is very handy for a message that you always want displayed such as a copyright message, or a back to top link, or a small always visible header.

The mechanics of position:fixed are that the element is always placed in relation to the viewport and not in relation to a positioned parent (unlike absolute positioning). This can make its use tricky when you want to match other elements on the page.

Without getting bogged down in the finer details there are a number of things you need to know about fixed positioning so that you can cater for them in your design:

  • fixed elements are removed from the flow and do not interact with other elements.

  • fixed elements that extend outside the viewport are unreachable because you cannot scroll a fixed element (you can scroll content inside the fixed element but you cannot scroll the element itself in the viewport).

  • a fixed header will sit on top of the natural content in the page which means you need to create an offset for the normal content or it will always remain hidden (the same applies to a fixed footer).

  • fixed headers and footers are best suited to one line of text that doesn’t wrap. Otherwise if the content is fluid and wraps the height of the element increases and then it will cause some of the content of the page to be obscured and unreachable.

  • if you scroll to an in-page link in a page that has a fixed header then the destination will most likely be scrolled under the fixed header and be obscured.

  • on small screens/ mobile a fixed header may take up most of the screen leaving little room for content and the site almost impossible to use.

As you can see there are a number of issues that you have to take care of and control when using fixed elements.

I feel it is best to use fixed elements in small doses and for small unobtrusive messages. If you want a larger fixed element such as a header with navigation then you are better implementing a sticky header approach which gives you the best of both worlds. The header starts off as static but as you scroll it becomes fixed. It would also be wise to remove this functionality for smaller screens by using media queries to allow the element to remain static.

The in-page link problem is hard to solve without JS but if you have a fixed height header then you can offset a target link to account for this. It does smell of magic numbers though and of course doesn’t cater for a fluid height header.

Which brings me to the question of a fluid height fixed header and how to adapt content underneath when the screen width is reduced or enlarged. You could set up many media queries to change the height of the content offset but that soon becomes complicated for all but for the simplest layout. In the end you would need to use some js to measure the height of the element and adjust the content offset so that it is still visible. (Note the demos I’ve linked to are just proof of concept and not fully fledged solutions).

What about you? (after all this is a discussion)

Have you tried fixed positioning?

How did you get on?

How did you fix the issues you ran into?

2 Likes

I’ve used position fixed for JavaScript modal dialog messages a few times.

It has been OK as long as the content was minimal.

Other than that I’ve never really found much use for position fixed and even then it wasn’t essential.

2 Likes

I’ve used {position:fixed} to graphically “punch a hole” in a foreground container and give the illusion that the page’s background pattern is showing through. It works a treat for illusions like that.

5 Likes

I’ve used it for a vertical side nav, so it’s available anywhere down the page and it seems to work.
I did add a height query to collapse to hamburger (as well as width), just in case the screen is not high enough to show the whole thing, because it can’t be scrolled.

4 Likes

What is the display value of an absolute element?

When you make an element position:absolute its computed display value is changed according to the table here in the specs.

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.

If the element is inline by default (like a span) then when you make it position:absolute its display becomes block which is why you can add dimensions to it without explicitly making the element a block element. (Refer to the table here for a full list.)

It should therefore follow that there is no need to set display:block to an absolute element and that display:inline would have no influence?

Or does it?

Take a look at this code and guess where the absolute element will be placed.

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
<style>
span{position:absolute;padding:5px;background:rgba(0,0,0,0.5);color:#fff;}
</style>
</head>
<body>
<p>Lorem ispum dolor sit amet <span>Absolute</span> dolor sit amet.</p>
</body>
</html>

Because the element is auto positioned (no co-ordinates) then it should become absolutely placed at that point in the flow and overlap the text on that line somewhere around the word ‘amet’. Which it does:

Now add display:block to the absolute element and see what happens.

span{display:block}

As you can see the absolute element has now dropped to the next line.

Therefore it is important when using absolute elements to take care of what display they have when using auto positions. Although absolute elements are display:block by default the block position it will not affect the auto position of the element which will be whatever its previous display:value was.

Using your new found knowledge of absolute elements have a guess at where the following code will place the absolute element?

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
<style>
p{text-align:right}
span{position:absolute;padding:5px;background:rgba(0,0,0,0.5);color:#fff;}
</style>
</head>
<body>
<p><span>Absolute</span> </p>
</body>
</html>

All I added was p{text-align:right} so see if you can guess where the absolute element will be?

Did you get it right?

errr yes and no.

In good browsers the element will be to the far right of screen and poking out of the parent. That is the correct position but if you look in IE11 you will see that IE11 gets this wrong and doesn’t place it to the right unless there was also a little text actually in the line with the absolute element (IE Edge is ok).

So now you know that auto positioned absolute elements are affected by the display value and that they are also affected by the text-alignment of the parent (text-align:right text-align:center etc.).

With that in mind I have updated the box to the right demo with Example 19 using the techniques we just mentioned to move the box to the right.

These are all behaviours (and bugs in IE) that can bite the unwary so make absolutely sure you know where your absolute element is :slight_smile:

.

5 Likes

Why when using text-align:right do you have to use display:inline-block to shift the box to the right? And why without using the inline-block will it only shift the content to the right.

2 Likes

Text Align only works on in-line elements, it does not work on blocks.
Think of in-line as being like words of text, they sit on a line, one after the next, then wrap to a new line when the line runs out of space.
inline-block makes a block behave like a word in text.

4 Likes

This scroll indicator by Mike Riethmuller is doing the rounds but is worth mentioning as it shows what can be achieved by simply thinking outside the box.

It only takes a few lines of css and neatly accomplishes what would normally have to be scripted.

See if you can work out how it works as it will give you an insight into different aspects of css positioning.

9 Likes

That’s pretty cool :slight_smile: . Thanks for sharing, Paul. For those who are having trouble figuring it out, remove the body:before{} CSS and you can get a clear visual of what’s going on.

5 Likes

Many thanks for this dCode! When it comes to CSS, Paul is a grand master!

Not sure if it’s worth mentioning. Here’s, however, what I have to add to the list:

.wrap20 {display:flex; flex-direction:row-reverse;}

2 Likes

Ok added to list :slight_smile:

1 Like

Two more:

.wrap21 {padding-left:calc(100% - 50px);}

and

.wrap22 {text-align:right;}
.wrap22 .box {display:inline-flex;}
2 Likes

Hi @Mori, nice! :slight_smile:

Your example #20 was a new flex variant to #11:

.wrap11{ display:flex; justify-content:flex-end}

Your #21 seems to be a new grip.

Your example #22 would become a sequal to #4 and #9 in the demo.

.wrap4{ text-align:right}
.wrap4 .box{ display:inline-block}

.wrap9{ text-align:right}
.wrap9 .box{ display:inline-table}
2 Likes

There is one more variant to consider, if you like. :slight_smile:

The one you used in your solution for the “poem” in the CSS challenge post 21: https://www.sitepoint.com/community/t/css-diverse-text-alignment-challenge/256571/21:

/* reversed CSS Quiz solution */
.wrap23{ direction:rtl; white-space:nowrap}
.wrap23:before{ float:left; margin-right:999em; content:"\a0"}
.wrap23 .box{ display:inline-block}
2 Likes

Thanks Erik I added it to the end of the list :slight_smile:

1 Like

One more time the flexbox model comes to the rescue:

.wrap24 {display:flex;}
.wrap24:before {content:""; flex:1;}
3 Likes

Ok thanks added :slight_smile:

There’s probably going to be a lot more ways now that grid has landed in Chrome and Firefox :slight_smile:

Are the following declarations added to resolve the Chrome bug:

.wrap14 {display:table; width:100%;}

If so they’re not needed anymore in the latest version of Chrome:

.wrap14 {text-indent:calc(100% - 50px);}
.wrap14 .box {display:inline-block; text-indent:0;}

Yes, the list seems to be endless! :slight_smile:

1 Like