Multi column layout control
- Download demo project - 20 Kb
- Download source - 32 Kb
- Download control documentation (chm file) - 34 Kb
Image 1. - Three column layout
Introduction
This control allows you to simply and automatically divide your html content into multiple columns and present articles in better readable multi-column layout. If you look at web page of random newspapers, you'll notice that width of article text is about 400px. This is because wider texts are less comfortable to read. In paper newspapers text of article is divided into more columns. This technique isn't used on the web pages, because it is more difficult to implement since you need to manually divide article into more columns. This control makes it possible...
See online demos
- I just started to use this control at my homepage - www.eeeksoft.net [^]
- You can also see attached demo application online [^]
Multi-column layout
Multi-column layout is part of CSS 3 specification (More at w3c.org - CSS3 module: Multi-column layout [^]), but since CSS 3 is still only a draft it will take long time before it will be possible to implement multi-column layout on your web page using CSS 3. If you want to use it now you have to divide every article into columns manually and put these columns in table or floating DIV elements.
This control does all the work automatically, so everything you have to do is to put it into your web page, column control then takes it's content and divides it into specified number of columns.
<cc:ColumnControl ColumnCount="3" runat="server"> .. your original long html content .. </cc:ColumnControl>
How does this control work
There are two main problems with implementing this control. First is how to calculate estimated height of content and the second is how to divide content into columns withou breaking anything, because it can't just split html after specified number of characters. I decided to solve this problems on server side, but it could be also implemented on client using JavaScript. I believe that server side is better for this, because it requiere quite complex code that would run very slowly on client and it wouldn't probably work on all clients. On the other hand it is more difficult to estimate size of HTML elements on server.
The control contains many features that allows you to specify how should the
original HTML code be divided. Control groups HTML tags into following
types: header tags (h1
, h2
, ...), paragraph tags
(p
, div
, ...), list tags (ul
,
ol
, dl
) and list items (li
,
dd
, dt
) and others. If control reaches the limit of
column while rendering its behavior depends on the current top level tag.
If breaking occurs in header tag, this header is moved to the beginning of next column. In parahraph tag control breaks this tag into two parts and second part is moved to the next column. In list control waits to the end of current list item and moves the rest of list items to next column. Other tags can't be divided, the control just moves to the end of the tag.
Header and list division
These images show how the control behaves when dividing content. Text highlighted with green color is first and red is second part when calculating where it should be divided. In gray boxes you can see the result. Interesting fact that you can see from second image is that if you add some more attributes to list (and also to paragraphs) it is automatically copied to second column, so these attributes aren't lost.
Formating tags
Automatic division works great, but sometimes you may need to specify something more. For example you want to define that one section of document should be divided into three columns, second section shouldn't be divided and third section should be two columns. Sometimes you may also need to insert some additional white space to specified column (and move content to following). This is exactly what formating tags are good for! Formating tags can be inserted into HTML code as HTML comments, so it is quite simple. Formating tags can be also very usefull when you want to load content form external resource and still be able to change division settings simply.
Image 2. - Usage of formating tags
Following code shows how you can control dividing behavior. If you enable
formating tags using EnableFormatTags
property, control will
not divide whole content info columns, but it will only divide sections marked
by cc:section
tag. (Image on the right side shows what this code generates)
<cc:ColumnControl runat="server" EnableFormatTags="true"> <h1>Header</h1> <!--[cc:section cols=2]--> <p>First paragraph..</p> <p>Second paragraph..</p> <!--[/cc:section]--> <h2>Small header</h2> <!--[cc:section cols=3]--> <p> This very long paragraph will be divided into three columns... </p> <!--[/cc:section]--> </cc:ColumnControl>
Second use for formating tags is when you need to move some content to
next column and you need to insert additional space to first one.
In this case you can use cc:space
tag as you can see in following
example:
<cc:ColumnControl ColumnCount="3" runat="server"> <p>First paragraph..</p> <!--[cc:space size=50]--> <p>Second paragraph..</p> <p>Third paragraph..</p> </cc:ColumnControl>
For more advanced examples with formating tags see online demo application [^].
Control properties
General properties
As you can see from previous examples, you can change column number using
ColumnCount
property. When you want to control division from
content using formating tags, you can use EnableFormatTags
.
If formating tags are enabled ColumnCount
is used as default
value when you don't specify column count in section tag (<!--[cc:section]-->
).
Image 3. - What can be done with MinColumnWidth property
Generated code
In current HTML, there are two ways of doing multi-column layout. First is using
table
with specified number of columns and second is using div
tags (with CSS styles). Each of this approach has its advantages and disadvantages, so
you can decide which one should be used by RenderMode
property.
It has following three possible values:
- DivFixed - generates columns using
div
elements. All columns except last one has css stylefloat:left
to achieve column layout. Each column has css classcc_col
and it contains anotherdiv
element withcc_cont
class. Last column contains element withcc_last
css class. - TableFixed - generates table with specified number of columns.
Each column has css class set to
cc_col
and it also has exactly set width in percents, so column width can't change. - TableVariable - Like previews method, generates table and
each column has css class set to
cc_col
. Table columns doesn't have specified width, so width can be adjusted by web browser.
If you use DivFixed
render mode, you can also use
MinColumnWidth
property to specify minimal width of control at which
column layout will be preserved. This means that if you resize control to smaller
width, it will display whole content in one column. This feature is demonstrated
in second example [^].
Appearance - column division
Because it is difficult to estimate size of elements, you can help control by
setting properties TagConstants
and ElementsSizes
. First one
can be used to specify ratio between sizes of elements. For example if you expect
that one character in pre
element has same size as 10 characters
in p
element, you can set this property to "pre=10"
and control
will use this settings for better division. ElementsSizes
property
allows you to specify how much space is taken by non-pair tags. This is very useful
if you want to insert image into document, just use this property (for example "img=500"
)
and control will be able to better estimate size of img
tags.
Usage of these properties is demonstrated in third
online example page [^].
As described above control uses three different approaches to division. You can
specify what HTML tags should be considered as header tags using HeaderTags
property
(control will never divide tag into multiple columns and it won't be left at the end
of column). Next type are lists that are divided only after end of list item.
Tags that are handled as lists can be set using ListTags
and
list items can be changed using ListItemTags
. Last type of tags
are ParagraphTags
that can be divided into multiple columns. SpaceChars
allows you to specify characters that can be used to divide content of paragraph.
Control also uses list of all other tags used for text formating. This list can
be modified using PairTags
property, but be careful - control expects
that all this tags have matching end tag!
Known issues
- Parser that is used for dividing HTML content passed to the control isn't very smart. It doesn't expect fully valid XHTML (it doesn't try to work with it using XML classes), but it expects that all pair tags have ending tag.
- I tried to test control as I could, but if you find any example when it generates strange results, please contact me! I'm looking forward to improving it.
Future work and history
- (7/7/2005) - Control available for ASP.NET 1.1 and ASP.NET 2.0 beta 2
- (7/7/2005) - First version of this article published at CodeProject