17

Situation: I have two fixed-height divs, overflow set to hidden on both, and dynamic text content within the first div. Should that content exceed the overflow boundaries of the first div, I would like for it to automatically spill into the second div.

My questions is simply how to do this? I've researched, and the closest thing I found was a JQuery plugin that automatically creates columns for a newspaper-like layout. While this is not exactly what I need, it does give me hope that this is achievable on a simpler level.

Visual Example:

  <html>
     <head>
       <style type="text/css">
          div{height:1in;width:4in;overflow:hidden}
        </style>
     </head>
    <body>
     <div id="d1">...(enough text to cause overflow exceeding 1in height)...</div>
     <div id="d2">...(the rest of the text that got cut off from the first div)...</div>
    </body>
   </html>

Thanks everyone! Based on all the input, I put this together. NOTE: this may not suit everyone's purpose:

  1. I did it in JQuery
  2. This is very conceptual
  3. Each additional item it its own element, and not just open text
  4. I already know for my needs that a single div will not break the overflow limits

That being said:

HTML

<html>
<head>
<style type="text/css">
    #base{border:1px black solid;height:2in;width:3in;overflow:hidden;}
    #overflow{border:1px black solid;width:3in;}
    .content{width:2in}
</style>
<script type="text/javascript" src="ref/js/jquery-1.6.2.min.js"></script>
<script type="text/javascript" src="work.js"></script>
</head>
<body>
<div id="base">
    <div id="sub"></div>
</div>
<br />
<div id="overflow">
</div>

JQ

$(document).ready(function(){

//  An array of content, loaded however you wish
var items=new Array();
items[0]='<div class="content" id="C0" style="border:1px blue solid;height:.75in">content 1</div>';
items[1]='<div class="content" id="C1" style="border:1px green solid;height:.75in">content 2</div>';
items[2]='<div class="content" id="C2" style="border:1px red solid;height:.75in">content 3</div>';
items[3]='<div class="content" id="C3" style="border:1px yellow solid;height:.75in">content 4</div>';
items[4]='<div class="content" id="C4" style="border:1px orange solid;height:.75in">content 5</div>';

//  Variable for the height of the parent div with the fixed width
var baseheight=$("#base").css('height').substring(0,$("#base").css('height').length-2);

//  Function to dynamically get the height of the child div within the fixed width div
function subheight(){return $("#sub").css('height').substring(0,$("#sub").css('height').length-2);}

// For each individual piece of content...
for(i=0;i<items.length;i++)
    {
    //  Add it to the child div
    $("#sub").append(items[i]);

    // Variable for the difference in height between the parent and child divs
    var diff=subheight()-baseheight;

    //  If this piece of content causes overflow...
    if(diff>0)
        {

        // Remove it...
        var tooMuch="#C"+i;$(tooMuch).remove();

        // And put it in the overflow div instead
        $("#overflow").append(items[i]);
        }
    }

});
Decoder.Ninja
  • 174
  • 1
  • 1
  • 8

6 Answers6

10

this is sort of JS only.

what you should do in JS:

  1. get the height of cont1
  2. when content is loaded to cont1, get the <p> height
  3. if <p>'s height > cont1's height, remove text (and store it to a temporary variable) starting from the end of of the text in<p>'s until it's height is equal or lesser than cont1.
  4. the removed text (which was stored earlier) will be dumped into the second cont2. wrap the text in <p> so that if you plan to do this feat again, you have 2 containers to deal with again.

not the most elegant of code (loop will lag when content is very long), but it's worth a try

HTML:

<div id="cont1">
    <p>long text here</p>
</div>
<div id="cont2">
    <p><!-- future content --></p>
</div>

CSS:

#cont1{
    height:100px;
    background:red;
    margin-bottom:10px;
    padding:10px;
}
#cont2{
    height:100px;
    background:blue;
    margin-bottom:10px;
    padding:10px;
}

JS:

//existing text must be rendered in the first container so we know how high it is compared to the div

//get references to avoid overhead in jQuery
var cont1 = $('#cont1');
var cont1Height = cont1.height();

var p1 = $('#cont1 p');
var p1Height = p1.height();

var p2 = $('#cont2 p');

//get text and explode it as an array
var p1text = p1.text();
p1text = p1text.split('');

//prepare p2 text
p2text = [];

