why does div collapse with relative/absolute positioning? - css

I've dealt with divs collapsing on their content when using float positioning (e.g. solving with overflow:hidden), but am trying to learn absolute/relative positioning and can't figure out why the container div is collapsing. My test case:
<html>
<head>
<style type="text/css">
body {
background-color:#eee;
}
#content {
margin:0 auto;
position:relative;
border:1px solid red;
width:800px;
display:block;
background-color:white;
}
#header {
border:1px solid black;
background-color:#777;
color:white;
width:800px;
position:absolute;
left:0;
top:0;
}
#leftcol {
position:absolute;
border:1px solid black;
background-color:#ddd;
width:200px;
top:100px;
left:0;
}
#rightcol {
position:absolute;
top:100px;
left:205px;
border:1px solid black;
background-color:#ddd;
width:500px;
}
</style>
<title>CSS Positioning Example 1</title>
</head>
<body>
<div id="content">
<div id="header">
<h1>The Awesome Website</h1>
</div>
<div id="leftcol">
<h2>About</h2>
<p>
This website is so awesome because it was made by someone
and that is really all there is to it. There.
</p>
</div>
<div id="rightcol">
<p>This is where I'm going to put some real body text so that it goes
on and on for a while and so I can get a sense of what happens when
the text in the paragraph keeps going and the box containing it keeps
going on as well.
</p>
</div>
</div>
</body>
</html>
What's going on here? Why does the red-bordered content div collapse even though it contains the other divs?

It is because all of its content is styled as position:absolute. This takes those elements out of flow and (layout-wise) it's like they don't even exist. Consider using position:relative to position the content.

You really need to read these articles at A List Apart
CSS Positioning 101
CSS Floats 101
Your question is why the div with red borders don't expand to it's content. As Joseph said the problem is that you take the elements out of the document flow. Positioning an element absolutely make the element's position independent from it's parent and siblings.
I fixed your code using CSS float property. Take a look here.
I highly recommend you read those articles.

Related

Min-width on a Centered <div> CSS and HTML

