Why my div is going outside of its parent div? - html

Div with id "message-box" is going outside its parent div "message-container"
I dont understand why?
I used "overflow:auto;" in my css for "message-box". but still its not giving me the desired result. margin left is not working properly when i use "overflow:auto" on "message-box".
Below is my HTML file:
<html>
<head>
<link rel="stylesheet" type="text/css" href="styles.css" >
<title>temp</title>
</head>
<body>
<div id="main">
<div id="header">header</div>
<div id="container">
<div id="user-container">user</div>
<div id="message-container">
<div id="message-box">message box</div>
<div id="text-box"> text box</div>
</div>
</div>
<div id="footer">footer</div>
</div>
</body>
</html>
Below is my CSS file:
#main{
border: 1px solid red;
margin: 5px;
}
#header{
border: 1px solid red;
height:30px;
margin: 10px;
}
#container{
margin:10px;
height:32em;
}
#footer{
border: 1px solid red;
height:30px;
margin: 10px;
}
#user-container{
border: 1px solid red;
float:left;
width:120px;
height:32em;
}
#message-container{
border: 1px solid red;
height:32em;
width:100%;
}
#message-box{
border: 1px solid grey;
overflow:auto;
margin:5px;
}
#text-box{
border:1px solid grey;
overflow:auto;
margin:5px;
}
please someone help me out here.

Quick answer
Your #message-box has correct margins all around in relation to the #message-container div, but the problem is that both #message-container and #message-box are overflowing into #user-container. Since #message-box has the overflow property, it is clipped at the exact edge where it overflows into #user-container. Since #message-container does not have overflow, it continues to flow behind the #user-container to the edge of the #container div. To fix this, add overflow to the #message-container.
#message-container {
height: 32em;
border: 1px solid red;
overflow: hidden;
}
I think what you want here is overflow: hidden to clip the overflowing content; overflow: auto adds scroll bars to see the overflowing content.
Explanation
The float on #user-container is causing the problem. Floats remove an element from the normal document 'flow' (see Normal Document Flow below).
I added background colors to #user-container(green) and #message-container(blue) so you can see what's happening. If you remove overflow from #text-box and #message-box, you'll see margins are actually working correctly between #message-box and #message-container. Add them back and you'll see how they get clipped by #user-container.
This is what's happening http://jsfiddle.net/fmceqbdp/2/
Normal Document Flow
The DOM has an element hierarchy. The document is the highest level parent (or outermost box), and any element you add is its child. The element's starting position is the upperleft of its parent. If you add another element at the same level (not nested), it is another child of the document and a sibling of the first element. The sibling also wants to be positioned as close as it can to the upperleft of the document, but it gets pushed right by the first element (inline) or to the next line (block). When you nest an element inside that element, the nested element is the child, it is contained inside the parent. It's starting position is the upperleft of its parent element. This is normal document flow. A floated element is removed from this normal flow, so it doesn't push other elements the way it normally would.
How Floats Behave
Divs are block elements, they push other elements away. However, when you float an element, it removes that element from the normal document flow -- that means its position is invisible to sibling elements (elements at the same level), so they're now positioned in front or behind the floated element as though the floated element doesn't exist. Because you floated #user-container, #message-container fills the entire #container as though #user-container is not there.
How Overflow Works
The element that has the overflow property will self-clear from overflowing into other elements. This is why #message-container flowed into the space occupied by #user-container but its children #message-box and #text-box with the overflow property had cleared themselves from flowing into the space #user-container. Their margins were still relative to their parent #message-container, not where they're clipped, which is why it appeared there was no left margin where they ran into #user-container.
For more details, see http://css-tricks.com/the-css-overflow-property/ -- scroll about 1/4 of the way down the page.

You need to add an overflow to #message-container because that's the div that's being pushed by the float not its children. #message-box and #text-box don't interact with their parents previous siblings.
So, remove all overflow: auto; and do this:
#message-container {
height: 32em;
border: 1px solid red;
overflow: hidden;
}
Here is a Fiddle:
http://jsfiddle.net/Ljqmjzkp/1/
PS: Cleaned the code so it's easier to read, also I indented it according to your DOM so you can see the structure. Keep that in mind, it helps ^^

Related

DIV as filling block in another DIV

