Search code examples
csssemantic-markup

Is there a CSS alternative to horizontal table layouts without drawbacks?


My boss wants me to stop using CSS layouts and start using table layouts. A major factor in this is the desirable behavior of tables in horizontally positioned, fluid layouts. See this example:

If you slide the width of the HTML panel narrower, you will see that the table (the first one) has several convenient qualities:

  1. Automatically finds a good place to split the two cells, giving the cell with more content a larger percentage of the available width.
  2. Fills all of the available width 100%.
  3. When deciding which of the cells to wrap, it does so in the way most efficient with regards to vertical space.
  4. Keeps the two cells aligned horizontally no matter what.

Example A does not have quality 1. (You have to update the ratio by hand if the content size changes.)

Example B does not have quality 1 or 3. (Static 50% is less than ideal but could work. However, it breaks on to 3 lines while the table is still only 2 lines tall.)

Example C does not have quality 2 or 4. (I can see ways to fake quality 2 with this one, but clearing down to the next line is totally a deal breaker.)

Example D does not have quality 1 or 4. (Technically it has 1, but the huge gap in between is not practical. Also, left/right floating on the same line doesn't work well in some browsers.)

Since the data is not semantically tabular, I really want to avoid using tables. But my boss pays me, so I need to go with what he says or find a better solution. Is there a way to do this using semantic markup and CSS?


Solution

  • Updated: For all browsers > ie7 you can use display: table, table-row, table-cell. the jQuery code will target ie7 and then replace the div's with appropriate table elements.

    If this is the only problem you've run into so far, you shouldn't install some goofy grid system just to fix this. That's overkill and a waste of time.

    http://jsfiddle.net/CoryDanielson/yuNTX/

    sample html

    <div class="table width100pct">  <!-- .table should have NO style. just 'display: table' -->
        <div class="tr">
            <div class="td"></div>
            <div class="td"></div>
        </div>
    </div>​
    <!-- class="table, tr, td" is ONLY for changing display: table, table-row and table-cell.
    you SHOULD NOT include any styles inside of these CSS selectors. These classes will 
    be removed when the divs are transformed into <table>, <tr>, <td>
    -->
    
    //conditionally load the javascript patches for ie7
    <!--[if IE 7]><script src="/js/IE7fixes.js"></script><![endif]-->
    

    IE7fixes.js

    $(document).ready(function(){
      //comment out the if statement to check functionality without ie7    
      if ($.browser.msie && $.browser.version == 7) {
          $('html').addClass('ie7') //<html class="ie7">.. like modernizr
          var elem, elemClass    
          $('div.table').each(function(i, elem) {
              elem = $(elem)
              elemClass = elem.removeClass('table').attr('class') || ''
              elem.wrapInner("<table class='" + elemClass + "' />").children().unwrap()
          })
          $('div.tr').each(function(i, elem) {
              elem = $(elem)
              elemClass = elem.removeClass('tr').attr('class') || ''
              elem.wrapInner("<tr class='" + elemClass + "' />").children().unwrap()
          })  
          $('div.td').each(function(i, elem) {
              elem = $(elem)
              elemClass = elem.removeClass('td').attr('class') || ''
              elem.wrapInner("<td class='" + elemClass + "' />").children().unwrap()
          })
      }                    
    });​
    

    You should structure your CSS similar to mine

    required css

    table, div.table { width: 100%; }
    tr, div.tr { vertical-align: top; }
    /* the following 3 classes will be dropped when transformed in ie7
       but that won't matter because they'll fall back to <table><td><tr>
     */
    div.table { display: table; } /* NO STYLES HERE */
    div.tr { display: table-row; } /* NO STYLES HERE */
    div.td { display: table-cell; } /* NO STYLES HERE */