i read that negative margin-top and left takes the element and pushes it in this direction. On the other hand negative bottom and right margins draw the rest of the content over the element.
Question
I have a floated element float:right; wrapped in the body tag. Negative left margin will move it to the left.
Negative RIGHT margin wont do anything at all because the document ends where this negative margin starts and there is nothing to draw over the element (or pull over it)?
Am i correct?
Negative margins will always work on block boxes the same way that positive margins do. They just move a box and/or surrounding boxes in the opposite direction that positive margins do. Heck, negative margins can even collapse.
If any overflow occurs, then related boxes will adjust and accommodate for this box's movement.
If an element is floated in a certain direction, then a margin on the side that it's being floated towards will have an effect on its own position, and a margin on the opposite site will influence it relatively to any succeeding floats.
Negative RIGHT margin wont do anything at all because the document ends where this negative margin starts and there is nothing to draw over the element (or pull over it)?
No. There is this thing called the canvas, which has a theoretically unlimited amount of space for expansion. Got a margin pushing an element out of the page body or page root? NBD, just expand the canvas in that direction, make a scrollbar in the viewport which is used to display this canvas, and done.
It's the same as if you had a negative margin on an element whose parent has overflow: auto, because the root element itself has overflow: auto by default (since you can't really have stuff visibly overflowing the browser window itself...).
jsFiddle proof-of-concept
Many people believe the same misconception about negative margins. The behavior you describe tends to match many negative margins cases, but it is explaining them from a flawed perspective. Actually, negative margins have the same effect on any side of the box, but not in terms of "move the box" or "draw other content in".
For example, a left-margin: -20px means "position the element as if its left edge were 20 pixels inwards from its true left edge". A right-margin: -20px means exactly the same thing, but for the right edge.
In the simplistic description you have provided, the negative left margin would indeed shift the element itself leftwards, because its left edge is placed adjacent to the previous element's right edge, but the browser pretends that our element's left edge is actually moved rightwards, so the content of the element itself appears moved leftwards.
With the negative right margin, the browser places the next element's left edge adjacent to our element's right edge, but it pretends that our element's right edge is moved leftwards, so the next element itself appears moved leftwards.
In both cases, the only thing that is changed is the browser's notion of the position of the element's edges.
When you have a right-floated element, the browser will position it so that its right edge will be adjacent to the left edge of the previous right-floated element, or if there is no previous right-floated element, it will be adjacent to the right edge of its position parent (which is the closest parent element with a position style that is not static). In your case you don't have a previous right-floated element, so the browser positions your element so that its right edge is adjacent to the parent's right edge, but it pretends your element's right edge is moved leftwards, so your actual content is moved rightwards, protruding outside of the parent element.
Here is a demonstration. The box with the blue border has negative left and right margins. The yellow box inside it represents how the browser considers it — it is narrower than the blue-bordered box, because the negative margins tell the browser to move its edges inwards, eating from the element's actual size. As you can see, its positioning box is placed exactly as any element would be, touching its left and right siblings on both sides. And the actual content extends in both directions by exactly the same amount, because its negative margins are the same. The perceived change is that the element itself is moved left due to its left margin, and following content is moved left due to its right margin, but as you can see, in reality, the effect is exactly the same on both sides.
Negative right margin sure works! http://fiddle.jshell.net/H6mjC/
also made a fiddle. Of course negative margin is working.
fiddle with negative margin
enter code here
Related
I have two divs in this jsFiddle - http://jsfiddle.net/z4062jfn/ - with absolute positioning. I didn't expect any margin values given to the divs to affect their absolute position. And this is true for a margin-bottom value given to the top div (uncomment line 8 of CSS). But a margin-top value given to the bottom box (uncomment line 19 of CSS) does move the bottom div position down by that amount.
What is there in this situation that lets a margin rule override an absolute position rule - sometimes?
<div id="box1"><p>box 1</p></div>
<div id="box2"><p>box 2</p></div>
The simple factual explanation for why this happens is that the offset properties top, right, bottom and left actually respect the corresponding margin properties on each side. The spec says that these properties specify how far the margin edge of a box is offset from that particular side. The margin edge is defined in section 8.1.
So, when you set a top offset, the top margin is taken into account, and when you set a left offset, the left margin is taken into account.
If you had set the bottom offset instead of the top, you'll see that the bottom margin takes effect. If you then try to set a top margin, the top margin will no longer have any effect.
If you set both the top and bottom offsets, and both top and bottom margins, and a height, then the values become over-constrained and the bottom offset has no effect (and in turn neither does the bottom margin).
If you're looking to understand why the spec defines offsets this way, rather than why browsers behave this way, then it's primarily opinion-based, because all you'll get is conjecture. That said, Fabio's explanation is quite reasonable.
Because an absolutely positioned box is removed from the normal flow and is assigned a position with respect to the containing block. If you don't define a containing block, then it's body.
So, with that in mind, think of the containing block as a coordinates axis that starts at top left. If you give your element this properties:
position: absolute;
top:100px;
left:100px;
just like you did, you will have leave an empty space above and left, thus, if you apply margin-top or margin-left, it will work, because your elements are capable to virtually go through every pixel of both axises up to that 100px top and 100px left position, and same applies for negative margins. However, since position:absolute removes the element from the flow and any impact on any subsequent sibling element, it's easy to see that nothing can happen after the element "finishes", hence margin-bottom and margin-right won't work since they don't have anything to get margin from.
I have made an image to show the behavior since my explanation might be a bit obscure
Your margin bottom is not working since you put the top property in your divs. Remove top and your margin bottom will work for your #box1.
Margin-bottom affect too. See the code below, if you set a bottom reference in #box1 it will apply 20px in margin-bottom.
http://jsfiddle.net/t5ooot7u/
#box1 {
width:200px;
height: 100px;
background-color:gold;
position: absolute;
bottom:230px;
left:100px;
margin-bottom:20px;
}
To me specifying both bottom and margin-bottom seems like a contradiction. Because both are means to specify indent between the element and surrounding elements/containers. That is, bottom should be measured from the border, otherwise it's indent measured from indent. Does anyone know what the specification has to say?
bottom property "specifies how far a box's bottom margin edge is offset above the bottom of the box's containing block"1. And
The margin edge surrounds the box margin. If the margin has 0 width, the margin edge is the same as the border edge. The four margin edges define the box's margin box."2
So yes, specification says that bottom is measured from margin edge.
So I asked this question: google chrome issue with fixed position and margin-top which finally got me to realize that top and margin-top are not the same thing. I don't know how I've missed that all these years.
Anyways that got me thinking what is the difference exactly between margin-top and top, which is how I found this question: CSS: Top vs Margin-top.
I already knew what margin-top did. But I had never extrapolated that out to think "hmm, this element is not in the DOM flow so what exactly is margin-top pushing it away from?"
From the question I asked I know that margin-top behaves in very unexpected ways when applied to an element with a fixed position. And that in Chrome at least this can lead to some crazy rules (like margin-top: -273%;).
So my Question is: How do browsers apply margin rules to elements not in the DOM flow (i.e. elements with a position value of fixed or absolute . And what about the way they are applied and rendered leads to rules, like the one described above, actually rendering the element inside the view-port?
The top property simply determines how far from the top of the containing element that the box-model should start being rendered. In the case of position: fixed, that is the window itself. In the case of position: absolute, it is the next parent element with a non-static position.
Margin, on the other hand, is part of the box-model itself. Adding margin to the top of the box increases the empty space present above the box.
Consider the following layers for a position: fixed box:
top:10px
margin-top:10px
------------border-top:1px------------
padding-top:10px
content
All of the margin, border, and padding are part of the box model. That entire element, or "piece", is just one big square when positioning. So, if you have a margin of 10px on the top of the box, and position the element 10px from the top, it will have the appearance of having 20px of margin between the top of the window and where the visible box starts.
I've also made a very simple example in jsFiddle.
If you like graphics, take this example, where the red box has a position: fixed:
As you can see in the first section, only setting position: fixed on the element doesn't actually move it anywhere. It just removes it from the flow of the document.
In the section section, adding a margin-top: 10px makes the element move down 10px because the box now has 10px of margin on the top of it. However, it hasn't actually moved anywhere. The box has just gotten taller because the box model has changed.
In the third section, using a top: 10px actually moves the box to be 10px from the top of the window container. It has the exact same box model as in the first section.
Section four is like the second section above it, except the negative margin causes it to move up ten pixels. The box model is still taller and the box still hasn't moved.
When you set an absolute position on an element, the element doesn't move at all if you don't set any other position properties. So, without a top, right, bottom, or left property set, the element stays in the position it would have been in if it had been rendered as part of the flow, it's just now removed from the flow. So adding a margin, either positive or negative, makes it appear to move up or down from that position. In reality, you're just changing the element's box model though.
You also have to realize that using a percentage on top and bottom margins (and even paddings) has nothing to do with the height. It actually uses the width to figure out how much margin is there. Saying margin-top: 10% will make that value 10% of the available width, not the available height, and making it negative will just negate that value. I mentioned this because it is relevant to that first question you linked where you were using percentages for margin-top.
I hope this covered what you were looking for. I couldn't tell what exactly you were confused about so I just explained as much as I could.
I have this html and CSS:
<div style="background-color:Red; width:200px; height:200px;">
<div style="background-color:Blue; width:50px; height:50px; float:right;">aa</div>
<div style="background-color:Green; width:50px; height:50px;">aa</div>
I thought it would place the blue box after the green one (flow layout) but its moved it right over to the edge of the red container, which is really wierd..Any ideas why it doesnt flow?
'float' means 'move to that side and allow anything following to appear on the opposite side'
Since you are floating blue right, it appears on the far right hand side of its container.
Since there is room next to Blue and Blue is floating, Green appears next to Blue. Green appears at the left hand side because it has nothing to alter its horizontal position from the default (such as margins, or touching Green).
Because that is what float: right does.
According to the specification:
A floated box is shifted to the left
or right until its outer edge touches
the containing block edge or the outer
edge of another float.
Because float moves the element as far as possible to the right and to the top.
Here are the precise rules that govern the behavior of floats (from W3):
The left outer edge of a left-floating box may not be to the left of the left edge of its containing block. An analogous rule holds for right-floating elements.
If the current box is left-floating, and there are any left-floating boxes generated by elements earlier in the source document, then for each such earlier box, either the left outer edge of the current box must be to the right of the right outer edge of the earlier box, or its top must be lower than the bottom of the earlier box. Analogous rules hold for right-floating boxes.
The right outer edge of a left-floating box may not be to the right of the left outer edge of any right-floating box that is next to it. Analogous rules hold for right-floating elements.
A floating box's outer top may not be higher than the top of its containing block. When the float occurs between two collapsing margins, the float is positioned as if it had an otherwise empty anonymous block parent taking part in the flow. The position of such a parent is defined by the rules in the section on margin collapsing.
The outer top of a floating box may not be higher than the outer top of any block or floated box generated by an element earlier in the source document.
The outer top of an element's floating box may not be higher than the top of any line-box containing a box generated by an element earlier in the source document.
A left-floating box that has another left-floating box to its left may not have its right outer edge to the right of its containing block's right edge. (Loosely: a left float may not stick out at the right edge, unless it is already as far to the left as possible.) An analogous rule holds for right-floating elements.
A floating box must be placed as high as possible.
A left-floating box must be put as far to the left as possible, a right-floating box as far to the right as possible. A higher position is preferred over one that is further to the left/right.
As you can see, floated boxes tend to go to the top. If you were to float other boxes, then the order would matter. If only one floats, it shoves all the rest around.
Float moves an item to the far left or right of the parent element.
Why not place it after the green div, and apply float: left to both?
What is the difference between using top and left properties and top and left margins?
I know top and left are usually used in position:absolute situation but I'm still wondering if there is any major difference.
ex:
position:absolute;
top:5px;
left:5px;
-vs-
margin-top:5px;
margin-left:5px;
Well, the main difference is that absolutely positioned elements are pulled out of the content flow.
But also with relatively positioned elements, the surrounding content may become obfuscated.
Margins on the other hand are added to the element's size while the surrounding content flows accordingly.
See this sample fiddle with some differences.
Surely there are situations where both deliver the same results, but under normal conditions, these two aproaches aren't simply exchangeable nor comparable.
A There's a semantic difference. Box offsets like top specify how far a box's margin edge (dotted edges in the image below) is offset from a reference edge (For absolutely positioned elements, that's the top edge of the box's containing block). Margin properties like margin-top specify the width of the margin area of a box (The distance TM between the dotted edge and and solid edge in the image below).
B top and left apply only to positioned elements (elements with position set to anything other than static) while margin-top and margin-left apply to all elements except elements with table display types other than table-caption, table and inline-table.
Margin describes the space between your box and adjacent boxes. Boxes that are positioned relatively (i.e. that are part of the normal flow) will keep the sufficient space between them that each one's "margin" requirements are met (called "margin collapsing").
top and left on the other hand are positional attributes that specify where your box is located; for absolutely positioned boxes the values are taken relative to the nearest containing box which is itself absolutely positioned. The top/left/bottom/right attributes specify the location of the respective edge of your box including its margin.
In short, the two are entirely different concepts. For normally flowed boxes you should use margin to control the spacing between neighbouring boxes.