Ropstah
Ropstah

Reputation: 17804

Why does 'clear:left' also clears right?

I've been struggling to get CSS floating to work (in my head).

Note the following example:

<style type="text/css">
    div.container {
        width:500px;
    }
    div.left {
        float:left;
        clear:left;
    }
    div.right {
        float:right;
    }
</style>
<div class="container">
    <div class="left">leftdata 1</div>
    <div class="left">leftdata 2</div>
    <div class="right">rightdata 1</div>
    <div class="right">rightdata 2</div>
    <div class="right">rightdata 3</div>
    <div class="right">rightdata 4</div>
</div>

This will give the following output:

+--------------------------------------------------------------------+
| leftdata 1                                                         |
| leftdata 2         rightdata 1 rightdata 2 rightdata 3 rightdata 4 |
|                                                                    |
+--------------------------------------------------------------------+

However I was expecting this:

+--------------------------------------------------------------------+
| leftdata 1         rightdata 1 rightdata 2 rightdata 3 rightdata 4 |
| leftdata 2                                                         |
|                                                                    |
+--------------------------------------------------------------------+

Why is clear:left; also clearing right?


My goal:

I want to only add a clear:right; to the DIVs marked with class: right. This should produce the following:

<style type="text/css">
    div.left {float:left;clear:left;}
    div.right {float:right;clear:right;}
</style>
+--------------------------------------------------------------------+
| leftdata 1                                             rightdata 1 |
| leftdata 2                                             rightdata 2 |
|                                                        rightdata 3 |
|                                                        rightdata 4 |
+--------------------------------------------------------------------+

Upvotes: 5

Views: 1172

Answers (5)

B T
B T

Reputation: 60875

In CSS, for some stupid reason, it matters what order you put the floated divs in. If you put the <div class="right"> ones in FIRST (instead of putting the left ones in first), then there won't be that extra newline on the right.

Another thing: I don't think anyone should ever use css's clear command. Why? Because it can be affected by other surrounding floated elements. In other words, clear:both doesn't just clear space for floated elements in the currrent element, it clears space for every floated element on the page.

The better solution is using overflow:auto;

Heres some code that accommplishes what you want:


<style type="text/css">
    div.container {
        width:500px;
        overflow:auto;
    }
    div.left {
        float:left;
    }
    div.right {
        float:right;
    }
</style>
<div class="container">
    <div class="right">rightdata 1</div>
    <div class="left">leftdata 1</div>
    <br>
    <div class="right">rightdata 2</div>
    <div class="left">leftdata 2</div>
    <br>
    <div class="right">rightdata 3</div>
    <br>
    <div class="right">rightdata 4</div>
</div>

Edit: Actually, note that in this situation, neither clear, nor overflow:auto are strictly neccessary to produce the configuration of leftdata/rightdata divs, but they are neccessary if you want the container div to expand to the height of the divs. Without clear or overflow:auto, the div's height will not expand to accomodate the height of floated divs it contains.

Upvotes: 2

stevedbrown
stevedbrown

Reputation: 8934

To answer you question,

clear:left

is clearing left. If you have a float:left, clear:left clears it. I agree with everyone else in that float:left and float:right alone are not really going to get you a column formatting.

Upvotes: 1

nnevala
nnevala

Reputation: 5997

In your first example the rightdata-divs are placed under the left ones because they appear later in the document. Place them first and you get your expected results.

Or you could try something along the lines of:

<style type="text/css">
  div.left {
    float: left;
  }

  div.right {
    float: right;

  }
  div.container {
    width:500px;
    overflow: auto; /* to make sure .container expands vertically */
  }

<div class="container">
  <div class="left">
    <div>leftdata 1</div>
    <div>leftdata 2</div>
  </div>
  <div class="right">
    <div>rightdata 1</div>
    <div>rightdata 2</div>
    <div>rightdata 3</div>
    <div>rightdata 4</div>
  </div>
</div>

Upvotes: 4

anddoutoi
anddoutoi

Reputation: 10111

I think your best bet is to do something like:

+--------------------------------------------------------------------+
|+------------+                                       +-------------+|
|| leftdata 1 |                                       | rightdata 1 ||
|| leftdata 2 |                                       | rightdata 2 ||
|+------------+                                       | rightdata 3 ||
|                                                     | rightdata 4 ||
|                                                     +-------------+|
+--------------------------------------------------------------------+

EDIT: like the code that john misoskian posted ^^

Upvotes: 1

john misoskian
john misoskian

Reputation: 584

<style type="text/css">
    div.left {float:left;}
    div.right {float:right;}
    br.clear{clear:both;}
</style>

<div class="container">
    <div class="left">
         <div> data 1 </div>
         <div> data 2 </div>
         <div> data 3 </div>
    </div>
    <div class="right">
         <div> right data 1 </div>
         <div> right data 2 </div>
         <div> right data 3 </div>
    </div>
    <br class="clear" />
</div>

Upvotes: 1

Related Questions