I have a text box that will expand across the screen when I do not use position: absolute;, however upon using it, the text is all in one column per word, and the box is very tiny.
What is causing this? Or what can cause this? I've been trying overflow settings, different sort of positions and z-indexes, etc.
This is a good question because it highlights an important aspect of absolutely positioned elements.
If you don't specify the width of an absolutely positioned element, or if you don't specify the left and right offsets, then the width is computed to be a shrink-to-fit width similar to what is done for table cells.
The details are given in the CSS specification, Chapter 10: http://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-width
There are also some subtle consequences when you place an absolutely positioned element such that it triggers an overflow condition or when one of the edges if out of the view port. In these cases, a absolutely positioned block may have a computed width smaller than you specified.
The key is to consider what type and how much content the block will hold and provide a clear constraint for setting the width, either with a fixed value of a relative value.
Example
If you absolutely position the following:
<div class="abs ex3"><b>Small amount of text:</b> shrink-to-fit</div>
as shown in http://jsfiddle.net/audetwebdesign/SHxPR/, then the computed width of the block will be smaller than the width of the page. The block will expand in width and then height as needed to accommodate more text.
The element where you have position:absolute; is doing as it is expected to do. You should use position:relative; to the parent container for this absolutely positioned element.
Related
I want to have a region of my page that is reserved for context sensitive help text. It is blank, except when hovering over certain particular elements. But, of course, there are several independent pieces of text from which the visible selection might be chosen. This is in a page flow, with more stuff below it. I tried using a div "positioned", and putting help divs inside that. Each of the help divs is position: absolute; top: 0px; visibility: hidden; with the intention that JS would make one of them visible at a time, yet the space would have been reserved for the biggest piece of text in any of the help divs. Well, as most of you have guessed, because the help divs are position: absolute, their heights don't affect the height of the enclosing div, which ends up at a height of zero.
how can I achieve this? I don't want to use pixel sizing to force a height, because it's almost always wrong on some browser/font combination, and would be a bear to keep tweaking every time the help text were changed, or a new, longer help segment gets added to this.
Did I make sense, or do I need to try to draw pictures?
Yep, you're making sense. As you indicate correctly the containing element is collapsing to zero height since it doesn't contain any flow children with size. There is no simple solution to this without resorting to Javascript as obvious alternatives mean making all of them part of the flow layout, meaning the container would grow to accomodate all of the texts.
Solutions that would work:
Apply display:inline-block to all of the help texts to put them next to eachother, put them in a container element that has a width of 10000px or more as required, and encapsulate that element in a container with overflow:hidden. This way the container will actually assume the height of the largest child. Activating a text would then require moving the element in the DOM to the front so it is drawn first, or scrolling to bring it to the right position, which could be complex.
After loading the page use Javascript to measure the actual heights of the elements, set the largest one as the height of the container, and then apply display:none to the children instead of visibility:hidden.
The second option is easiest, and would be my preferred choice. It all depends a bit on your specific case though whether there's a better alternative.
I've set up a test here
http://jsfiddle.net/WZyF7/11/
Firefox seems to differ from Chrome and IE7-9 on how to calculate the width. Instead of giving the content as much width as it needs, it makes the div as wide it's widest child element. This stacks the elements vertically in FF, while horizontally in other browsers.
Is there any way to make all browsers handle this the same way without setting a width to the parent element or using JS? And does anyone have information on exactly how this is calculated across browsers? (width:auto; ? )
The relevant spec bit is http://www.w3.org/TR/CSS21/visuren.html#floats where it says:
The border box of a table, a block-level replaced element, or an element in the normal flow that establishes a new block formatting context (such as an element with 'overflow' other than 'visible') must not overlap the margin box of any floats in the same block formatting context as the element itself. If necessary, implementations should clear the said element by placing it below any preceding floats, but may place it adjacent to such floats if there is sufficient space. They may even make the border box of said element narrower than defined by section 10.3.3. CSS2 does not define when a UA may put said element next to the float or by how much said element may become narrower.
And the part in http://www.w3.org/TR/CSS21/visudet.html#float-width which says:
If 'width' is computed as 'auto', the used value is the "shrink-to-fit" width.
and following. Note that the actual computation of preferred width, which is what matters here, is not all that well defined. So basically, per spec behavior in this situation is undefined.
In any case, what's happening here is that Firefox is giving the overflow: hidden block the width it should have per section 10.3.3 and then clearing it past the float, while Chrome and IE seem to take the "they may even" path. And in particular, it's assuming it will do that when computing the preferred width of the parent.
All that said, I think the Firefox behavior is more correct in this particular narrow case: your "container" is 400px wide. The "parent" has 20px of horizontal padding. The "floated" is 300px wide. The "content" has 20px of horizontal padding. That leaves 60px of width for the text inside "content", but the longest word ("available...") is about 70px wide with my fonts. In Chrome, for example, the only way "content" fits next to the "floated" is because the right padding of the "content" disappears entirely. Firefox will do the same thing if you give a fixed width to the "parent" here.... but then you're forcing a width, instead of asking the browser to pick a reasonable one via the shrink-wrap algorithm, of course.
Your best bet here is to just give the "parent" a specific width if you want it to have that width, instead of relying on shrink-wrapping to produce a width that's actually too small for the content.
I have a strange problem....
Div should expand to 100% of available space by default, but its not the case.
I don't understand what's going on, even if I put display:block it's behaving as automatic width (relative to content).
I appreciate any help.
Thanks in advance.
http://jsfiddle.net/T3arP/
The effect I need to achieve is let the box with green border absoluted or fixed to top of its container, so you can scroll keywords but title will remain there.
When you absolutely position something (that's using position: absolute or position: fixed) width: auto no longer expands it to the container's width. The rules from which the width is actually determined are complicated*. That's why many people consider it a good practice to set a specific width on those elements (absolutely positioned ones, that is).
*you can find out about those rules at http://www.w3.org/TR/CSS2/visudet.html#abs-non-replaced-width)
As has been said, once you absolutely position an element, it loses the parent's tag association in a sense. So you could do something like this maybe.
http://jsfiddle.net/T3arP/1/
Given a dom element that has set height and width, and is set position:absolute, is there a predictable positioning for the element if it doesn't have any positioning specified (like top, right, bottom, and left properties)? Does the position default to left:0, top:0? Or does the element stay where it originally was positioned on the page?
Or does the positioning differ from browser to browser?
Here is an example using jsfiddle.
http://jsfiddle.net/hPJa8/
Most browsers seem to position the element in its natural position, but then subsequent elements will not take into account the absolutely positioned element when they are placed onto the page. This results in the subsequent elements overlapping.
The top left corner of the element stays where it would be if the position of the element was static. Unfortunately, it is not a strict definition.
Take an image as an example. Would we consider it as an inline or block element? (Most browser say inline). Should we consider line break caused by image? (Most browser act as if it's size is zero.) Where should we put it vertically? Choices are: at the the top of the line, at the baseline, at current font height, at image height; adding spans adds choices. The way IE answers this question changed recently AFAIK.
So, do expect differences from browser to browser.
I'm not sure if I fully understand the difference between these two.
Can someone explain why I would use one over the other and how they differ?
You'd use margin, if you wanted to move a (block) element away from other elements in the document flow. That means it'd push the following elements away / further down. Be aware that vertical margins of adjacent block elements collapse.
If you wanted the element to have no effect on the surrounding elements, you'd use positioning (abs., rel.) and the top, bottom, left and right settings.
With relative positioning, the element will still occupy its original space as when positioned statically. That's why nothing happens, if you just switch from static to relative position. From there, you may then shove it across the surrounding elements.
With absolute positioning, you completely remove the element from the (static) document flow, so it will free up the space it occupied. You may then position it freely - but relative to the next best non-statically positioned element wrapped around it. If there is none, it'll be anchored to the whole page.
top is for tweak an element with use of position property.
margin-top is for measuring the external distance to the element, in relation to the previous one.
Also, top behavior can differ depending on the type of position, absolute, relative or fixed.
Margin applies and extends / contracts the element's normal boundary but when you call top you are ignoring the element's regular position and floating it to a specific position.
Example:
html:
<div id="some_element">content</div>
css:
#some_element {margin-top: 50%}
Means the element will begin displaying html at the 50% height of its container (i.e. the div displaying the word "content" would be displayed at 50% height of its containing div or html node directly before div#some_element) but if you open your browser's inspector (f12 on Windows or cmd+alt+i on mac) and mouse over the element you will see it's boundaries highlighted and notice the element has been pushed down rather than re-positioned.
Top on the other hand:
#some_element {top: 50%}
Will actually reposition the element meaning it will still display at 50% of its container but it will reposition the element so its edge starts at 50% of its containing element. In other words, there will be a gap between the edges of the element and its container.
Cheers!
The top property is a position property. It is used with the position property, such as absolute or relative. margin-top is an element's own property.
from bytes:
"Margin is that space between the edge of an element's box and the edge of the complete box, such as the margin of a letter. 'top' displaces the element's margin edge from the containing blocks box, such as that same piece of paper inside a cardboard box, but it is not up against the edge of the container."
My understanding is that margin-top creates a margin on the element, and top sets the top edge of the element below the top edge of the containing element at the offset.
you can try it here:
http://w3schools.com/css/tryit.asp?filename=trycss_position_top
just replace top with margin-top to see the difference.
This is my understanding...
TOP: it defines the position of the element wrt its own elements or other element i.e in case of relative top refers to compare with its own element whereas in fixed top refers to compare with viewport.
Margin_Top: it always refer to its own elements that adds an offset(outside) to its border