I have a CSS
.nav {
width: 200px;
line-height: 50px;
float: left;
}
.content {
margin: 0px 0px 0px 230px;
}
.container {
border: 1px solid red;
}
And here is the HTML
<body>
<div class="container">
<div class="nav">Some text
<br>more text
<br>even more text
</div>
<div class="content">
<h1>Home</h1>
<p>Text paragraph</p>
</div>
</div>
</body>
This gives me menu on the left and the content on the right. And a red box around the content on the right, but only the half menu on the left.
But I would like to have the red box also around the complete nav-div Can anyone help?
Thanks
Teddy
Add overflow:auto to your container div's CSS:
.container {
border: 1px solid red;
overflow:auto;
}
jsFiddle example
Floating the child div removes it from the flow of the document and the container essentially collapses as if it didn't exist. Adding the overflow restores the behavior you're after.
I think this is a quick fix if you float your container it should solve the problem your having. See here http://jsfiddle.net/1540sscj/
.container {
border: 1px solid red;
float:left;
width:100%;
}
Floating an element removes it from the normal flow of the page with one side effect being that its parent's dimensions won't expand to fit it.
So, what you need to do is clear the floated item. The best way to do this, without using additional markup or using the overflow property, which may cause other issues, depending on your layout, is to use the :after pseudo class on the parent element, like so:
.nav{
width:200px;
line-height:50px;
float:left;
}
.content{
margin:0px 0px 0px 230px;
}
.container{
border:1px solid red;
}
.container::after{
clear:both;
content:"";
display:block;
height:0;
width:0;
}
<body>
<div class="container">
<div class="nav">Xalsdk fjaskldfj alskdfj asädf<br>asdf<br>asdf</div>
<div class="content">
<h1>Home</h1>
<p>Bla bla.</p>
</div>
</div>
</body>
More information on clear
More information on pseudo elements
Best way imho would be to add a div like:
<div style="clear:both;"></div>
Under your floating elements: FIDDLE
This way you don't need to use oveflow:hidden on your container that may give you problems once you have more stuff in your project.
Also you shoudn't use a margin-left for your content as the previous element is already floating left. The best practise if you want to add some margin between nav and content would be to make your content float left as well and then use margin left (the exact size you want) with respect of the nav and not with the left of the window.
Finally, if you don't want to add the clear:both div to the html you could add somethign like
.content:after {
content:'';
display:block;
clear: both;
}
it's a bit less browser (old ones) compatible but cleaner
You have to add overflow:auto to .container in your css
Check my js fiddle
Also the css that modified.
.container {
border: 1px solid red;
overflow:auto;
}
Description of property overflow from MDN
The overflow property specifies whether to clip content, render
scrollbars or just display content when it overflows its block level
container.

About css float left for div1, the appearance of div2?

This is the html code.
<div id="sidebar1">
sidebar1
</div>
<div id="sidebar2">
sidebar2
</div>
This is the css code for the html.
div {
width: 100px;
height:100px;
border-style: solid; border-width: 1px 1px 1px 1px;
}
div#sidebar1 {
float: left;
}
The presentation of it looks like below in my latest firefox.
Why was the text 'sidebar2' not hidden by the div1?
The original html looked like below.
In my opinion, due to the float left, the entire div2 will be overlapped by div1 including the text in div2 like below.
the below picture is the moment when I hover to the div2 in firebug. Obviously, the text 'siderbar2' seems depart from the div2. why?
To get the problem, you need to understand that the box is not the content.
From W3C wiki:
Each rendered line is enclosed in a separate line box.
You make #sidebar1 floating, so you put it out of the flow
Now, #sidebar2 box can take its place
But, #sidebar2's content (aka. first line box) is different from #sidebar2 box, and was pushed down by #sidebar1
To avoid this kind of behavior, you can add overflow: hidden on #sidebar2, or better: float: left.
Many people doesn't understand float and don't think it put the element out of the flow. The way we use it usually makes us to think it simply "puts elements next to each other". And when we face an "issue", we solve it without understanding it.
This property's name is float, not arrange.
If you want the two elements to display over each other. Change the positioning of the first one to absolute.
This will take it out of the ordinary flow rendering and allow any elements to overlap with it.
div {
width: 100px;
height:100px;
border-style: solid; border-width: 1px 1px 1px 1px;
position:absolute;
}
div#sidebar1 {
float: left;
}

long data extending the limit of div

I am having a problem keeping long data within a divs boundary.
Here is the demo for which I am facing the problem:
<html>
<head>
<style>
#main {
width: 500px;
margin:50px auto;
}
#data {
width:500px;
height:500px;
border: 1px solid #000000;
}
</style>
</head>
<body>
<div id="main">
<div id="data"> TestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTest
</div>
</div>
</body>
Here I make the div width 500px fix but still the data is extending the div boundary.
Is there any solution that when the data reaches to the max width the remaining data displayed in the next line?
You can use word-wrap:break-word; if you'd like the text to keep inside the div and appear on the next line.
jsFiddle here.
You can use:
word-wrap: break-word;
Word-wrap property specifies whether the current rendered line should
break if the content exceeds the boundary of the specified rendering
box for an element (this is similar in some ways to the ‘clip’ and
‘overflow’ properties in intent.) This property should only apply if
the element has a visual rendering, is an inline element with explicit
height/width, is absolutely positioned and/or is a block element.
This is a property introduced in CSS3 but it should work just fine for older browser.
Fiddle
#data
{
width:500px;
height:auto;
border: 1px solid #000000;
word-wrap:break-word;
overflow:auto;
}