//if greater height
while (p1Height > cont1Height) {

    //remove last character
    lastChar = p1text.pop();

    //prepend to p2 text
    p2text.unshift(lastChar);

    //reassemble p1 text
    p1temp = p1text.join('');

    //place back to p1
    p1.text(p1temp);

    //re-evaluate height
    p1Height = p1.height();

    //loop
}

//if less than, assemble p2 text and render to p2 container
p2.text(p2text.join(''));​
Joseph
  • 117,725
  • 30
  • 181
  • 234
  • Agreed, there is no way without JS for this one, as you are fundamentally changing the content markup. – Hawken Feb 16 '12 at 03:52
  • here's a proof of concept code: http://jsfiddle.net/P7Dfz/4/ (may lag due to loop) – Joseph Feb 16 '12 at 04:19
7

It's slightly hacky, but this should work. http://jsfiddle.net/D6L7u/

Basically it copies the content of the first div into the second and then offsets it so the initial text is not shown twice.

HTML

​<div id="one" class="mydiv">
Tail beef tenderloin chicken. Ground round tenderloin t-bone biltong fatback andouille bacon, ribeye leberkase boudin ham hock capicola salami frankfurter chicken. Boudin meatball pig strip steak, tongue sirloin brisket bacon capicola beef t-bone hamburger shankle beef ribs frankfurter. Capicola bresaola brisket chuck, short ribs ham jerky. Hamburger venison turkey short ribs jerky, bresaola chuck filet mignon spare ribs. Drumstick kielbasa sirloin jowl flank shoulder, salami tail short ribs corned beef chicken jerky tri-tip bresaola.
</div>

<div id="two" class="mydiv">

</div>​​​​​​​​​​​​​​​​​​​​​​​​​​​

CSS

​​.mydiv
{
    float: left;
    width: 200px;
    height: 200px;
    border: 1px solid black;
    overflow: hidden;
}

JS

​$(​function() {
    var copy = $("#one").clone().attr("id", "onecopy").css({
        "margin-top": "-200px",
        "height":"400px"
    });
    $("#two").append(copy);
});

You may wish to modify the js to be a little more dynamic such as getting the current height of div#one rather than a static value. ​

Kevin Ji
  • 10,479
  • 4
  • 40
  • 63
SynXsiS
  • 1,860
  • 10
  • 12
1

CSS3 supports this kind of columnar flow via its Multi-column Layout Module. Caniuse.com shows that it isn't supported around the board though.

Here's a Quirksmode.com article showing how it's used.

Twisol
  • 2,762
  • 1
  • 17
  • 17
0

Since the heights are fixed. Copy the html from first div into the second and scroll the second div up the height of the divs.

There will be two copies of the text but the illusion will be of having wrapped content.

Here is a working example: http://jsfiddle.net/natedavisolds/bxzCK/16/

natedavisolds
  • 4,305
  • 1
  • 20
  • 25
0

A framework like this allows you to detect when content overflows (otherwise a hard task). You can then decide what you want to do with the overflown content.

http://jsfiddle.net/mrtsherman/R7cZL/

<div  id="a" contenteditable>Start typing here...</div>
<div  id="b"></div>
<div  id="c">You should position me way off the screen</div>
<div  id="d">I'm a mirror of div C</div>

div {         
    border: 1px solid gray; 
    margin: 5px; 
    height: 75px; 
    width: 100px; 
    overflow: hidden; 
    display: inline-block;
}
div#c { visibility: hidden; position: absolute; left: -9999px; }

$('#a').bind('input propertychange', function() {
    //copy current content into hidden div c
    $('#c').html($(this).html());
    //now we know height of content if it we didn't have overflow on
    var cHeight = $('#c').height();
    //compare to current height, if greater than then we have overflowed
    if (cHeight > $(this).height()) {
        //move new content in div B
        //there are lots of ways to do this and it depends on what
        //people's input is. Can they cut/paste in?
        //Maybe we start at the end of the string, working backwards until
        //we find that content now fits.
    }
});​
mrtsherman
  • 39,342
  • 23
  • 87
  • 111
0

HTML

<div id="block1" style=">
  <p>
    long text...
  </p>  
</div>

<div id="block2">

</div>

Jquery

var $1stblock = $('#block1');
var $2ndblock = $('#block2');
var $1stpar = $('#block1 p');
var diff = $1stpar.height() - $1stblock.height();
$1stpar.clone().appendTo($block2).css('top', diff);

CSS

div {
  position: relative;
  overflow: hidden;
}

div p {
  position: absolute;
}
Kyle Macey
  • 8,074
  • 2
  • 38
  • 78