How can I avoid spaces after moving a relatively positioned element? - html

I have an<article> element inside a <div> and article has a position: relative;.
I moved it up 95px (bottom: 95px;) but the space it took up in its original place remained there. How can I make that disappear? When I do the same with article positioned as absolute, there is no problem. But I need to stick this to the middle too and margin: auto won't work with position:absolute.
http://jsfiddle.net/xnvMD/2/

I have an<article> element inside a <div> and article has a position: relative;.
I moved it up 95px (bottom: 95px;) but the space it took up in its original place remained there.
Well, this is how relative positioning is supposed to work – http://www.w3.org/TR/CSS21/visuren.html#choose-position:
“When a box B is relatively positioned, the position of the following box is calculated as though B were not offset.”
So the original space required by a relatively positioned element gets reserverd.
How can I make that disappear? When I do the same with article positioned as absolute, there is no problem. But I need to stick this to the middle too and margin: auto won't work with position:absolute.
Have you tried just using a negative margin-top to “move” the element upwards? This should work in all browsers (that are not from the stone age). And you can still set the horizontal margins to auto to have your element centered.
.trdown {
/* everything else besides position and bottom stays */
margin:-85px auto 0 auto;
}
(If this destroys the spacing at the bottom of the container element that you want to keep, then give that a padding-bottom as well.)

Instead of the relative position, use a negative top margin. Something like this:
margin:-95px auto 0 auto;
As CBroe has already pointed out, to get the arrow to show up over the image above, you'll need to add back the position:relative (but not the bottom) when you set the z-index.
position:relative;
z-index:1;
Technically you don't even need the z-index.
If you're curious why this works the way it does, you need to understand the rules for painting order in CSS. The full details are fairly complicated, but the basics are outlined in the section on the z-index property.
Within each stacking context, the following layers are painted in back-to-front order:
the background and borders of the element forming the stacking context.
the child stacking contexts with negative stack levels (most negative first).
the in-flow, non-inline-level, non-positioned descendants.
the non-positioned floats.
the in-flow, inline-level, non-positioned descendants, including inline tables and inline blocks.
the child stacking contexts with stack level 0 and the positioned descendants with stack level 0.
the child stacking contexts with positive stack levels (least positive first).
By default, images (which classify as inline-level, non-positioned descendants) are at level 5, which is above your article element (a non-inline-level descendant) at level 3.
By adding a postion:relative to the article element, you've made it a positioned descendant, level 6, and thus moved it higher up the stack and above the image again.
Note that if your article had contained any inline content of its own, that would have displayed above the img element (they're both inline, but the article's inline content comes later in the tree order), but the article background and borders would still have painted below.

I dont have enough reputation to add a comment without first adding an answer. Without seeing code like Cody added it's difficult to help.
I think you're not entirely sure how positioning works. When an element is set to position: absolute, it's then positioned in relation to the first parent element it has that doesn't have position: static. If there's no such element, the element with position: absolute gets positioned relative to <html> (from Codecademy)
If you give an element relative positioning and tell it to have a margin-top of 10px, it doesn't move down ten pixels from any particular thing—it moves down ten pixels from where it otherwise would have been.
Remember, that if your using margin-auto on an element inside of another element, it will center inside of that element, as opposed to the document. Div's by default are the entire width of the page though.

Related

If the child is position:absolute and the parent is overflow:hidden, why does the child overflow?