I am attempting to write a simple 404 (Page not Found) error page for my website: bazingamanphdgaming.t15.org. This is my code so far:
<html>
<head>
<title>404 - Not found</title>
<style>
#title {
position:fixed;
top:40%;
color:white;
font-size:40px;
text-align:center;
width:100%
}
#link {
position:fixed;
top:45%;
font-size:20px;
text-align:center;
width:100%
}
</style>
</head>
<body style="background-color:black">
<div id="title"><b>404 - Page not found</b></div>
<div id="link"><br />
<a style="color:white" href="http://bazingamanphdgaming.t15.org">
Return to the BazingaManPHD Gaming home page.
</a>
</div>
</body>
</html>
However when I reduce the browser window's width the bold text in the #title goes over the link going back to the homepage. This is a screenshot:
Of course to fix this problem I would need to put a min-width property on the #title like so:
<div id="title" style="min-width:200px"><b>404 - Page not found</b></div>
I am using 200px as an example there, but it doesn't seen to work, whatever size I put it as. Any help would be appreciated.
Simply add this to your CSS:
#title {
white-space: nowrap;
/* rest of your styles */
}
This will prevent the text in #title from wrapping.
You could enable vertical align by setting display:table and display:table-cell to the containers.
html,body{
width:100%;
height:100%;
}
body{display:table}
.page {
background:black;
display:table-cell;
vertical-align:middle;
text-align:center;
width:100%;
height:100%;
}
.title {
color:white;
font-size:40px;
}
.link {
font-size:20px;
color:white;
}
<div class="page">
<div class="title">404 - Page not found</div>
<a class="link" href="http://bazingamanphdgaming.t15.org">Return to the BazingaManPHD Gaming home page.</a>
</div>
This way it will center whatever you put into it.
Demo at http://jsfiddle.net/gaby/f6c1wupL/1/
here is a fiddle to take a look.
Basically there were a couple problems in your css.
Setting the position of elements to fixed takes them out of the natural flow.
If your thinking about the page as a piece of paper these fixed elements are floating above the paper wherever you place them.
By putting them relative you are putting them onto the piece of paper so the position of other elements can have an effect on their position. i.e bumping them out of the way.
by marking them relative the 'top' selector no longer works instead to move the items down the page give them a margin-top to offset them from the the bounds of the body(it's parent element).
#title {
position:relative;
margin-top:40%;
color:white;
font-size:40px;
text-align:center;
width:100%;
http://jsfiddle.net/crnc6ht5/

Header-footer-content layout with inline-block div taking remaining space (no float or overflow: hidden)

I have a (relatively) simple layout, with fixed header and footer divs. The content div is split in two "full height" divs with display: inline-block;. The left div is used for navigation and the right one for the actual content and has overflow-y: scroll;. The problem is that I cannot set the width of the right div to fill the remaining space. I have tried using float (as a last resort) but the right div was pushed downwards and, honestly, I'd prefer not to use floats.
Is filling the remaining width possible in my scenario? I would very much like to not hardcode the width of the right div.
Here's the JSFiddle example.
Simple HTML structure:
<html>
<head></head>
<body
<div id="container">
<div id="header">This is the header area.</div>
<div id="content">
<div id="leftContent"> </div>
<div id="textContent">
<p>Hello world (and other content)</p>
</div>
</div>
<div id="footer">This is the footer area.</div>
</div>
</body>
</html>
CSS excerpt:
html, body { margin:0; padding:0; height:100%; }
#container { position:relative; margin:0 auto; width:750px; overflow:hidden;
height:auto !important; height:100%; min-height:100%; }
#header { border-bottom:1px solid black; height:30px; }
#content { position:absolute; top:31px; bottom:30px; overflow-y:none; width:100%; }
#leftContent { display:inline-block; height:100%; width:200px;
border-right:1px solid black; vertical-align:top; }
#textContent { display:inline-block; height:100%; vertical-align:top; overflow-y:scroll;
width:540px; /*would like to not have it hardcoded*/ }
#footer { position:absolute; width:100%; bottom:0; height:30px; }
Edit:
Thanks to Prasanth's answer, I was able to achieve what I wanted. The solution was to set
display:flex; flex-direction:row; on the #content div and
width: 100%; on the #textContent div.
Testing on IE 11 (and downwards in compatibility mode) did not produce unwanted results.* The new version can be found here.
*Edit: This method works properly in IE11. In IE10, the scrollbars do not appear if the content of the #content div requires scrolling. The layout works thought. In IE <10 it does not work at all.
You can use Flexbox to achieve this
Go through this and you will get what you need
.content{ display:flex } .content > div { flex: 1 auto; }
and beware of browser support

Making two floating divs match height

I know this has been asked somewhere else, but I can't find the solution. I have a simple layout. A container Div with two floating divs inside. The left div holds the navigation and has a background image. The right div has a solid background and is dynamic based on the content of each page. I am not having issues with the content div. My problem is I want the left div to "stretch" vertically to match the height of the content div. What is happening is the left is only stretching to the min-height value. Here is my CSS:
#containerTemp {
margin-left:auto;
margin-right:auto;
width:1000px;
min-height:100px;
height:auto;
}
#containerNavigation {
width:210px;
float:left;
background-image:url(../images/template/linkbgd.gif);
background-repeat:repeat-y;
min-height:500px;
height:100%;
}
#containerContent {
width:790px;
background:#FFFFFF;
background-repeat:repeat-y;
float:right;
min-height:500px;
height:100%;
}
You can see the issue by visiting this page: http://www.athensfireandrescue.org/?pid=7
I am sure it's something simple, but I can't put my finger on it. Sorry for the redundant question, but my searches just didnt' turn up viable solutions.
Heights can be a bit tricky. However the goal is to make sure the parent containers have 100% height.You have a lot of stuff going on in your web page. So I created an isolated demo to demonstrate how this works.
HTML
<div class="wrapper">
<div class="left"></div>
<div class="right"></div>
</div>
CSS
html, body {height:100%;}
.wrapper {
width:400px;
height:100%;
margin:0 auto;
}
.left {
width:198px;
border:1px solid black;
float:left;
height:100%;
}
.right {
width:198px;
border:1px solid red;
float:left;
height:100%;
}
DEMO:
http://jsfiddle.net/nFdtT/
SOME OTHER STUFF I NOTICED:
If I can offer some advice I would suggest the following:
Don't use tables unless it is tabular data. Your NAV should be constructed using a list.
Remove all inline styles and place them in a separate stylesheet.
<meta> and <style> tags should be in the <head> of your document. (For some reason you have a partial doctype heading nested inside of your <head>)
And if you aren't already, I would suggest using a CSS reset.

