Mozilla COL Alignment via DOM Scripting

Relates to CSS Design and DOM Scripting, Firefox and Co

One of the Mozilla rendering engine's few annoyances is its apparent disregard for the alignment attributes of col and colgroup elements within HTML tables. One might argue this is justified since alignment is a presentational attribute that should be defined with CSS. However, table alignment can be crucial to the visual display of data in a usable format and this should not be dependant on CSS - perhaps one reason why table alignment persists in the XHTML 1.1 Table Module.

Putting this presentation/structure debate aside, a workaround is required if alignment rules are to be defined by column in Mozilla browsers. One solution is to turn to CSS and define adjacent sibling selector rules (or direct adjacent combinators in CSS3 syntax) for table cells as demonstrated in these CSS snippets. However this will only work if the number of columns and columnar alignment is predefined.

The scenario I found myself in earlier today, working on the latest version of my PHP powered CMS, had column alignment and quantity determined on a content module basis with considerable variation. So it was once again time to call on the DOM, and to create those adjacent sibling selector rules dynamically.


function synchronizeColumns(table) {
  var inline = create('style');
  inline.setAttribute('type', 'text/css');
  var rule = "tbody th", 
      rules = "", 
      span, halign, valign, i, temp;
  (function(elem){
   temp = "";
   span = elem.getAttribute('span');     
   halign = elem.getAttribute('align');     
   valign = elem.getAttribute('valign');          
   if (halign != null) {
     temp += "text-align:" + halign + ";";  
   }
   if (valign != null) {
     temp += "vertical-align:" + valign + ";"; 
   }
   i = (span != null) ? span : 1;
   do {
     if (temp.length > 0) {
       rules += rule + "{" + temp + "}\n";
     }
     rule += "+td";      
   } while (–i > 0);
  }).Iterate(table.get('col')());
  inline.appendChild(create(rules,Node.TEXT_NODE));   
  get('head')(0).appendChild(inline);  
}

The rules are declared inline (to override any default alignment rules that may be set for columns, by appending a new style node to the head element. Then it is just a case of iterating through each col element in the table, extracting the corresponding align and valign attributes and building the corresponding rule. The span attribute must also be taken into consideration to ensure the correct attribute values are assigned across each column as this document fragment demonstrates:


<colgroup>
<col align="left" width="50" />
<col span="3" align="center" width="2*" />
<col width="3*" />
<col span="2" align="right" width="1*" />
</colgroup>

So, the do..while loop takes care of appending the correct number of adjacent sibling selectors.

The function described above only loops through col elements which met my requirements. Including colgroup elements is a little more complex since the content model can contain col child nodes or be empty. Since the problem only applies to Mozilla, this would be a perfect opportunity to utilise the supported TreeWalker interface from the DOM2 Traversal and Range specification. For example:


var nodes = document.createTreeWalker(
  table,
  NodeFilter.SHOW_ELEMENT, 
  {
    acceptNode : function(n) {
    return (n.tagName == "COL" || 
            (n.tagName == "COLGROUP" && 
             n.childNodes.length == 0)
           ) ?
      NodeFilter.FILTER_ACCEPT :  
      NodeFilter.FILTER_SKIP;
    }  
  },
  false);

The returned node list will contain all col and colgroup empty elements. This assumes that a colgroup element does not define the alignment for any child nodes - to account for this the acceptNode method would need to be extended further.

Posted on Monday, Nov 08, 2004 at 20:20:29.

Comments on Mozilla COL Alignment via DOM Scripting (2)

α comment

Quite insteresting is that Mozilla seems to ignore absolutely any styles assigned to columns through col or colgroup. A moment ago, I tried to use CSS for a few col's and colgroup's (I wanted to draw an outer border for four column group, using a different colour), I've set class attributes for the colgroup, then i tried to format it with CSS. And mozilla seems to simply ignore that. And even Konqueror does the same. :( Makes me think i'm doing something wrong, hmm…

Posted by RQ
Sunday, Nov 21, 2004 at 01:59:45

β comment

I have found assignment and cascade of CSS rules for tables to be quite erratic in all the browsers I have access to really - cannot test on Konqueror.

I ran some quick tests assigning a class to col and colgroup on Firefox 1.0 and Mozilla 1.6 (Win) and found that:


.colClass {
  /* This failed on both */
  text-align:right;
   
  /* This failed on Moz but ok on FF */
  background:#ccc;
  
  /* This partially worked in both! */
  border:1px solid #ccc;
}

The border did not work correctly if border rules had already been assigned to the table or its children regardless of specificity.

Perhaps your best solution is just to use adjacent selectors on the cells assuming the column count is predetermined?

PS Cheers - finally got round to fixing (hopefully) a bug in my fragment parser following the broken formatting of your original post :)

Posted by Tom W
Sunday, Nov 21, 2004 at 12:08:40

Breadcrumbs Trail

[ Home ] -> TW Blog -> Nov 04 -> Mozilla COL Alignment via DOM Scripting
Site Map

The Severn Solutions website achieves the following standards:

[ XHTML 1.0 ] [ CSS 2 ] [ WAI AA ] [ Bobby AA ]

Page compiled in 0.020 seconds