George Mauer
George Mauer

Reputation: 122172

How to use CSS to position divs?

I have html that looks roughly like this

<div>
  <div id="header"></div>
  <div id="chart"></div>
  <div id="legend"></div>
  <div id="info1"></div>
  <div id="info2"></div>
  <div id="info3"></div>
</div>

I would like to position the elements like this: positioning

How in the world do I go about doing this?

Edit: This is a question about "the right way to do it" and it is certainly not easily Google-able. Essentially what I want to do, rather than define columns in html, is to define a height for the container div, and then have the other divs position themselves naturally within it.

Upvotes: 0

Views: 863

Answers (12)

John Rudy
John Rudy

Reputation: 37858

Edit based on Question Edit

Seeing the HTML you have, my biggest suggestion is nesting some of the divs to get the control you want. While I'm not using your specific IDs in my sample below, the nesting should show you how to adapt what you have to where you want to be. (I hope!)

Original Answer

I'm going to have to make some assumptions about what you're trying to do in order to help you out. Lining up the bottoms will be the single hardest part, so I'm going to just go ahead and pretend it's not really the nice pretty square you've displayed. (I still can't do lining the bottoms without resorting to tables. Although I believe some of the frameworks, like those mentioned in Josh's answer, may be able to make that happen.)

So the assumptions I'm going to make, to keep life relatively simple, are thus:

  • You need to have an overarching header
  • You need a left column and a right column
  • The right column has three discrete elements in it
  • The left column has two discrete elements in it

Also to make life easier, I'm not going to break the stylesheets into their own CSS file; I'm going to assume that you know CSS and HTML already, and will be able to move them appropriately based on this basic HTML layout I'm about to throw out there.

So the basic layout would probably look something like such:

<html>
    <head><!-- blah blah blah --></head>
    <body>
        <!-- the overall container -->
        <div style="width: 500px; margin-left: auto; margin-right: auto;">

            <!-- the header -->
            <div style="width: 100%; height: 100px;">
                My headery goodness here
            </div>

            <!-- the left column -->
            <div style="float: left; width: 320px;">
                <div>
                    My charty goodness here
                </div>
                <div>
                    My legendary goodness here
                </div>
            </div>

            <!-- the right column -->
            <div style="float: left; width: 180px;">
                <div>
                    Info 1
                </div>
                <div>
                    Info 2
                </div>
                <div>
                    Info 3
                </div>
            </div>
        </div>
    </body>
</html>

You'll need to season the dimensions and add padding to taste, and if you do want the bottoms to line up, I recommend setting explicit height, min-height, max-height and overflow properties on all of the divs.

Finally, again, you really want to separate the CSS I've embedded here into appropriate ID or class selectors in a separate CSS file. This was just a rough hash-out to get you started on the layout; it's by no means a complete answer.

Upvotes: 2

Anax
Anax

Reputation: 9372

The following code will allow you to position your DIV without any additional HTML markup:

//* in order to view the results */
div#header, div#chart, div#legend,
div#info1, div#info2, div#info3
{ border: 1px solid black; }

/* IE requirement to center on screen */
body { text-align: center; }

/* define container size */
div
{
 width: 500px;
 margin: auto; 
 padding: 0;
 text-align: center;
}


/* for header, just define the size */
div#header
{
 width: 500px;
 height: 50px;
}

/* chart and legend are left floating
   and do not allow other elements to their left */
div#chart
{
 width: 248px;
 height: 250px;
 float: left;
 clear: left;
}
div#legend
{
 width: 248px;
 height: 202px;
 float: left;
 clear: left;
}

/* cover the rest with info divs */
div#info1, div#info2, div#info3
{
 width: 248px;
 display: block;
 height: 150px;
 margin-left: 248px;
}

You will notice some strange dimension measurements; this is an effort to combat the way browsers treat differently how to measure an element (if they should include the border or not). The final rendering is almost identical to the three browsers I tested (IE8, FF3.5, O10).

Complete test HTML:

<html>
<head>
<style>

div#header, div#chart, div#legend,
div#info1, div#info2, div#info3
{ border: 1px solid black; }

body { text-align: center; }

div { width: 500px; margin: auto; padding: 0; text-align: center; }

div#header { width: 500px; height: 50px; }
div#chart  { width: 248px; height: 250px; float: left; clear: left; }
div#legend { width: 248px; height: 202px; float: left; clear: left; }

div#info1, div#info2, div#info3
{ width: 248px; display: block; height: 150px; margin-left: 248px; }

</style>
</head>
<body>

<div>
  <div id="header">header</div>
  <div id="chart">chart</div>
  <div id="legend">legend</div>
  <div id="info1">info1</div>
  <div id="info2">info2</div>
  <div id="info3">info3</div>
</div>

</body>
</html>

Upvotes: 4

plainprogrammer
plainprogrammer

Reputation: 594

One option that works for me in Safari is this:

#header {
  height: 50px;
  background-color: #000000;
}  

#chart, #legend {
  float: left;
  clear: left;
  width: 50%;
}

#chart {
  height: 150px;
  background-color: #ff33ff;
}

#legend {
  height: 75px;
  background-color: #33ffff;
}

#info1, #info2, #info3 {
  float: right;
  clear: right;
  width: 50%;
  height: 75px;
}

#info1 {
  margin-top: -150px;
  background-color: #ffff33;
}

#info2 {
  margin-top: -75px;
  background-color: #ffccff;
}

#info3 {
  background-color: #66ff66;
}

I chose arbitrary heights so you implementation would need to be adjusted but I think the adjustments are pretty clear from the CSS.

Upvotes: 1

Mottie
Mottie

Reputation: 86443

This works for me in FF, Chrome and IE8... not sure about older IE and other browsers