How to create equal height columns in pure CSS [duplicate]

This question already has answers here:
CSS - Equal Height Columns?
(11 answers)
Closed 7 years ago.
How to get your div to reach all the way down?
How to fill up the vertical space of parent div?
How to get equal length columns without using background images?
I spent a couple days googling and dissecting code to understand how to accomplish equal length columns as easy and efficient as possible. This is the answer I came up with and I wanted to share this knowledge with the community copy and paste style in a little tutorial.
For those that think this is a duplicate, it is not. I was inspired by several websites, among them http://matthewjamestaylor.com/blog/equal-height-columns-cross-browser-css-no-hacks but the code below is unique.
For a simpler solution, you can give the parent display: table and its children display: table-cell, like this:
.parent {
display: table;
}
.child {
display: table-cell;
}
See DEMO.
Please note that this does not work in IE7, so if IE7 support is required, a more elaborate solution would be needed.
One of the tricky things in modern web design is to create a two (or more) column layout where all the columns are of equal height. I set out on a quest to find a way to do this in pure CSS.
You can easiest accomplish this by using a background image in a wrap-div that holds both of your columns (or the background of the page).
You can also do this by using CSS table cells, but unfortunately the browser support for this is still shady, so it's not a preferred solution. Read on, there is a better way.
I found my inspiration from two pages on the web, although I prefer my solution, since it gives me more freedom to use rounded corners and precise widths or percent layouts, and it is easier to edit, your final layout holding div is not forcing you to do negative number crunching.
== The trick: ==
First you create the background design cols, then you put a full width div that can hold your regular content. The trick is all about floated columns within columns, creating a push effect on all parent columns when the content extends in length, no matter what end column is the longest.
In this example I will use a 2 column grid in a centered wrap-div with rounded corners. I have tried to keep the fluff out for easy copy-paste.
== Step 1 ==
Create your basic web page.
<!DOCTYPE HTML>
<html>
<head>
</head>
<body>
</body>
</html>
== Step 2 ==
Create one floated div inside another floated div. Then apply a negative margin on the inside div to pop it out of its frame visually. I added dotted borders for illustrating purposes. Know that if you float the outside div to the left and give the inside div a negative margin to the left, the inside div will go under the page edge without giving you a scroll bar.
<!DOCTYPE HTML>
<html>
<head>
<style>
#rightsideBG{
float:right;
background:silver;
width:300px;
border: 3px dotted silver; /*temporary css*/
}
#leftsideBG{
float:left;
background:gold;
width:100px;
margin-left:-100px;
border: 3px dotted gold; /*temporary css*/
}
</style>
</head>
<body>
<div id="rightsideBG">
<div id="leftsideBG">
this content obviously only fits the left column for now.
</div>
</div>
</body>
</html>
== Step 3 ==
In the inside div: Create a div without background that has the with of all the columns combined. It will push over the edge of the inside div. I added a dotted border for illustrating purposes.This will be the canvas for your content.
<!DOCTYPE HTML>
<html>
<head>
<style>
#rightsideBG{
float:right;
background:silver;
width:300px;
border: 3px dotted silver; /*temporary css*/
}
#leftsideBG{
float:left;
background:gold;
width:100px;
margin-left:-100px;
border: 3px dotted gold; /*temporary css*/
}
#overbothsides{
float:left;
width:400px;
border: 3px dotted black; /*temporary css*/
}
</style>
</head>
<body>
<div id="rightsideBG">
<div id="leftsideBG">
<div id="overbothsides">
this content spans over both columns now.
</div>
</div>
</div>
</body>
</html>
== Step 4 ==
Add your content. In this example I place two divs that are positioned over the layout. I also took away the dotted borders. Presto, that's it. You can use this code if you like.
<!DOCTYPE HTML>
<html>
<head>
<style>
#rightsideBG{
float:right;
background:silver;
width:300px;
}
#leftsideBG{
float:left;
background:gold;
width:100px;
margin-left:-100px;
}
#overbothsides{
float:left;
width:400px;
}
#leftcol{
float:left;
width:80px;
padding: 10px;
}
#rightcol{
float:left;
width:280px;
padding: 10px;
}
</style>
</head>
<body>
<div id="rightsideBG">
<div id="leftsideBG">
<div id="overbothsides">
<div id="leftcol">left column content</div>
<div id="rightcol">right column content</div>
</div>
</div>
</div>
</body>
</html>
== Step 5 ==
To make it nicer you can centered the whole design in a wrap div and give it rounded corners. The rounded corners wont show in old IE unless you use a special fix for that.
<!DOCTYPE HTML>
<html>
<head>
<style>
#wrap{
position:relative;
width:500px;
margin:20px auto;
-webkit-border-bottom-right-radius: 20px;
-moz-border-radius-bottomright: 20px;
border-bottom-right-radius: 20px;
}
#rightsideBG{
float:right;
background:silver;
width:300px;
}
#leftsideBG{
float:left;
background:gold;
width:100px;
margin-left:-100px;
}
#overbothsides{
float:left;
width:400px;
}
#leftcol{
float:left;
width:80px;
padding: 10px;
}
#rightcol{
float:left;
width:280px;
padding: 10px;
}
</style>
</head>
<body>
<div id="wrap">
<div id="rightsideBG">
<div id="leftsideBG">
<div id="overbothsides">
<div id="leftcol">left column content</div>
<div id="rightcol">right column content</div>
</div>
</div>
</div>
</div>
</body>
</html>
== Inspiration sources ==
http://www.pmob.co.uk/pob/equal-columns.htm
http://matthewjamestaylor.com/blog/equal-height-columns-2-column.htm

