Is there CSS which can allow an element to follow flow, while a child has position:absolute? - html

Is there CSS which can allow an element to follow flow (similar to position:inline), while a child to the element has position:absolute?
EDIT: the answer is yes, just use inline and position absolute. I had a different issue than the one I posted. My apologies. My issue was that using margin:auto made the item centred, but gave all margins 0 rather than the maximum amount (ie. the container would spread as far as it could and the border would generally touch the border of the parent element). To solve the issue I'll be using an additional container and text-align.
Thanks to the people who helped and read this question.
Ignore the following historic portion of the post.
Obviously I want the position absolute to be positioned relative to
the bounds of it's parents (so the parent would not have
position:static).
Still I am unsure how to do this. Does CSS even have the expressive
power to do this?
Think of having a picture in the middle of a paragraph, but instead of
an image, it's a container with more elements inside.

Basically what you are looking for is position:relative;
Position relative retains the normal flow position but allows coordinate modifications. Using the css values top and left, for example will move the object relative to where it should normally be placed. If you nest the object inside a div, it will use the div's top left corner as the 0,0 coordinate origin.
Keep in mind that the position:relative property is applied to the elements inside your parent container and not the parent itself. You can use static or whatever you'd like for the parent. However, the parent won't necessarily resize to encapsulate its relatively positioned children visually, so you will have to set height and width values yourself.
<style type="text/css">
#my_button {
position:relative;
top:10px;
left:10px
}
#my_div {
height:25px;
background-color:yellow
}
</style>
<div id="my_div">
<input type="button" value="OK" id="my_button"></input>
</div>

Use position:relative; That way the parent stays in the same location but child elements with position: absolute are positioned relative to the parent not the body.

Related

Position:absolute without top/left/bottom/right values

I need to take an element out of the flow an am using position:absolute; for that.
Now if I just set position:absolute; without giving any top/bottom/left/right values or giving a relative position to the parent, the element sits right where I want it to be.
Here is a FIDDLE
html :
<div id="parent">
<div id="absolute">.. Absolute div ..</div>
</div>
CSS :
#parent{
width:50%;
margin:10% auto;
background:gold;
height:20%;
}
#absolute{
position:absolute;
background:lightgrey;
padding:2%;
}
Is there a reason not to do this?
Should I realy give the element top/left values and the parent a relative position and why?
If you want an element to remain in its static position (where it would normally be if it were not positioned) but simply take it out of normal flow, simply specifying position: absolute is perfectly acceptable. The behavior is as described in sections 10.3.7 and 10.6.4 of the spec, and every browser behaves correctly.
You aren't required to give it any offsets if you don't want to move the element from its usual static position, and you aren't required to relatively position its parent element if you're not going to move the element anywhere since it'll remain in its static position anyway.
I just looked at your code again and noticed that you're applying percentage padding to your absposed element. You will need to relatively position the parent element if you want the percentage padding to be calculated based on the width of this parent element and not the initial containing block (where the root element resides):
#parent{
position:relative;
width:50%;
margin:10% auto;
background:gold;
height:20%;
}
Compare this fiddle with the original.
So, the main purpose of relatively positioning some ancestor of an absolutely-positioned element is for designating its containing block. Sections 9 and 10 have most of the gory details on the interactions between elements and their containing blocks. Depending on your layout you may not need to position anything else at all, however if your layout is complex enough you may find that there are side-effects resulting from whether or not you position any container elements, and which one you do position. I suspect the topic of containing blocks could be covered in a different question since it may very well be out of scope of this one.
I would say: It depends on what you are doing with the parent element.
If you add content to the parent AND also position:absolute;top:0;left:0; to the child it want help cause the position of the parent is not set and so it remains static.
example with only added content here: fiddle child box moved down cause of content
example with position:relative; to parent and position:absolute;top:0;left:0; to child here:
fiddle
#parent{
position:relative;
width:50%;
margin:10% auto;
background:gold;
height:20%;
}
#absolute{
position:absolute;
background:lightgrey;
padding:2%;
left:0;top:0;
}
The thing is that if you don't specify position, it's default value is static which doesn't allow you to specify any offset such as left, top... but if you don't need to specify offset, as it is in your case, then it is completly valid. On the other hand, if you want to specify offset then you also need to set position to something else than static.
I have done a test suite about "position: absolute;".
---> look at this
In summary:
the left edge of the containing block of an element set 'position: absolute' without top, right, bottom or left is probably the right margin edge of its previous inline box (ignoring white space)
the top edge of the containing block of an element set 'position: absolute' without top, right, bottom or left is probably the top edge of the containing block of the line box in which the element lives
But I cannot find any relevant specifications in w3.

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.

