Understanding Series

Working with dynamic multiple columns

Topic status automatically displays here - do not remove.

Bookmark me!Bookmark this topic  Print me!Print this topic

By Colin Ramsden, March 2008.

Newspaper style multiple columns in HTML have only been possible using predetermined statically fixed layout dimensions and block structured elements such as Tables or Divs. Now they can be dynamically determined. This article describes how you can create dynamically sized newspaper style columns in HTML today, using styles that won't be available for general use until the next version of CSS is released by the W3C standard organization.

The next release of CSS version 3 (CSS3) will introduce multiple column styles, however, as CSS3 has been in draft release for several years now, major browser vendors are unlikely to introduce CSS3 features until after the recommended release, so there may be some time yet until multicolumn CSS is widely supported. That doesn't mean that you shouldn't be thinking about dynamic multicolumn functionality now, and planning for its use where appropriate in your current stylesheets.

What are dynamic multiple columns?

 

How to layout the content into multiple columns

In general terms, take the content, and divide it by the number of columns:

  1. All HTML element text content is a string (stream) of characters. Count the total number of characters in the element, and divide it by the number of columns. This will determine the rough location for the column breaks. For example, if there were 100 characters, and you wanted three columns, then the ideal location for column breaks would be located as near as possible to characters 33 and 66.
  2. Search the string around these locations for the nearest space character, and break the string at that point.
  3. Display the text of each substring inside each respective column.

In script, this can be achieved with a function which receives a reference to the element, retrieves the text content from the element storing it locally as a string, divides the string into the number of columns, and returns the substrings for each column to the destination. For example:

function fnDivideIntoCols(elSrcID, elDestIDx, NumCols)
{
   var v, vSrc, vCount, vDest;
   aryDest = new Array();
.  aryCols = new Array();

   vSrc = document.getElementsByID[elSrcID];
   vCount.Total = vSrc.innerText.length;
   vCount.CharsPerCol = vCount.Total/NumCols;

   for(v=1; v<NumCols; v++)
   {
      //store the ideal position for the column break
      aryCols[v].IdealPos = v * vCount.CharsPerCol;
      //search around the ideal position for the space char
      aryCols[v].PostPos = vSrc.innerText.indexOf(" ", aryCols[v].IdealPos);
      aryCols[v].PrevPos = vSrc.innerText.lastIndexOf(" ", aryCols[v].IdealPos);
      //compare search results to determine closest space to ideal position
      if((aryCols[v].IdealPos-aryCols[v].PrevPos)<(aryCols[v].PostPos-aryCols[v].IdealPos))
      {
         //break at PrevPos
         aryCols[v].BreakPos = arCols[v].PrevPos;
      }
      else
      {
         //break at PostPos
         aryCols[v].BreakPos = arCols[v].PostPos;
      }

   }

   //breakup the string
   aryDest[v].Content = vSrc.innerText.slice(1, aryCols[v].BreakPos);
}

Further refinement would take a larger block of content and parse the string to determine the extent of the divisible areas, setting flags to indicate the extent of what's required.

 

Examples of JS:

/* For additional information about this JavaScript
and how to use it, see the "Displaying Number of Words
Typed Into Form Fields" article, linked from the archives
at from http://willmaster.com/possibilities/archives/
The above note and the copyright line must remain with
this JavaScript source code. Comments below this point
in the code may be removed if desired. */

// Customizing this JavaScript code requires specifying eight values.

// Value One:
// Specify the maximum number of characters the form field
// may contain. If you have no maximum, specify 0 (zero).

var MaximumCharacters = "80";

// Value Two:
// Specify the maximum number of words the form field may
// contain. If you have no maximum, specify 0 (zero).

var MaximumWords = "16";

// Value Three:
// Specify the form's name (provided by the name="_____"
// attribute in the FORM tag).

var FormName = "myForm";

// Value Four:
// Specify the name of the text field being monitored
// (provided by the name="_____" attribute in the
// INPUT or TEXTARE tag).

var TextFieldName = "TextField";

// Value Five:
// Specify the field name where where is to be displayed
// the number of characters the user has typed. Make
// it blank (nothing between the quotation marks) if
// you aren't displaying the number of characters typed.

var CharactersTypedFieldName = "CharsTyped";

// Value Six:
// Specify the field name where where is to be displayed
// the number of characters left that may be typed.
// Make it blank (nothing between the quotation marks)
// if you aren't displaying the number of characters
// left.

var CharactersLeftFieldName = "CharsLeft";

// Value Seven:
// Specify the field name where where is to be displayed
// the number of words the user has typed. Make it
// blank (nothing between the quotation marks) if you
// aren't displaying the number of words typed.

var WordsTypedFieldName = "WordsTyped";

// Value Eight:
// Specify the field name where where is to be displayed
// the number of words left that may be typed. Make it
// blank (nothing between the quotation marks) if you
// aren't displaying the number of words left.

