views:

365

answers:

6

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 |
+--------------------------------------------------------------------+
+1  A: 
<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>
john misoskian
This is the pragmatic solution to the problem yes... But why is 'clear:left' also clearing right? :)
Ropstah
clearing all , right and left :)
john misoskian
Isn't that the job of 'clear:both' ?
Ropstah
please visit w3 web site : http://www.w3.org/TR/CSS2/visuren.html#propdef-clear
john misoskian
Why the clear br? Why not use the overflow method on the container to save markup:http://www.quirksmode.org/css/clearing.html
Simon Scarfe
because , need cross browser support. and using clear the br.
john misoskian
never never EVER use <br class="clear" />... this is messy, horrible practice, as all it does is leads to problems down the line when you are trying to redesign your site. use css clears, such as `min-height:10px` and the `:after` method
Jason
@Jason: again, cross browser support. `:after` is not always supported.
cottsak
@cottsak i wrote that comment about a year ago. since then i would still agree with my statement, although i would change it to be `overflow:hidden` rather than `:after`. however, IRT my previous comment, the `height: 10px` method is for IE, the `:after` method is for all other browsers. so if you use both, you're x-browser compatible.
Jason
+1  A: 

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 ^^

anddoutoi
Although HTML is my mothertongue, i still rather have conceptual and visual answers like these! +1. However the question isn't really about solving the problem, it's more: why does 'clear:left' also clears right?
Ropstah
+3  A: 

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>
nnevala
Placing them first does not produce the expected results. I think you are referring to alternating the placement of 'left'/'right' divs and only clearing the 'right' ones. This will produce the expected results, however this would require the page to have an equal amount of 'left'/'right' DIVs
Ropstah
Only change required to your original example code is placing the div.right elements before div.left ones in the DOM. Thus, clear:left doesn't actually clear:right...
nnevala
A: 

another use :

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

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

    <div class="left">left 2 </div>
    <div class="right">right 2</div>
    <br class="clear" />

</div>
john misoskian
See comment @ nnevala
Ropstah
+1  A: 

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.

stevedbrown
+2  A: 

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.

B T
I just wanted to add that john misoskian's technique (of having inner div elements with the elements you want floated left and right separated) is the right way to go - although as I noted above, I disagree with his use of clear:both; . With my code above, you can't reliably add text in the middle there (non-floated text).
B T