css height standards mode

Hello and nice to meet you.
I would like to ask the following.
<body>
<div style="border:1px solid #ff0000">
<pre>dfssdgfdsgsd sdgsdg
sgdsdsgsdg</pre>
</div>
<div style="border:1px solid #ff0" id="secondDiv">
ggg
</div>
</body>
Is it possible to make #secondDiv to take 100%(in height) of the remaining vertical space?
I don't want to use min-height(doesn't work in ie) or javascript.
Complete html http://paste2.org/p/1177197
Thanks.
ps:I know that there exist a lot of related questions so i'm sorry in case of a duplicate.
If you can use fixed height for the top div then it is easy to work around the second div, by using absolute positioning.
CSS
html,body{
margin:0;
padding:0;
width:100%;
height:100%;
}
#head{
border:1px solid #ff0000;
height:50px;
}
#content{
position:absolute;
top:50px;
bottom:0;
width:100%;
border:1px solid #ff0;
}
HTML
<body>
<div id="head">
<pre>dfssdgfdsgsd sdgsdg
sgdsdsgsdg</pre>
</div>
<div id="content">
ggg
</div>
</body>
Demo: http://www.jsfiddle.net/RVTpT/
add #secondDiv { height:100%; } to your CSS.
I believe in order for this to work in IE you need to set
html, body { height:100%; }
as well

Resources