If the child is position:absolute, the parent is overflow:hidden, and the parent is position:static, the child still overflows:
<div style="overflow:hidden;height:100px;border:2px solid red;">
<div style="position:absolute;height:200px;width:200px;background:blue;opacity:0.5">
</div>
</div>
If the parent has a position other than static, the child no longer overflows:
<div style="overflow:hidden;height:100px;border:2px solid red;position:relative;">
<div style="position:absolute;height:200px;width:200px;background:blue;opacity:0.5">
</div>
</div>
Why does this occur? What is this behavior called?
I'm using Chrome, is this behavior consistent across browsers?
That's because the spec defines overflow as
This property specifies whether content of a block container element
is clipped when it overflows the element's box. It affects the
clipping of all of the element's content except any descendant
elements (and their respective content and descendants) whose
containing block is the viewport or an ancestor of the element.
The absolutely positioned element is a descendant whose containing block is established by an ancestor of the element with overflow: hidden, as explained in Definition of "containing block"
If the element has position: absolute, the containing block is
established by the nearest ancestor with a position of absolute,
relative or fixed
Therefore the absolutely positioned element is not affected by that overflow: hidden.
If the parent were positioned, it would be the containing block of the absolutely positioned element, and then overflow: hidden would affect it.
First of all, take a close look at the MDN Documentation CSS Position.
So how does this relate to your question? let's first analyze position: absolute:
absolute:
Do not leave space for the element. Instead, position it at a specified position relative to its closest positioned ancestor or to the containing block. Absolutely positioned boxes can have margins, they do not collapse with any other margins.
As far as your case goes, the positioned ancestor div element does not have any specified position attribute to it.
Therefore, it assumes the default position: static which literally specifies nothing other than the standard position of the element in the page. Check it out:
static:
This keyword lets the element use the normal behavior, that is it is laid out in its current position in the flow. The top, right, bottom, left and z-index properties do not apply.
In other words, the child will not be positioned relative to its parent. The weird behavior is because you expect the parent div to be positioned when is not positioned at all. It falls to ask: what is the nearest positioned parent then? The answer is to go up on the DOM tree and find it, logically since you have nothing in your example but your two div, the nearest parent will be webpage document itself.
So, how can you fix this? By adding (for example) position: relative to the parent div element.
EDIT: Overflow and Position properties:
By using overflow, you are typically trying to do one (or all) of the following: clip content, render a scroll bar, display any overflown content in a particular way. I gather your goal however is to have the child div not overflow the parent div. The question of how to avoid this overflow can take you to a place you do not want to go.
So by narrowing down what overflow is all about: (long story short) it is about controlling/modifying the look and feel of the content of what is inside a particular HTML element. Keep in mind, the content, not the element itself.
In your case, you may perceive the child element of your parent div as being the content of the parent div. Rather, what you actually see is the contents of the child element. The positioning of the parent and child with respect to each other is thus not controlled by the overflow property, but by the position property.
Is this consistent across browsers?:
Since CSS 2.1, the overflow (visible | hidden | scroll | auto) and position (static | relative | absolute) have been supported in all major browsers. Any discrepancies would occur when you extend on the overflow since certain of its attributes are not widely supported. See here for reference: Can I Use: Overflow (also scroll to the bottom for the CSS 2.1 reference).
Do you have any questions about this? Ask in the comments below.
overflow property is not inherited anyhow: http://www.w3schools.com/cssref/pr_pos_overflow.asp
So in your first case it is understandable it is not working, since with static position the browsers put it in the order it reads and overlooks collisions.
In your second case absolute positioning actually sets a space for the container div and then puts the second div into it - thus makes the overflow hidden.
You can imagine it this way: in your first case you created two divs which are not related to each other but positioned on each other in the second case you created a container and forced another div into it by setting the container's overflow to hidden.
Hope it helped easy understanding,
Andrew
The relative value for the position property is very similar to that of the static value. The primary difference is that the relative value accepts the box offset properties top, right, bottom, and left. These box offset properties allow the element to be precisely positioned, shifting the element from its default position in any direction

What does single `position: absolute` do to a <div> tag?

