Absolutely Position Element Within a Table Cell

Avatar of Chris Coyier
Chris Coyier on (Updated on )

Have you ever wanted to absolutely or relatively position a table cell? Well, I can’t help you there. Table cell elements just won’t take those position values. And thus, you also can’t absolutely position elements within the context of those elements either. I can help you out with that issue.

The answer is just to make a generic wrapper element inside the table cells (the exact same size of the table cell) and use that as the relative positioning context. Non-semantic? Yep, but we’ll chuck that markup in with JavaScript so it’s not a big deal. Kludgy fix? You know it. Does it work? Sure does.

Before

<table>
   <tr>
       <td>
             <img src="yay.jpg" alt="">
      </td>
  </tr>
</table>

After

<table>
   <tr>
       <td>
            <div class="innerWrapper"> <!-- appended with JavaScript -->
                 <img src="yay.jpg" alt=""> <!-- original content of cell -->
            </div>
      </td>
  </tr>
</table>

jQuery Plugin

You could insert your inner div wrappers however you want, but there is appeal to using JavaScript/jQuery to do it because 1) it’s pretty easy and 2) it keeps your markup the same / clean.

We’ll make a quick jQuery plugin here, so that it can be called on any arbitrary set of elements.

$.fn.iWouldLikeToAbsolutelyPositionThingsInsideOfFrickingTableCellsPlease = function() {
    var $el;
    return this.each(function() {
    	$el = $(this);
    	var newDiv = $("<div />", {
    		"class": "innerWrapper",
    		"css"  : {
    			"height"  : $el.height(),
    			"width"   : "100%",
    			"position": "relative"
    		}
    	});
    	$el.wrapInner(newDiv);    
    });
};

This plugin iterates through each element it is passed, creates a <div> which has relative positioning and is the same height and width of the parent cell, then wraps the inside of that cell within itself.

Bear in mind I’m not using all the generally-regarded-as-smart plugin conventions like this does.

Usage

Load jQuery. Then run the above plugin code. Then use the plugin like this, either at the bottom of your web page or within a DOM ready statement.

$("th, td").iWouldLikeToAbsolutelyPositionThingsInsideOfFrickingTableCellsPlease();

That appends the inner wrapper to all table cells (<th> and <td> elements) although as you can see you can apply it to any arbitrary set of elements.

View Demo