dCode_Understanding CSS Positioning

Paul O’Brien is a widely recognized expert in all things CSS.

In this forum dCode, he answers anything and everything about the tricky subject of CSS positioning — from floats and relative, absolute and fixed positioning to table display and even flexbox.

If you have any questions about CSS positioning, please post them below!


About dCodes

Our Forum dCodes are topics that feature a guest who conducts a deep dive into a subject area. Unlike our Q&A sessions, which run for just an hour, dCode topics stay open over a long period, so that issues can be discussed at greater length and in greater depth. You can ask questions, or just sit back and follow along, over time, as the guest answers questions and posts content of interest.

2 Likes

Hi,

This thread is about positioning elements with CSS and to get the thread started and to give you all something to think/talk about I’ve created a small demo that simply places a small 50px fixed width and height red box to the right of the page. The html is basically as follows:

<div class="wrap">
  <div class="box">Box</div>
</div>

Before you look at the demo take some time and see how many ways you can think of doing this?

You may immediately think of about 3 ways to do this but as you delve into the details you find that there are in fact many ways to do this and in the demo I stopped at 15 but I wouldn’t be surprised to see quite a few ways I hadn’t thought of cropping up!

Here’s my demo and see if you can come up with other ways to do this:

The point of the exercise was simply to show that in CSS there are often many ways that a layout can be achieved and often the solution depends on what comes next as to what method is best to use. I often say that “the beauty of CSS is that there are many ways to do the same thing” but the difficulty for beginners is knowing which is the right way for the job in hand.

Now that you have looked at the demo (be honest here) how many of you thought of or understood the very first method in the demo?

This was the simplest and most basic answer and probably one of the first lessons learned and forgotten by most people and I will guess that few of you will have thought of it.

.box {margin:0 0 0 auto; width:50px; height:50px;background:red;}

It looks simple enough but how does that put a box to the right of the page?

We are all familiar with ‘margin:0 auto’ which will centre block elements horizontally but how does margin:0 0 0 auto; move a box to the right?

To answer this you need to refer to the specifications but a simplified example is that the width + padding + margins = width of the containing block.

Therefore, for a fixed width element that has a right margin of zero then the left margin must equal the distance left to the left edge of the containing block. This is achieved with a margin-left of auto.

If instead you put a margin-left of zero then the box moves to the left side and in ltr languages the margin-right zero would then equate to auto (even if you specify zero) in order for the requirements of the box model to hold true.

lastly if you put a margin-left and margin-right of auto then the box becomes centred as we all know and love.

(I have simplified the answer so read the specs for full details and understanding.)