I've a simple, silly question. What does position: absolute do to a div tag?
Here's an example. Let's say I've three <div> tags:
<div id="a"></div>
<div id="b" style="position: absolute"></div>
<div id="c"></div>
From my experiments position: absolute somehow "pushes" #b outside of regular block element flow and it appears between #a and #c, with #a directly following #c and #b just floating there below or above them.
What exactly is happening?
As you've noticed, position: absolute completely removes the element from normal layout flow, leaving you free to position it wherever you want.
The position attribute controls the location based on which ever parent element has a position defined. Unless a value is set explicitly for an element on the page the first parent with position is the <body> element.
Once you set a position value for an element you can then place elements within it.
As a rule I always set the nearest parent to have position: relative which is essentially the normal position it would have. Then I can position elements within it.
position: absolute will place the element using co-ordinates based on the top, bottom, left and right attribute values.
When you add the position:absolute; property to block b, you basically ripped that div div out of the layout's flow. The absolute div (block b) ignores it's next neighboring element(s) in the layout and vice versa.
As you can see here: http://jsfiddle.net/AndrewL32/65sf2f66/12/ block C is positioned right after block A as though block B doesn't exist. In the same way, block B ignore block C and position itself next to A.
An element with position: absolute; is positioned relative to the nearest positioned ancestor (instead of positioned relative to the viewport, like fixed).
However; if an absolute positioned element has no positioned ancestors, it uses the document body, and moves along with page scrolling.
With CSS positioning, you can place an element exactly where you want it on your page.
When you are going to use CSS positioning, the first thing you need to do is use the CSS property position to tell the browser if you're going to use absolute or relative positioning.
Both Postion are having different features.In Css Once you set Position then you can able to use top,right,bottom,left attributes.
Absolute Position
An absolute position element is positioned relative to the first parent element that has a position other than static.
Relative Position
A relative positioned element is positioned relative to its normal position.
To position an element relatively, the property position is set as relative. The difference between absolute and relative positioning is how the position is being calculated.
According to Positioning schemes,
In CSS 2.1, a box may be laid out according to three positioning
schemes:
Normal flow.
Floats.
Absolute positioning.
Therefore, adding psotion: absolute to your element will make it positioned according to the absolute scheme, instead of the normal flow one.
According to The position property, position: absolute means this:
The box's position (and possibly size) is specified with the
top, right, bottom, and left properties.
These properties specify offsets with respect to the box's containing
block.
Absolutely positioned boxes are taken out of the normal flow. This
means they have no impact on the layout of later siblings.
Also, though absolutely positioned boxes have margins, they do
not collapse with any other margins.
Also, according to Absolute positioning,
In the absolute positioning model, a box is explicitly offset with
respect to its containing block. It is removed from the normal flow
entirely (it has no impact on later siblings).
An absolutely positioned box establishes a new containing block for
normal flow children and absolutely (but not fixed) positioned
descendants.
However, the contents of an absolutely positioned element do not flow
around any other boxes.
They may obscure the contents of another box (or be obscured
themselves), depending on the stack levels of the overlapping
boxes.
Absolutely positioning is related to display and float, as explained in Relationships between 'display', 'position', and 'float'. Basically,
An absolutely positioned box is not floated
An absolutely positioned box is blockified as follows: a display of inline-table becomes table; and inline, table-row-group, table-column, table-column-group, table-header-group, table-footer-group, table-row, table-cell, table-caption, inline-block become block
According to Layered presentation, absolutely positioned elements are painted in another layer:
Within each stacking context, the following layers are painted in
back-to-front order:
the background and borders of the element forming the stacking context.
the child stacking contexts with negative stack levels (most negative first).
the in-flow, non-inline-level, non-positioned descendants.
the non-positioned floats.
the in-flow, inline-level, non-positioned descendants, including inline tables and inline blocks.
the child stacking contexts with stack level 0 and the positioned descendants with stack level 0.
the child stacking contexts with positive stack levels (least positive first).
The position (and the size, if width or height are auto) of an absolutely positioned element is determined by its containing block and its top, right, bottom and left properties. If those are not specified, their value will be auto. The algorithms are explained in detail here and here. Basically:
The element will be placed at the same position it would have if it had position: static and float: none.
An auto width is calculated by shrink-to-fit: min(max(preferred minimum width, available width), preferred width).
An auto height is calculated as usual for block formatting context roots

Will the css properties 'left' or 'right' affect other elements on a webpage

