Unable to position an element
# April 25, 2013 at 7:46 am
I’m trying to position this ‘ABOUT ME’ box but I am unable to posiition it down. I can move it left or right using margin-left or margin-right properties but I’m not able to move it top or down. I have used float:right to position the sidebar. So I used clear:both on my header. But still it remains stationary.
The following images will help you to understand my problem.
The code of this page is [here](http://jsfiddle.net/ZFzp7/ “here”) (jsFiddle)# April 25, 2013 at 11:05 am
There’s a couple of things going on here. You have margin collapse, clearance, and block formatting context all coming into play. I’ll try to explain what’s going on. For the record, I disagree with some of the statements above – absolute positioning has its place/purpose (although probably not here), and layout using left and top margins is acceptable, but again you need to understand how it works and what’s at play.
In your fiddle you have a wrapper, a floating #nav, and a #box with clear: both. Let’s remove the clear: both to take the clearance out of the equation for a minute. You might not have expected the results. Both the #nav and #box appear to have a top margin of (approximately) 500px. Why does the nav appear to? It’s collapsing margins. The top margin on #box is actually protruding out from the top of #wrapper – this is normal, and in effect pushes the top of the #wrapper down 500px; which is why the #nav, with no top margin, appears so low. It is at the top of #wrapper, but #wrapper has been moved down.
Now, without introducing the clear. Let’s look at how to change this. There are three ways. 1 and 2) add a top padding _and/or_ a top border to #wrapper. This gives #box’s top margin something to ‘push’ against. 3) change #wrapper’s block formatting context, in which there are a number of ways. One way is to float the wrapper and another is to add overflow: hidden; so let’s add overflow: hidden. Now the #wrapper, with it’s new block formatting context, is back up top, the #nav is at top of #wrapper, and the #box is pushed down 500px with its top margin.
Incidentally, if there was no #wrapper and just the body, the top padding and top margin trick would work, but the body’s block formatting context cannot be changed – it’s the base block from which all others’ are derived.
Now, let’s go back to square one – remove the overflow from #wrapper and re-establish the clear: both on #box. Why doesn’t the margin still push the #wrapper (or #box for that matter) down in this situation? It’s called clearance – any clear value other than none, will cause the top margin to be re-calculated with a clearance value added. In this case, the top of #box is set to the bottom of #nav and the ‘extra’ top margin is still collapsing outside of #wrapper. But the clear: both did establish a clearance and a new position for #box. So, why didn’t it push the #wrapper down the additional extra top margin? I don’t claim to fully grok the exact reason, other than clearance inhibits margin-collapsing. The specs state that an element with clearance and its parent’s margins are _not_ adjoining and therefore _don’t_ collapse (collapse is what happened when we removed the clearance and the #wrapper was pushed down), but in calculating clearance, collapsed margin is taken into account…
Now, add back again the overflow: hidden; to #wrapper (or any of the other methods mentioned above) and we’re back to the results from the first test – this is true whether #box has clear: both or not. Again, when calculating clearance and the margin is _not_ collapsed with the parent, the expected behavior results.
So, I hope this gives a better understanding as to what is happening. Now, to address the best (or perhaps, an appropriate) way of handling the situation – could you provide an image of the desired result and I, or the others, can show how we would tackle the layout.
You must be logged in to reply to this topic.