I mention this auto margin technique because it is a prominent technique when using flexbox and an auto margin on a flex-item will move that element to the edge of the box (whether that be left , right up or down). Incidentally it is not well known that margin:auto on an absolutely positioned element will centre the element both horizontally and vertically within a fixed height and width container. (http://codepen.io/paulobrien/pen/jAzkpY)

That’s enough about margins anyway and have a look through the rest of the examples in the first demo and if you can think of more ways to do this then feel free to post or discuss.

If you don’t understand any of the examples then please discuss and we can clarify.

Note that this thread isn’t simply about this first post but mainly as a talking point to keep things moving so if you have topics you wish to discuss then please go ahead.

I look forward to answering or being baffled by your queries. I can’t guarantee to know all the answers but I’m sure if I don’t know the answer someone else will have a good idea and chip in to the conversation.

12 Likes

Go with the flow!

One concept that will help with positioning elements in a responsive and responsible manner is to always place elements so that you do not disrupt the flow of the page.

It may seem strange to talk about “flow” in terms of a web page but what we are referring to is the fact that content can flow from top to bottom easily and without restriction.

Imagine if you have two paragraphs of text on the page and nothing else and no styling. If you resize the browser window the text flows and adapts as required without any effort on your behalf. You can even add another paragraph, add or remove words and the page still works and the content flows up and down without restriction.

Now imagine if the first paragraph was absolutely placed at the top of the page and the second paragraph was absolutely placed at 100px from the top (because that’s how high you think the paragraph is). If you resize the browser window now or add more content to the first paragraph the page no longer has a flow and everything stays where it was placed except now the content overflows and obscures other content that is in the way. We have now lost the flow of the page and in order to add more elements we would need to make a guess with magic numbers as to where content could reside but we would ultimately fail.

Beginners often fall into the ‘absolute trap’ because its something they can understand easily (e.g. 10px from top and 10px from the left) but in doing so immediately create a problem that cannot be rectified.

Absolute positioning is fine as long as it does not disrupt the flow and that means when you absolutely place something it must live in a place where it will do no harm and not interrupt the flow of the rest of the page.

In most cases you simply want elements to follow logically one after the after (no positioning or fixed heights are needed) and in that way you can add or remove content anywhere and not need to re-style every other element on the page as you would if it was all absolutely placed.

When laying out a web page you need to use properties that maintain the flow of the page and indeed that is mostly anything except absolute/fixed or relative positioning. For most other properties (even floats) you can control the flow of the page and let content flow logically from one to the next. You can space content with margins or align horizontally with floats, display:inline-block, display:table-cell, flexbox etc and still maintain the flow of the page.

Lastly, a quick word on ‘heights’ (of which we will probably talk more about later). As a general rule don’t set fixed heights on your containers if they contain fluid content like text. The reason for this is that fixed heights mean an element cannot grow past that point (unless it has the property/value of display:table) and once again you break the flow of the page.

7 Likes

One of the keys for how CSS works, is the ‘box model’. I’ve always felt that if that is understood first, CSS becomes a rather simpler set of instructions to work with.

How would you recommend that those new to CSS go about understanding it?

5 Likes

I can’t believe you found so many ways to do it so you couldn’t stop yourself until fifteen.

“immediately think of 3 ways”? I couldn’t find more than one way to do it:

.wrap16{ text-align:justify; line-height:0}
.wrap16:before{ display:inline-block; content:"\a0"}
.wrap16:after{ display:inline-block; margin-right:100%; content:"\a0"}
.wrap16 .box{ display:inline-block}
4 Likes

With flexbox rising in popularity as the cream of the crop for all matters positioning, do you think we even need more layout modules? What else could be offered that we don’t have? There are very few positioning issues which I run into which can’t be resolved with the tools available, but I hear modules such as the grid and others are currently in talks. What do you think about this?

5 Likes

Yes the box model is important in understanding how elements are laid out on the page and how padding, margin, border and width/height all play their part.

I remember being confused when I first started especially as IE5 used a different ‘box model’ from the specs. We commonly referred to it as the ‘broken box model’ !!

Times change, and now due to the box-sizing property we now have a choice in which box model we use and a lot of developers prefer to use the old (broken) box model which is now called the border-box model as opposed to the content-box model .

The border-box model (As seen in old IE5 and old IE versions in quirks mode) starts with a width and height and then padding and borders are placed inside that width and height which leave less space for actual content. However it means you can do things like width:100%, padding:3em and border-width:10px with no problem.

In the normal content-box model padding and borders are placed outside the width and height thus leaving the space for content untouched but increases the elements overall dimensions. (Try making two floats of 50% width width 3em padding and getting them to fit side by side without using nested elements or calc!)

I find the easy way to understand the box model is by visual representations and the Sitepoint reference has a nice article on the subject here.

When talking about the box model I often think in terms of a real box (as nearly everything in CSS is a box shape of sorts) where borders, padding and content are the stuff you stick inside the box and margins are how far away from other boxes the box is.

In order for a box to fit where you want it to then all the margins, padding, borders and widths must make sense and add up to match the available space.

6 Likes

It was a good way though :slight_smile:

Thanks Erik, I knew you would have something up your sleeve.

That makes 16 ways so far and there are a few more although some may be variations on what went before.

4 Likes

I think the grid module when it arrives will allow us to do all the things we dreamed of but it may just make it that bit harder to get started. I like to keep an eye these new layout methods but I tend not to delve deeply into them until they are ready for use.

When working I often favour a ‘Reduced Instruction Set’ as you can often do more with less because you become more inventive and more knowledgeable with those simpler tools.

Flexbox is great and the more I use the more I like it but I still feel like a beginner with it. Indeed even the experts get it wrong sometimes and this page at CSS Tricks is a brilliant guide to flexbox but their 3 column (holy grail) layout is broken (just try adding content into their aside bars). Way back In 2003 I solved the holy grail layout (as did others) with the tools available at the time but 13 years later people are still getting it wrong.

My favourite layout technique since I had the luxury of not supporting less than IE8 is to use the display table and table-cell properties. I see no need to use flex box for equal columns when this method works all the way back to IE8 almost flawlessly in every browser. These days I rarely use floats for columns and floats are consigned to er umm… floating things… like images:)

Flexbox is great for other smaller components but I only feel the need to use it when necessary or when it does the job easier and better than other methods.

I’ve put up a demo of common flexbox patterns which may prove useful for those taking the plunge into flexbox.

Fell free to discuss or point out issues you see or come across.

5 Likes

Which method would you recommend to build a card layout like Pinterest?

1 Like

Yes, I think they all are mainly variation of three cases: let it position itself right or affect it by another element pushing it right from the left or another pulling it from the right.

E.g:
The 16th was positioning itself.

The 17th is pulled from the right:

.wrap17{ width:100%; text-align:center}
.wrap17:after{ display:inline-block; margin:0 -100% 0 45px; content:"\a0"}
.wrap17 .box{ display:inline-block}

The 18th is pushed to the right:

.wrap18:before{ display:inline-block; margin-right:-55px; width:100%; content:""}
.wrap18 .box{ display:inline-block}

That’s one way to describe what is going on.

I’m still amazed when I look at your demo.

3 Likes

I assume we are talking about the ‘masonry’ effect where blocks are uneven heights and stacked together without gaps so that you get a patchwork effect. These kinds of layouts are challenging and pose some difficult questions.

The pinterest page is basically built with JS and absolute positioning. It doesn’t work at all with JS turned off which is a shame as a lot of basic functions could still be available without JS. The cards could simply be arranged in rows if js is turned off but at present the whole page is blank with js off.

To do it in pure CSS would be difficult until grid layout is available but flexbox can be made to do something similar.

You can also use CSS columns to good effect but of course the order is top to bottom instead of left to right although for unrelated items that should not matter.

I’m not a big fan of those ‘masonry’ type layouts as I just seem to get lost in the middle of them.:slight_smile: In small doses they can be effective but I like my pages more organised so that I can scan more easily.

6 Likes

Yes good summary :slight_smile:

Maybe also add "not really moving it at all but move everything else instead ":slight_smile:

2 Likes

I find amusing that you use calc in one of your examples.

I’ve never seen it used anywhere, to be honest. Does it really have a purpose? I mean I can’t think of any particular situation where it is practical to use it.

What made you think of it to add it to your list of examples?

2 Likes

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