The title is fairly self explanatory. Additional details to consider are...
The element i'm applying the css to will be position:relative
The element will be embedded onto a web page
I'm using left: -9999px to move the element off screen temporarily
The element may or may not move 'over' or 'through' other elements on the page.
Will doing this have any negative effects such as altering the layout/placement of other elements on the page?
Thanks
In most cases, offsetting a relatively-positioned element will not affect the layout of other elements in the same flow, because other elements will only respect the "original" position of the element (i.e. the position if it had not been offset). The offset properties only create a visual effect on the element being offset. From the spec:
Once a box has been laid out according to the normal flow or floated, it may be shifted relative to this position. This is called relative positioning. Offsetting a box (B1) in this way has no effect on the box (B2) that follows: B2 is given a position as if B1 were not offset and B2 is not re-positioned after B1's offset is applied. This implies that relative positioning may cause boxes to overlap.
However, the spec does point out an edge case (immediately after the above portion):
... However, if relative positioning causes an 'overflow:auto' or 'overflow:scroll' box to have overflow, the UA must allow the user to access this content (at its offset position), which, through the creation of scrollbars, may affect layout.
For example, scrollbars can reduce the width of a container and cause other elements to wrap where they otherwise would not.
No.
From MDN:
relative
This keyword lays out all elements as though the element were not positioned, and then adjust the element's position, without changing layout (and thus leaving a gap for the element where it would have been had it not been positioned). The effect of position:relative on table-*-group, table-row, table-column, table-cell, and table-caption elements is undefined.
As you can see in this Demo, the relatively positioned element simply overlaps other elements, without affecting the original layout - the other elements stays as it was previously (other than the fact that currently it's overlapped, obviously).

With no z-index, why does an early sibling covers up a later sibling in DOM?

I have a simple page with 3 DIV's: http://jsfiddle.net/AxX29/32/
With the HTML:
<div id="content1">foo</div>
<div id="overlay"></div>
<div id="content2">bar</div>
and CSS:
#overlay { width: 160px; height: 160px; background:yellow;
position: absolute; top:0; left: 0 }
I thought that when no element has any z-index defined, that means they are all auto (as shown by the JS in the jsfiddle), so that means the effective z-index is 0, and they would appear in the order of the DOM tree traversal (probably depth first search), meaning that overlay should cover up content1, while content2 should cover up overlay, but as it turns out, overlay covers up both content1 and content2, why is that?
(I know I can put a z-index of -1 to overlay and make it go below content1 and content2, but the question is, if no z-index is given, why does overlay cover up both content1 and content2?)
Giving an element position: absolute; removes it from the normal document flow and puts it on top of other elements.
You can add position: relative; to a parent div to make the absolute-positioned element positioned absolutely relative to the parent, rather than absolutely relative to the entire document.
EDIT: As you mentioned that you know already, applying z-index to positioned elements will change their depth behavior (the stacking context, as it's technically called); applying z-index: 100; position: absolute; to your first element, for example, would put it above the position: absolute; element.
From the CSS spec:
Within each stacking context, the following layers are painted in back-to-front order:
the background and borders of the element forming the stacking context.
the child stacking contexts with negative stack levels (most negative first).
the in-flow, non-inline-level, non-positioned descendants.
the non-positioned floats.
the in-flow, inline-level, non-positioned descendants, including inline tables and inline blocks.
the child stacking contexts with stack level 0 and the positioned descendants with stack level 0.
the child stacking contexts with positive stack levels (least positive first).
Here is my attempt at it, auto just means default.
The only thing to infer is that by choosing a position:relative/absolute/static etc. you are enabling an element to fall in to the domain of z-indexing. While it is effectively at position 0, it has more weight than a inline positioned element.
So index -1 places underneath the inline elements and index 0 or 1 does nothing.
I guess the answer is that auto/baseline is index 0, any elements with no position: (inline elements) live in plane 0 but have an inactive zindex. Any absolute element will overlay an inline positioned element zindexed or not.
Also worth noting is, if you absolutely position all three elements, they all overlay each other in the reverse order that they are in the DOM (last on top, first on bottom). which means the z-index weighting seems to favour the last element in the DOM.

CSS Positioning Margin Trouble

I am unsure how to position elements using css, as when I use methods like the following, whenever I resize the browser, the elements stay in the same place instead of where I would like them to be on the resized document. Please can you tell me what I am doing wrong?!
.logo {
left: 20px;
top: 20px;
position: absolute;
}
#header h1 {
margin-top: 20px;
margin-left: 500px;
color: rgb(127, 127, 126);
line-height: 0px;
}
Please, have a fiddle - http://jsfiddle.net/hHGRc/
Within the (X)HTML DOM, CSS recognizes four types of positioning. By default, every element in HTML is positioned Statically. This means that it is positioned according to the place that it appears in the normal flow.
Relative Positioning
When an object is positioned relative, it means that it modifies the position based on the origin, which is where it would have been positioned in the normal flow (static). Relative also does something else special, however, and tells the browser that all of its children will be positioned according to this element, whether using relative or absolute.
Absolute Positioning
When an object is positioned absolute, it is placed according to the position of its nearest non-static positioned ancestor. If there is not one, then it uses the <body> to determine its position. This has the potential to break document flow, if its siblings or ancestors are not positioned absolute. If all are positioned absolute from the outer most top node to current node, then it will maintain the flow.
Fixed Positioning
This takes the element out of the flow and positions the object according to the Window object. This means that no matter the scroll state of the document, its size or any other property, it will always appear in that location. (This is how you get objects that scroll with you).
Multiple solutions to your issue
First, as described by others, you may add position:relative to the #header. It will, like explained above, make your header the nearest non-static ancestor and will use it and the basis for determining position. This is probably not ideal for you because you are an admitted novice and this one absolute could easily break enough flow that you may struggle with sibling elements.
As an alternative, you may change the logo from position:absolute to position:relative. This will keep your logo in the flow, but move the logo according to where it appears naturally in your document flow. Chances are that unless you are using floats in your #header, this is probably the one you want, as it a) keeps flow, b) allows for use of child element floats without losing flow, c) achieves your ideal positioning, d) keeps inheritance from parent elements (when it is important).
Another choice is to change the #header to position:absolute. This may alter the way everything interacts, however, unless you change all of your parent and sibling elements to position:absolute. Additionally, you may lose access to ancestor defined widths and heights, as they are only inherited if they are in the same flow. This is the 2nd best situation for you as you can simply add the rule body * { position:absolute; } and all will remain in the flow with you. However, it neglects to really teach you the things you need to learn about positioning and will simply be a crutch.
Hope this helps,
FuzzicalLogic
Defining position: absolute in CSS takes the element in question out of the flow of the document.
Think of this as layers: the bottom most layer is the document (though not always, depending on z-index!), and the top most layer is your element which you have defined as absolutely positioned.
By setting position: absolute, you have told the browser that you will be responsible for positioning the element relative to the top left corner of the document (screen). Above, you have told the browser to position #logo 20px from the left and 20px from the top of the document. When you resize your browser viewport, that element will remain in that position.
I think what you want is to position your element within the document flow, without using absolute positioning. This can be achieved with a combination of floats, margins, and padding.
CSS positioning can be tricky to understand correctly, but once you do, you'll find it very useful.
Try this: http://www.barelyfitz.com/screencast/html-training/css/positioning/
Basically, to position anything that needs to be locked to a parent or a container element, the parent or container element itself needs to be positioned as well (absolute, or relative, doesn't matter) this is called positioning context. If an absolutely positioned element cannot find a parent or container that is positioning itself, it will then use the `body as the positioning context.
So in your example, if i were to to guess without seeing your HTML and more of your CSS,
adding position:relative to #header would then allow .logo to position itself absolutely from the top left of the #header element.
Also important to remember that absolute positioning takes the element out of the normal flow of the document.
I'm going with a wild guess and saying that your logo is inside the header division, but your header is positioned staticly. Therefore, your logo is not being positioned according to the header, but according to the document's window. So it will be going to a position that is 20px right and 20px down from the top left corner of the document in all instances.
Try setting position: relative on your #header element. This will keep the header in the same place as it would always appear, and the logo will use the header box to find it's left and top positions rather than the browser window.