Update:
The position value will change the width.
The JSFiddle: http://jsfiddle.net/caicai/mbtb5m7p/2/
Why does the width of div .a2 equal to its parent's width, while the the text in the div .a1 won't wrap?
The JSFiddle: http://jsfiddle.net/caicai/mbtb5m7p/
.r {
position: relative;
width: 100px;
height: 22px;
background: blue;
}
.a1 {
position: absolute;
top: 30px;
margin-right: -9999px;
background: green;
}
.a2 {
position: absolute;
top: 60px;
background: orange;
}
<div class="r">
<div class="a1">
Why does this line no wrap.
</div>
<div class="a2">
Why does this line wrap.
</div>
</div>
The div.r has a width of 100px and is placed relative.
The children .a1 and .a2 are placed absolute. The related on their (relatively placed) parent.
Without a negative margin, the children will take a maximum width equal to its parents size.
But, by adding a negative margin, you allow the children to "float over" its parents borders.
It's not that the content of .a1 is no longer wrapping, it is that the content of .a1 has no need to wrap because the available interior space has been made wide enough for the string inside it by your negative margin.
So your div.a1 will essentially be the width of .r + the value of the negative margin, which is dragging out the right extremity and increasing the size of your div.
That's pretty much how the box model works, check it out here or here
The margin is something that depends on it's parent element(class/id) here class r for classes a1 and a2.
1) Now you have width:100px for parent class(Class .r) so all child classes(class a1 & a2) inherits same width.
2) There is no issue for class a2, that class is totally normal as no unique(different) property than parent class(.r), so behaves properly.
3) Now the case for class .a1, which behaves properly too till it finds margin-right:negativeValue;.
So first understanding margin, Margin is the space between class/element block and it's parent class/element block. For Example margin-left:5px; so that particular block starts after leaving 5px from left, respectively for rest three sides(top, bottom, right)
Now negative margins, when used what it does is it trespasses their parent blocks boundary. That is it gets beyond the boundaries of their parents.
So here you specified margin-right:-9999px; so it gets beyond the boundary of class .r, still it might be giving you a thought that -9999px is a huge value, should throw the div beyond the screen, but as of limited text it only shows the area contained with text.
Inserting more text in class a1 it will surely go beyond screen scope, but text should be more than enough.
Graphical Explanation Updated
Related
My question relates to when you have one div floated (float:left) and a div right afterwards that is not floated. In that situation, why does the unfloated div cover and overlap the first div? It's like the first, floated div is taken out of the flow (like absolute positioning) in how the 2nd unfloated div goes over the 1st div.
I am aware that text in the 2nd unfloated div does not do this. It seems aware of the first div and floats next to it.
I am also aware that the fix is to have the 2nd div also floated to the left.
My question is a focus on the why. Why does the 2nd unfloated div (except for any text that might be in it) cover and overlap the 1st floated div?
In another similar question here on Stack Overflow, someone said "float removes an element from the normal flow, meaning that neighboring elements are positioned as if the float didn't exist...This isn't the case if an element has an inline display." So my question is why is a floated element removed from the normal flow (except for inline elements)? I understand why that is the case with inline elements (you want the text flushed to the floated div for word wrap around an image, for example). But why is it removed from the normal flow at all???
Here is some code to illustrate what I mean.
.box1 {
border: solid 3px;
width: 350px;
float: left;
height: 100px;
}
.box2 {
background-color: lightblue;
width: 400px;
height: 150px;
border: blue solid 3px;
}
<div>
<div class="box1"></div>
<div class="box2"></div>
</div>
It's like the first, floated div is taken out of the flow
Exactly, that's the reason. Floated elements are out-of-flow:
An element is called out of flow if it is floated, absolutely
positioned, or is the root element.
And that's necessary given the behavior of floats:
A float is a box that is shifted to the left or right on the current line.
If they were not removed from the normal flow, they would continue occupying some space in their initial position before being shifted.
Note inline floats are not an exception, because there is no such thing. Floats are blockified as explained in Relationships between 'display', 'position', and 'float'
Therefore, blocks following a float overlap it:
Since a float is not in the flow, non-positioned block boxes created
before and after the float box flow vertically as if the float did not
exist. However, the current and subsequent line boxes created next to
the float are shortened as necessary to make room for the margin box
of the float.
You can prevent this behavior by establishing a new block formatting context:
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.
.box1 {
border: solid 3px;
width: 350px;
float: left;
height: 100px;
}
.box2 {
background-color: lightblue;
width: 400px;
height: 150px;
border: blue solid 3px;
overflow: hidden; /* Establish BFC */
}
<div>
<div class="box1"></div>
<div class="box2"></div>
</div>
Consider the following HTML:
.top {
min-height: 150px;
}
p {
margin: 50px;
}
div {
background-color: #eee;
}
<div class="top">
<p>Welcome</p>
</div>
<div class="content">Main content</div>
You can see it in action here:
http://jsfiddle.net/Lp4tp/1
Question
In Chrome(for Ubuntu), it appears that the margin defined on the p tag causes spacing between the top div and it's surrounding elements, instead of expanding the top div and producing the equivalent of adding 50 pixels padding on the top div.
Is this correct behavior? And if so, how can I ensure that child elements inside the top div cannot create undesired space between the top div and the content div.
Note
If I use a fixed height instead of a minimum height, the spacing between the top and the content div vanishes, but the top still produces 50 pixels of white space above itself.
Your margins collapse. Fix with overflow:auto on the div:
div {
background-color: #eee;
overflow:auto;
}
jsFiddle example
Top and bottom margins of blocks are sometimes combined (collapsed)
into a single margin whose size is the largest of the margins combined
into it, a behavior known as margin collapsing.
You could also add a border to the div for the same result.
add to p
display:inline-block;
After a couple of waisted hours I've managed to find a solution to my problem, so the question is not "how to", but "why it works like that". Here's my stripped down example:
<div id="header">
<div id="header-element">header</div>
</div>
<div id="footer">footer</div>
CSS:
#header {
width: 100%;
position: relative;
padding-bottom: 5%;
}
#header-element {
position:absolute;
bottom: 0;
}
#footer {
position: relative;
margin-top: 5%;
}
And jsFiddle - http://jsfiddle.net/H7jwm/3/.
My problem was how to position those relatively positioned elements using percentage, first one some % off the top of the document, and the second one from the first one. I've accomplished that by giving padding-bottom to the first one, and margin-top to the second one, but I've got to the solution with a brute force - trying out every remotely logical solution. Now, if you remove the padding, margin-top of the second element becomes margin between that element and the top of the document, not the first element, and that first element "takes" rest of the space to the top.
The question is why that padding works like that? Or, to rephrase it, how does padding work with relative positioning?
Actually, you are mixing positions. Your #header has a height of zero. That's right, zero like in nothing, because it has no relative content. #header-element is absolutely positioned and because #header has a height of 0 it happens to be exactly in the padding-bottom space.
So, if you remove the padding-bottom from #header, the #footer moves up, starting right at the top of the document. Because of the margin-top, there's some space between the document top border and the word 'footer'.
But you still have that absolutely positioned #header-element, which will now be right in that margin-top space.
I have two elements inside a containing element. The container is 960px widt with 10px of padding on each side. I have two floated elements that are next to one another. The first element will contain text of an unknown amount and the other element will need to adjust to fill the rest of the containers width.
For example:
<div id="container">
<div id="item1">Unknown size</div><div id="item2">fill in width of left over</div>
</div>
edit---->
more information:
my first element will contain an unknown amount of text. The second element will contain none but will rather contain a background and be treated more like an accent to the text. Think of it like this:
START YOUR ENGINES! (followed by a pattern of tire marks)
CAUTION ON THE TURN! (followed by a pattern of tire marks)
These two items have different lengths for text so the tire marks would be different too. but I need the all to be on the same line.
You can float #item1 and not float #item2 like so:
http://jsfiddle.net/CevQH/1/
because of the float, #item1 will be ontop of #item2, it is removed from the regular document flow. As you can see in the jsfiddle, the text in item2 flows next to item1 while the background takes up the entire width.
If you place items underneath it, you should add a clear:left to the first item after #item2
If you can be sure that one column will always have the greater height you can leave that column unfloated and absolutely position the second column. The second column would hold to the container (which would need position: relative) by the top and bottom.
.container {
position: relative;
padding: 0 10px;
}
.left {
width: 200px;
}
.right {
position: absolute;
width: 100px;
right: 10px;
top: 0px;
bottom: 0px;
}
Fiddled here: http://jsfiddle.net/neilheinrich/5mRDM/
You can use flexbox.Chris explained very well here
<style type="text/css">
.a {
border: 1px solid #000;
position: relative;
}
.b {
background: #F93;
position: absolute;
top: 50px;
left: 50px;
}
</style>
<div class="a">
<div class="b">test</div>
</div>
a's height doesn't autoresize with it's content(beause b has flow), but how to resolve this problem, use css possible, not javascript.
If you are expecting to see your a-div resize, then I think you've misunderstood something. When you set an element to be absolute, you're taking it out of the "rendering flow", which means it won't interfere with any other elements on the page.
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.
You see the following documentation: Absolute positioning
When you have a Div with position:relative, you can control any absolute element inside. In fact, absolute Div is out of the flow of the normal document as Greg mentioned above. As I see you set left and top for b and then if you set width of a to 60px like this. Your <div class="b"> is outside the parent box. This is how absolute elements work.
Try "float: left;" in both classes. Didn't test, however. In wich browser are you testing?
if div b is positioned absolute it's not considered 'inside a' anymore, because it's not rendered inside of it.
so div a will not resize as div b gets larger or smalller...
By setting position: absolute you're taking the div outside the normal document flow, which is why the container won't resize to contain it.
Did you want to set margin-top: 50px; margin-left: 50px; instead?