dCode_Understanding CSS Positioning

What is usually forgotten is that the spec hadn’t been completed at the time IE5 was released. IE5 followed the spec as it existed at that time but the box model in the spec itself was then changed before it was completed.

5 Likes

Yes, a good point. It seems IE5 was actually ahead of the game at the time :slight_smile:

To be honest I don’t often find the need to use calc other than in edge case demos but there are a couple of places they can be useful if especially you are using the content-box model (the standard model).

e.g. If you want two floats next to each other but one is a fixed width and both have padding and borders then you can’t do it without using calc (there are other ways of doing this without using floats so assume floats are requisite).

Calc has also being used for responsive text resizing.

Calc is just another tool in the toolbox that comes in useful when you need it.

5 Likes

Sometimes an absolute object can use auto as coordinates to relate to the non-positioned parent’s position in the flow in the positioned container.

That has been useful a number of times. I have an example of this at JsFiddle: Adaptive-CSS-Tooltip

a[data-tooltip]:hover:before{
    position:absolute; /* auto position also lets tooltip wrap instead of overflow the RP parent's right edge */
    z-index:1;
    top:auto;
    left:auto;
    margin-top:1em;
    content:attr(data-tooltip);
}
3 Likes

Leave Your Relatives at Home

As this thread is about positioning I ought to for the sake of beginners mention why moving elements around with relative positioning is usually a bad thing to do unless you know what you are doing.

I often see in the forums where someone has shifted an element into place using relative positioning only to find out later that it breaks everything else and ‘appears’ to disrupt the flow of the document.

The first things to know about moving elements relatively is that in reality they don’t get moved at all!!

The space that the relative element originally occupied in the flow of the document is always preserved. Therefore when you move an element using relative positioning you are not really moving anything at all visually but you are making the element appear as though it is somewhere else.

Of course this new location cares nothing about any new flow of the document and may overlap or obscure other elements on the page. It won’t interact with other elements any differently had it not been moved at all.

This makes it clear that you can’t really use relative positioning for any structural layout (although there are edge cases of course) and generally you would use relative positioning to move an element without disrupting anything around it; perhaps to create some subtle overlapping effect or just to move one thing without having a knock on effect to other elements in the flow.

Here’s a short demo that makes it easy to see what happens when you move an element with relative positioning.

The black background is marking the space that the relatively placed element originally occupied and as per the specs this space is always preserved. Therefore when you move an element using relative positioning you are not really moving anything at all visually but you are making the element appear as though it is somewhere else.

It is also worth mentioning that relative position when used without co-ordinates is fine and is usually added so that z-index can be applied as in CSS2.1 z-index only applies to elements with a position other than static (the default). (In later specs elements with opacity or transforms (IIRC) can create local stacking contexts without position applied).

5 Likes

Thanks and I’ve added your extra demos to the end now also.

One of the benefits of pushing browsers to the limit is that you often run into unexpected or buggy behaviour which you can then avoid in real sites

In example 14 of the demo the example appears to work in Chrome but if you resize the browser smaller then the box stays wide and overflows the screen. If you click refresh it pops back into place so Chrome seems to forget to keep track of calc. What’s even stranger is that if you start small and then go wide it all works ok.

Another bug that came to light in Example 14 is that IE (Including edge) do not obey calc when used with the text-indent property (although it should be fine). (I have seen other bugs in IE with calc such as not honouring 100% when used on a font-size).

These types of bugs don’t often show in normal use so demos like these can prove very useful in weeding out the buggy browsers:)

6 Likes

A post was split to a new topic: Background Gradient & Aside Problems

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