var WordsLeftFieldName = "WordsLeft";

//////////////////////////////////////////////////////
// //
// No modfications are required below this point. //
// //
//////////////////////////////////////////////////////

var WordsMonitor = 0;
var MaxWords = parseInt(MaximumWords);
var MaxChars = parseInt(MaximumCharacters);
var textfield = 'document.' + FormName + '.' + TextFieldName + '.value';

function WordLengthCheck(s,l) {
WordsMonitor = 0;
var f = false;
var ts = new String();
for(var vi = 0; vi < s.length; vi++) {
vs = s.substr(vi,1);
if((vs >= 'A' && vs <= 'Z') || (vs >= 'a' && vs <= 'z') || (vs >= '0' && vs <= '9')) {
if(f == false) {
f = true;
WordsMonitor++;
if((l > 0) && (WordsMonitor > l)) {
s = s.substring(0,ts.length);
vi = s.length;
WordsMonitor—;
}
}
}
else { f = false; }
ts += vs;
}
return s;
} // function WordLengthCheck()

function CharLengthCheck(s,l) {
if(s.length > l) { s = s.substring(0,l); }
return s;
} // function CharLengthCheck()

function InputCharacterLengthCheck() {
if(MaxChars <= 0) { return; }
var currentstring = new String();
eval('currentstring = ' + textfield);
var currentlength = currentstring.length;
eval('currentstring = CharLengthCheck(' + textfield + ',' + MaxChars + ')');
if(CharactersLeftFieldName.length > 0) {
var left = 0;
eval('left = ' + MaxChars + ' - ' + textfield + '.length');
if(left < 0) { left = 0; }
eval('document.' + FormName + '.' + CharactersLeftFieldName + '.value = ' + left);
if(currentstring.length < currentlength) { eval(textfield + ' = currentstring.substring(0)'); }
}
if(CharactersTypedFieldName.length > 0) {
eval('document.' + FormName + '.' + CharactersTypedFieldName + '.value = ' + textfield + '.length');
if(currentstring.length < currentlength) { eval(textfield + ' = currentstring.substring(0)'); }
}
} // function InputCharacterLengthCheck()

function InputWordLengthCheck() {
if(MaxWords <= 0) { return; }
var currentstring = new String();
eval('currentstring = ' + textfield);
var currentlength = currentstring.length;
eval('currentstring = WordLengthCheck(' + textfield + ',' + MaxWords + ')');
if (WordsLeftFieldName.length > 0) {
var left = MaxWords - WordsMonitor;
if(left < 0) { left = 0; }
eval('document.' + FormName + '.' + WordsLeftFieldName + '.value = ' + left);
if(currentstring.length < currentlength) { eval(textfield + ' = currentstring.substring(0)'); }
}
if (WordsTypedFieldName.length > 0) {
eval('document.' + FormName + '.' + WordsTypedFieldName + '.value = ' + WordsMonitor);
if(currentstring.length < currentlength) { eval(textfield + ' = currentstring.substring(0)'); }
}
} // function InputWordLengthCheck()

function InputLengthCheck() {
InputCharacterLengthCheck();
InputWordLengthCheck();
} // function InputLengthCheck()

As sourced from http://javascript.about.com/library/blcount.htm

function cnt(w,x){
var y=w.value;
var r = 0;
a=y.replace(/\s/g,' ');
a=a.split(' ');
for (z=0; z<a.length; z++) {if (a[z].length > 0) r++;}
x.value=r;
}

<form name="myform">
<textarea rows="15" name="w" cols="45"
onkeyup="cnt(this,document.myform.c)"></textarea>
<br />Word Count: <input type="text" name="c" value="0" size="5"
onkeyup="cnt(document.myform.w,this)" />
</form>  

 

http://www.w3.org/TR/css3-multicol/

Property index

Property Values Initial Applies to Inh. Percentages Media
column-break-after auto | always | avoid auto block-level elements no N/A visual
column-break-before auto | always | avoid auto block-level elements no N/A visual
column-count <integer> | auto auto block-level elements no N/A visual
column-fill auto | balance balance multi-column elements no N/A paged
column-gap <length> | normal normal multi-column elements no N/A visual
column-rule <‘border-width’> || <‘border-style’> || [ <color> | transparent ] see individual properties multi-column elements no N/A visual
column-rule-color <color> currentColor multi-column elements no N/A visual
column-rule-style <border-style> none multi-column elements no N/A visual
column-rule-width <border-width> medium multi-column elements no N/A visual
columns [ [ <integer> | auto] || [ <length> | auto] ] see individual properties block-level elements no N/A visual
column-span 1 | all 1 static, non-floating elements no N/A visual
column-width <length> | auto auto block-level elements no N/A visual

 

 

 

Who am I? > find out more

 


See Also

Jump to site home page Lotech Solutions' Tips, Tricks, and Procedures

Back to Top