Placing absolute box at the end of text (flexible by length of text)

I want to place an absolute popup box at the end of text link.
HTML
<div style="float:left;">Hello World</div><div class="box">BOX</div>
CSS
.box
{
float:left;
border-color:#000;
border-style:solid;
border-width:1px;
width:80px;
height:80px;
text-align:center;
}
http://jsfiddle.net/7N6ye/1/
It works fine only when a box is relative. When I set position:absolute on the box, it looks like
http://jsfiddle.net/7N6ye/3/
Any ideas? Eventually, I'll have a list of links each of which has different text length. (And each box will popup at the end of text).
This might work:
<div class="box">Hello World<div>BOX</div></div>
with the CSS:
.box {
position: relative;
border: 1px solid red;
float: left;
}
.box div
{
position:absolute;
top: 0;
left: 100%;
border-color:#000;
border-style:solid;
border-width:1px;
width:80px;
height:80px;
text-align:center;
display: inline-box;
}
Fiddle Reference: http://jsfiddle.net/audetwebdesign/DWe8B/
Notes
(1) I nested the popup box within the text line. I can work around that.
the problem is that the popup inherits the width of the parent, so the box
can be quite narrow unless you specify a width.
If you set the position to relative, the div is put relative to its original position.
e.g. 100px to the left from where you are
If you set the position to absolute, the div is put relative to its parent (the next parent with relative or absolute positioning).
e.g. 100px from the left corner of the parent
on top of that the div is no longer part of the document flow. So other elements can overlap with it.
The same is true for floating elements. Here the next available position is used.
In general it makes no sense to set absolute positioning as well as a float.

CSS alternative to center

People frown upon the center tag, but for me it always works just the way I want it. Nevertheless, center is deprecated so I'll make an effort.
Now I see many people suggest the cryptic CSS margin: 0 auto; but I can't even get it to work (see fiddle here). Other people will go modify position or display, but that always breaks something else.
How can I center a span using css so that it behaves exactly like the center tag?
<div class="container">
<span class='btn btn-primary'>Click me!</span>
</div>
Span is an inline element, and the margin: 0 auto for centering only works on non-inline elements that have a width that is less than 100%.
One option is to set an alignment on the container, though this probably isn't what you want for this situation:
div.container { text-align: center }
http://jsfiddle.net/MgcDU/1270/
The other option is to change the display property of the span:
/* needs some extra specificity here to avoid the display being overwritten */
span.btn.btn-primary {
display: table;
margin: 0 auto;
}
Using display: table eliminates the need to hard code a specific width. It will shrink or grow as appropriate for its content.
http://jsfiddle.net/MgcDU/1271/
You can set .container { text-align:center; } so that everything inside div.container will be centered.
In general, there are two ways centering things.
To center inline elements (such as text, spans and images) inside their parents, set text-align: center; on the parent.
To center a block level element (such as header, div or paragraph), it must first have a specified width (width: 50%; for example). Then set the left and right margins to auto. Your example of margin: 0 auto; says that the top and bottom margin should be 0 (this doesn't matter for centering) ad that the left and right margins should be auto - they should be equal to each other.
The <center> element is really just a block-level element with text-align:center;. If you sent border: solid red 1px; on it, you can see that it's 100% wide, and that everything inside it is centered. If you change text-align to left, then its children are no longer centered. Example: http://jsfiddle.net/KatieK/MgcDU/1275/. Perhaps you should just consider your <div class="container"> with text-align:center; } to be equivalent to <center>.
You make the span block level, give it a width so margin:auto works
see this fiddle
.center {
display:block;
margin:auto auto;
width:150px; //all rules upto here are important the rest are styling
border:1px solid black;
padding:5px;
text-align:center;
}
UPDATE: In order to NOT specify a width and have natural width of element on the span you will have to use textalign on parent
see this fiddle
.container{text-align:center}
.center {
border:1px solid black;
padding:5px;
}
<span> is an inline element. <div> is a block element. That's why it is not centering.
<div class="container" style='float:left; width:100%; text-align:center;'>
<span class='btn btn-primary'>Click me!</span>
</div>
You can center the content of span only when you convert it into block, using 'inline-block' style.
Your parent element needs to have a larger width in order to let a child element be positioned within it. After that the trick with margin: 0 auto; is getting the parent and child container position and display values to be compatible with each other.
.container {
border: 2px dashed;
width: 100%;}
.btn {
display: block;
margin: 0 auto;
width: 25%;
}
http://jsfiddle.net/rgY4D/2/