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

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

Related

making a div an inline element

I'm trying to play with positioning in css and I noticed something that confused me. It's probably a dumb question...but I'm having trouble understanding it.
I created three divs with the width and height of 50px with different background colors. When I position the third div up -60px using margin-top, the third div is on top of the second div. However, when I make the first and second divs inline elements, then both the first two divs are now on top of the third one.
Can someone please explain this concept to me?
<head>
<style>
<!-- Divs with the same width and height. Second one where both the first two divs are inline below this one. -->
#one{
background-color:red;
width:50px;
height:50px;
}
#two{background-color:blue;
width:50px;
height:50px;
}
#three{background-color:green;
width:50px;
height:50px;
margin-top:-60px;
}
</style>
</head>
<body>
<div id="one">
</div>
<div id="two">
</div>
<div id="three">
</div>
</body>
<head>
<style>
<!-- First two divs are inline -->
#one{
background-color:red;
width:50px;
height:50px;
}
#two{background-color:blue;
width:50px;
height:50px;
}
#one, #two{display:inline-block;}
#three{background-color:green;
width:50px;
height:50px;
margin-top:-60px;
}
</style>
</head>
<body>
<div id="one">
</div>
<div id="two">
</div>
<div id="three">
</div>
</body>
I think there are two issues going on here. One is that by leaving the third div display:block it will naturally wrap the first two divs. For a quick primer on blockvs inline-block see here.
The second part of this is that you have margin-top: -60px while having height: 50px. The negative margin is basically moving it higher up the page. This means the green box will apear 10px higher than the red one (-60 + 50 = -10).
Example Fiddle - I've added margin-left: -5px; and you can see the third div peeking out from under the first.

How do I hide the underlying text of a div without background color?

I'm trying to overlay two div elements, the underlying has a background the overlaying can not have one, since later there will be a background image in the back.
I want the underlying text to be cut off at the place where it is behind the overlaying div.
The only way I found was to set background-color: white; to the overlaying div, as mentioned this is not possible.
Any tip/solution how do I accomplish this?
<div style="background-color:red;z-index:1;overflow:hidden;position:absolute;left:262px;top:222px;width:191px;height:48px;">
This is a TEST text.
</div>
<div style="border:1px solid black;z-index:2;overflow:hidden;position:absolute;left:152px;top:177px;width:199px;height:156px;">
Top Element
</div>
Would this work for you? Basically, I've added a third div with the background color white that you can set it's display to none when the image goes into the lower div. This is mainly just a thought, it can probably be applied to the lower div instead.
<html>
<head>
<style>
#botDiv{
background-color:red;
z-index:1;
overflow:hidden;
position:absolute;
left:262px;
top:222px;
width:191px;
height:48px;
}
#topDiv{
border:1px solid black;
z-index:2;
overflow:hidden;
position:absolute;
left:152px;
top:177px;
width:199px;
height:156px;
}
#interSectingDiv{
background-color:#fff;
position:relative;
top:26px;
left:109px;
overflow:hidden;
width:191px;
height:48px;
display:block;
}
</style>
</head>
<body>
<div id="botDiv">
This is a TEST text.
</div>
<div id="topDiv">
Top Element
<div id="interSectingDiv"></div>
</div>
</body>
</html>
[ updated ]
Another thought, is that you can probably shorten the width of the lower div by the amount of space it consumes from the higher div and position it at the right edge of the higher div until the image goes in (you'll most likely have to use animation in your css that's triggered by some form of javascript).

Confusion about div — why is it not as wide as its contents, and how can I center it?

