tags:

views:

324

answers:

4

If I have a collection of div elements, I can use CSS to have them flow across the page and overflow onto the next line.

Here's a simple example:

<html>
  <head>
    <title>Flowing Divs</title>
    <style type="text/css">
      .flow {
        float: left;
        margin: 4em 8em;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <div class="flow">Div 1</div>
      <div class="flow">Div 2</div>
      <div class="flow">Div 3</div>
      <div class="flow">Div 4</div>
      <div class="flow">Div 5</div>
      <div class="flow">Div 6</div>
      <div class="flow">Div 7</div>
      <div class="flow">Div 8</div>
    </div>
  </body>
</html>

Is it possible to have the divs flow down the page instead of across it, so that they would flow down columns not along lines, but still occupy the same space as they would if they flowed across?

So for the example above, if they flowed into two lines of four divs, could I get the first column to contain Div1 and Div2 instead of Div1 and Div5?

+2  A: 

No, it is not possible. Easiest workaround is to make separate columns by adding wrapper-DIVs, and then adding content to each column. This could also be generated dynamically either with Javascript or serverside.

Arve Systad
+2  A: 

Quickly threw this together.:

#column1 {float:left}  
#column2 {float:left}  
div div{height:100px;width:100px;border:1px solid}

<div id="column1">    
      <div>1</div>  
      <div>2</div>  
</div>  
<div id="column2">  
      <div>3</div>  
      <div>4</div>  
</div>
Rob
Mark the code and hit the Code-button :)Anyways, this might work, but it requires a lot of (IMHO) unnessecary CSS, plus it's very...un-dynamic. :p
Arve Systad
There is a big box with the title "How to Format" right next to the textbox where you type your answer.
Sinan Ünür
Honestly, I did the 4-space thing first and it didn't work but don't know what I did wrong.
Rob
@Arve,You think three lines, actually 2 lines, of CSS is "a lot"? It's a heck of a lot less than all the javascript solutions shown and definitely better than "it can't be done".
Rob
Might not be a lot of code, but it's a really dirty solution IMO to dynamically write more CSS depending on the content on the page. What about exchanging your #column1 and #column2 to .column ? In other words, using IDs on each column is a waste. Classes win. :)
Arve Systad
You're confusing something slapped together in a few seconds with production code but, without giving it any further thought and not knowing how it will be used, I don't see anything wrong with it.
Rob
+1  A: 

No, you can't, but you could arrange them however you want by using absolute positioning. However, doing so means you have to explicitly set the position of each element, and that is usually undesired.

A simple adjustment to the markup can make this work though. Is the following what you wanted to see?

<html>
  <head> 
    <title>Flowing Divs</title> 
    <style type="text/css">
      .container {
        float:left;
      }
      .flow {
        margin: 4em 8em; 
      } 
    </style> 
  </head> 
  <body> 
    <div class="container"> 
      <div class="flow">Div 1</div> 
      <div class="flow">Div 2</div> 
      <div class="flow">Div 3</div>
    </div>
    <div class="container">
      <div class="flow">Div 4</div> 
      <div class="flow">Div 5</div> 
      <div class="flow">Div 6</div>
    </div>
    <div class="container">
      <div class="flow">Div 7</div> 
      <div class="flow">Div 8</div> 
    </div> 
  </body> 
</html>
Josh Stodola
A: 

Unfortunately it can't be done in pure html/css. Below is an example of how this can be accomplished in javascript. It can be made more efficient, but harder to learn from. I haven't tested in IE/Safari, but works in FF.

How to use: - Add the class 'container' to the flow container - thats it

Enjoy :).

<html>
<head>
<title>Flowing Divs</title>

<style type="text/css">
.container {
    float: left;
    height: 1px;
}

.col {
    float: left;
}

#container-1 {
}

.flow {
    float: left;
    margin: 4em 8em;
    width: 200px;
    height: 100;
    overflow-y: hidden;
}
</style>

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js"&gt;&lt;/script&gt;
</head>

<body>

<div id="container-1" class="container">
    <div class="flow">Div 1</div>
    <div class="flow">Div 2</div>
    <div class="flow">Div 3</div>
    <div class="flow">Div 4</div>
    <div class="flow">Div 5</div>
    <div class="flow">Div 6</div>
    <div class="flow">Div 7</div>
    <div class="flow">Div 8</div>
    <div class="flow">Div 9</div>
    <div class="flow">Div 10</div>
    <div class="flow">Div 11</div>
    <div class="flow">Div 12</div>
    <div class="flow">Div 13</div>
    <div class="flow">Div 14</div>
    </div>

    <script type="text/javascript">

    /**
     * Setup some event handling and stuff
     */

    // Create flowing container after dom is populated
    $(document).ready(function()
    {
        createFlowingContainer('#container-1'); 
    });

    $(window).resize(function()
    {
        // Recreate flow for all containers without fixed heights
        $('.container-autosize').each(function(i, container)
        {
            var container = $(container);

            // Update container dimenions
            container.height($(window).height());    

            createFlowingContainer(container);
        });
    });

    /**
     * Magical function
     */

    createFlowingContainer = function(container)
    {
        var container = $(container);

        // Columns counter
        var colNum = 0;    

        // Some more counter vars, these reset when a new column is created
        var colHeight = 0;
        var colWidth = 0;
        var containerWidth = 0;

        var itemNum = 0;

        // Get height of container
        var containerHeight = container.height();

        // Has the container height been defined? 1px is the default height (as defined in the css)
        if (containerHeight == 1)
        {
            // Set the container height default value
            containerHeight = $(window).height();

            // Used to resize container on window resize events
            container.addClass('container-autosize');

            // Update container height
            container.height(containerHeight);
        }

        var containerElements = container.children('div :not(.col)');

        if (containerElements.length == 0)
        {
            containerElements = $('[itemNum]');
        }
        else
        {
            container.children('div').each(function(i, o)
            {
                $(o).attr('itemNum', itemNum);

                itemNum++;
            });
        }

        var containerTmp = container.clone();
        containerTmp.html('');    

        containerElements.each(function(i, ele)
        {
            var ele = $(ele);

            // Get the item's height with padding & margins included
            var eleWidth = ele.width();
            var eleHeight = ele.outerHeight(true);

            // Can the current column fit this item?
            if ((eleHeight + colHeight) > containerHeight)
            {
                // Reset calculated height of column & advance column pointer
                colHeight = 0;
                colNum++;
            }

            // Get the column container
            var column = containerTmp.find('.col-' + colNum);

            // Does the column exist? If not, its a new column and we'll need to create it
            if (column.length == 0)
            {
                column = $('<div class="col col-' + colNum + '"></div>');

                // Append column to container
                containerTmp.append(column);
            }

            // Keep track of widest ele in column, used for setting width of container
            if (eleWidth > colWidth)
            {
                colWidth = eleWidth;
            }

            column.width(colWidth);

            // Increment the calculated column height
            colHeight += eleHeight;

            // Append element to column
            column.append(ele); 
        });

        container.html(containerTmp.html());

        // Calculate container width
        container.children('.col').each(function(i, o)
        {
            containerWidth += $(o).width();
        });

        container.width(containerWidth);
    };
    </script>

</body>
</html>
John Himmelman