Wrapper re-size

I have a wrapper surrounding a header with content inside as well as a container with content inside. The wrapper is really on there to keep everything positioned to each other accordingly within the confines I set, as well as to center everything. I have my container to automatically re-size according to the content that goes inside of it, this works without issue. However, the wrapper around the header and the container won't follow the same rule and ends up taking a height of 1px it seems. Please note: the code below will show the wrapper outlined by a dashed white border up at the top, it should instead wrap around everything it contains.
Here's the code to the website on jsFiddle.
Any help would be greatly appreciated. I feel as though I closed all of my floats, I don't see why the height: auto; on wrapper won't work, but maybe there's something I'm missing.
height: auto on #wrapper isn't working because virtually every element inside it has position: absolute.
What does position: absolute do? http://www.w3.org/TR/CSS21/visuren.html#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.
The choices to fix your problem:
Give #wrapper an explicit height - but that won't work if you don't know the height beforehand.
As #jeroen said: use JavaScript to set the height of #wrapper.
What you should really do is completely redo your CSS:
position: absolute is not how you should position every element on the page. You should use floats instead.
For a comparison of using position: absolute vs floats, see:
http://www.htmldog.com/guides/cssadvanced/layout/
You are using absolute positioning for the contents of the wrapper, #container and that takes it completely out of the document flow. The same applies to the contents of your header.
The only way to get your wrapper to wrap, is using javascript to calculate and set the height manually.

CSS: why some parent divs area didn't cover child div?

I am using firebug to debug, one useful feature of firebug is when I click the element in HTML, firebug will show highlight on the actual browser window so that I know which part is currently selected.
But I noticed, with some css, below code is interesting:
<div>
<div>
</div>
</div>
The parent divs highlight area didn't cover the child div's highlight area. In my opinion, the child divs area should be a subset of parent's, is it right? In which cases that that is not true?
There are some cases:
If the child uses position: relative; top: 200px and move away from the parent.
If the child does something similar using a negative margin. (similar to 1)
If the child is a float, and there is no clearing or some kind of clearfix, such as the newest method of making the parent overflow: auto, then the parent will not enclose the floated child.
It is mostly likely because the child divs are floated. In this case you need to use a clearfix hack, or add an additional div into the container like so:
<div style="clear: both"></div>
It depends upon the style being applied. Generally what you are saying holds good. But positioning of a child element can be made independent of the parent.
You may please show the css to get clear idea.
If the inner element is floating or positioned absolutely, it won't affect the size of the parent.
If the inner element is floating you can change the overflow setting of the outer element to make it contain the child. You can specify overflow:hidden; for the parent element, but no size, which has the side effect that it will be sized to contain it's children.

wrapper not containing content div

I'm trying to get my wrapper to hold my content but it won't. I've taken out the floats and added "overflow: visible" no no avail. I'm thinking it's because of my z-indexing and negative margins, but have tried taking these out and still no change. Any ideas?
http://www.jenniferhope.com/bio
(the float is still in this example.)
Thanks for any help you can offer!
Try this:
#wrapper {
overflow:auto;
}
I took a look at the code on your site. There are a number of things you will probably want to address. It will be difficult to say exactly what you need to do, since I don't know exactly how you want the site to look. But, in general, here are some pointers:
To contain floated elements, apply overflow:auto; to the parent element, or place something to clear the floats at the bottom of the container, such as: <div style="clear:both;"></div>
Try to avoid using negative margins for positioning. This is OK in a pinch, but usually there is a better way.
If you need to have one element layered over another, you will need to position the element using position:absolute; and a z-index. When using position:absolute; the element will be positioned relative to the nearest ancestor that has position:relative; applied. If no element has this applied, it will be positioned relative to the body element.