Please note: I am new to CS. Brand new.
I want my button div to be placed horizontally inside the confirm div: example.
Right now my dialog-button div width is equal to the width of the confirm Div. Why?
I am just placing two buttons inside my Div, so it's width should be equal to 128 (the total of two button witdh). Similarly the height should be equal to button height, but it isn't.
Second i want that mt button-div placed center horizontally . I tried left: 50% inside my button-div. But it is aligning the left margin with the centre of the confirm div. How can i do it?
EDIT
--------------------------------------------------
May be I didn't understand correctly, but if you want it inside then put it inside.
<div id="message">
Are you sure you want to
<div id="dialog-button">
<button>Ok</button>
<button>Cancel</button>
</div>
</div>
Demo
Update 1
Right now my dialog-button div width is equal to the width of the confirm Div. Why?
Why, because <div>s are block tag, they always take 100% width of the containing element. It is not equal to the width of confirm Div.
To make the dialog-button take the actual width use display: inline-block as its CSS. Demo
Update 2:
To the best from what i understood. This is what you want. If not help me help you.
Update 3:
Ok, here is a demo with the image. I will leave the without image part to you. ;)
The div which the two buttons are in is actually the width of the of the comfirm div. The reasons why divs stretch to the width of their parent, is because that is block level element.
the reason every thing seems so confusing is that you have a lot left floating divs in your example. These are changing how things would normally laid out. To make things simpler why dont you try removing some of the more confusing elements. I suggest trying a more simple example like the one below:
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="css/ie-css3.htc" type="text/css">
<link rel="stylesheet" href="css/messageDialogStyle.css" type="text/css">
<script type="text/javascript" src="js/jquery-1.7.1.js">
</script>
<script type="text/javascript" src="js/jquery-ui-1.8.17.custom.min.js">
</script>
<script type="text/javascript" src="js/puff.js"></script>
<script type="text/javascript" src="js/jquery.dialog.js"></script>
</head>
<body>
<div id="confirm">
<div id="message">
Are you sure you want to
</div>
<div id="dialog-button">
<button>Ok</button>
<button>Cancel</button>
</div>
</div>
</body>
</html>
If you want to center a button. If you change the margin-left and margin-right to auto you will center any block element. try changing your css to the css below:
#confirm {
background-color: #ddd;
display:block;
width:400px;
min-height:120px;
position:absolute;
border:1px solid #ccc;
border-radius: 15px;
-moz-border-radius: 15px; /*FireFox*/
-webkit-border-radius: 15px; /*Opera, safari*/
behavior: url(css/border-radius.htc); /*IE*/
}
#message {
width: 280px;
border:1px solid #ccc;
white-space: normal;
word-wrap: break-word;
margin:20px 0 0 0;
overflow: hidden;
}
#dialog-button {
border:1px solid #ccc;
position: relative;
}
button {
display:block;
margin-left:auto;
margin-right:auto;
width: 64px;
}
Note if you have to make the button a block element for the margin auto trick to work.
You can find more about block level element here.

why does div collapse with relative/absolute positioning?

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.

CSS Padding and width

Consider the next code:
#container {
width:500px;
}
#inside {
padding:10px;
width:100%;
}
If I choose width:100%; will it be the same as stating "width 480:px" (that is, calculating the padding already) or will it be as "width:500px"
Thanks
Joel
It will be like width:500px and adding the padding it will push the insides of overflow the #container..
But if #inside is a block element, then just giving the padding will make it behave as if it were width:480px
Example at http://www.jsfiddle.net/uA9LV/
It will be the same width as the parent container provided it's a block level element. So #inside will be 500px wide with 10px of padding on every side.
I put this in a sample document and the container div only resized 3 sides (left, top, and bottom).. and the inside div pushed it's boundaries outside of the container by 20px to the right.
I tested in IE8, Firefox 3.6.10, and the latest Chrome. Using various doctypes had no effect.
The code I used was:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Untitled</title>
<style>
#container {
width:500px;
border: solid 1px blue;
}
#inside {
padding:10px;
width:100%;
border: solid 1px red;
}
</style>
</head>
<body>
<div id="container">
<div id="inside">
Hello World!
</div>
</div>
</body>
</html>
Note: if you remove the Width declaration from the #inside div then you'll get exactly what you want. Which is an inner div that is 480px in width + 10px on each side for padding. See this link for more information on it: Solving the CSS Padding problem.

Resources