<style type="text/css">
 #container { width: 95%; height: 95%; margin: 0 auto; overflow: auto; }
 #header { height: 9%; background: #444; }
 #chart  { width: 50%; height: 70%; float: left;  background: #555; }
 #legend { width: 50%; height: 20%; float: left;  background: #666; }

 #info1  { width: 50%; height: 30%; float: right; background: #111; }
 #info2  { width: 50%; height: 30%; float: right; background: #222; }
 #info3  { width: 50%; height: 30%; float: right; background: #333; }
</style>

<div id="container">
 <div id="header">Header</div>
 <div id="chart">Chart</div>
 <div id="info1">Info 1</div>
 <div id="info2">Info 2</div>
 <div id="info3">Info 3</div>
 <div id="legend">Legend</div>
</div>

*Note: I had to add the overflow:auto to the container to make it work in IE.

Upvotes: 0

Kris C
Kris C

Reputation: 2848

As pointed out elsewhere adding extra container divs to act as the columns is the way to go. Whilst perhaps unappealing as you have layout logic in your HTML, this is the currently accepted practice. And is nicer than using tables for layout.

Alternately you could take a static approach and use absolute positioning.

Upvotes: 0

bobince
bobince

Reputation: 536567

The problem is that you end up injecting layout logic into html.

Well spotted!

The fact is: CSS Positioning is not powerful to fulfill all possible layouts, especially when you are dealing with complex liquid layouts and double-especially when, as seems to be the case with your example, you want to tie the heights of unrelated, size-based-on-content elements together.

Yes, there are workarounds for many common situations, such as the ‘same height columns’ hacks and grids made out of nested floats and clears. But this almost always requires the markup to be tailored to the layout. Sometimes you can hide that by thinking of ‘nice’ class names that describe how the contained elements are related; more often, you end up with nastiness like class="left_column".

Simple layouts can be done with relatively few spurious wrapper divs and reorderings, so that still ends up a bit nicer than tables. But for variable-size stuff like your example appears to be, it's not really possible; what hacks do exist would end up deeper and less maintainable than just using a table. So go ahead and bung them in a table, as long as you use table-layout: fixed to make them stable and fast to render, and don't start nesting tables like the Netscape 4 horrors of yesteryear.

Until CSS delivers the Holy Grail of complete layout/markup independence — and that's something that CSS3 might deliver in a few more decades! — you will still occasionally need to use a table. There's no shame in it.

Upvotes: 0

Anas Toumeh
Anas Toumeh

Reputation: 201

<div>
  <div id="header"></div>
  <div style="float:left;width:50%;">
    <div id="chart"></div>
    <div id="legend"></div>
  </div>
  <div style="float:left;width:50%;">
    <div id="info1"></div>
    <div id="info2"></div>
    <div id="info3"></div>
  </div>
  <div style="clear:both;"></div>
</div>

Upvotes: 1

Jim Schubert
Jim Schubert

Reputation: 20357

This may not be exactly what you're looking for. I only spent a few minutes on it. It's not too difficult if you have control over how your div elements appear on the page.

<!-- The following shows your desired html structure -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title></title>
<style type="text/css">
html, body {
    margin: 0;
    padding: 0;
    background: #778899;
    min-width: 720px;
    max-width: 1020px;
}
#header {
    background-color:black;
    color:white;
    height:150px;
}
#chart {
    float:left;
    height:120px;
    width:50%;
    background-color:green;
    top:150px;
}
#legend {
    float:left;
    height:230px;
    width:50%;
    background-color:yellow;
}
#info1 {
    float:right;
    height:150px;
    width:50%;
    background-color:red;
    top:150px;}
#info2 {
    float:right;        
    height:150px;
    width:50%;
    background-color:black;
    color:white;}
#info3 {
    float:right;        
    height:150px;
    width:50%;
    background-color:yellow;}
</style>
</head>
<body>
<div style="width:500px;margin-left:150px;margin-left:160px;">
  <div id="header">BLACK</div>
  <div id="chart">green</div>
  <div id="info1">red</div>
  <div id="legend">yellow</div>
  <div id="info2">black</div>
  <div id="info3">yellow</div>
</div>
</body>
</html>

Upvotes: 2

jennyfofenny
jennyfofenny

Reputation: 4365

Here's something to start with:

HTML

<div id="header"></div>
<div id="left-column">
    <div id="chart"></div>
    <div id="legend"></div>
</div>
<div id="right-column">
    <div id="info1"></div>
    <div id="info2"></div>
    <div id="info3"></div>
</div>
<div class="clear"><!-- --></div>

CSS

#left-column{position:relative;float:left;width:50%;}
#right-column{position:relative;float:right;width:50%;}
.clear{clear:both;}

Upvotes: 6

Niels Bom
Niels Bom

Reputation: 9397

I don't see any HTML in your question.

The answer to your question depends on whether you want a liquid or a static design.

Upvotes: 0

Josh Leitzel
Josh Leitzel

Reputation: 15209

You use lots of cool things like float and position.

Or if you're looking for a solid framework that does most of the work for you, check out Blueprint CSS, which has several grid layouts that you might find applicable.

Here's some more resources you might find useful:

Upvotes: 4

Robert Greiner
Robert Greiner

Reputation: 29722

http://www.amazon.com/HTML-Utopia-Designing-Without-Tables/dp/0975240277/ref=sr_1_3?ie=UTF8&s=books&qid=1256937368&sr=8-3

is a good place to start with CSS.

Let me get you started off on the right foot, but the best way to learn this stuff is by doing.

I absolutely sucked at CSS when I first started, and now I'm fairly comfortable with it because I practice alot.

CSS

#header {
   width: 100%;
   height: 100px;
}

HTML

<div id="header"></div>

Upvotes: 1

Related Questions