4

I needed two columns of equal height, so used display:table. So far so good.

I then needed links to line up at the base of the table-cells, so went for absolute positioning.

Looks perfect, except in Firefox where the links aren't constrained by the 'position: relative' table-cells. Is there a way to fool Firefox into displaying this correctly?

Demo: http://jsfiddle.net/andy_lamb/C7qpX/

HTML:

<div id="equal_cols">
    <div class="largeleft">
        <img style="padding: 5px; margin: 10px; float: right; border: 1px solid #ccc;" src="images/some_img.jpg" width="205" height="126" alt="image" />
        <h2>Heading</h2>
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque mattis auctor metus, sit amet sollicitudin elit imperdiet sit amet.</p>
        <div class="alignlink"><a class="greybg" href="#">Read more</a></div>
    </div>
    <div class="col10px"></div>
    <div class="smallright">
        <h2>Heading</h2>
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque mattis auctor metus, sit amet sollicitudin elit imperdiet sit amet. Nunc laoreet leo nec sem porta scelerisque. In vestibulum fermentum metus, mattis placerat orci ornare quis. Maecenas vitae accumsan tellus.</p>
        <div class="alignlink"><a class="greybg" href="#">Read more</a></div>
    </div>
</div>

CSS:

a.greybg {
    padding: 3px;
    background: #464646;
    color: #ffffff;
}
p {
    padding: 10px 20px;
    margin: 0;
    font-size: 0.875em;
}
div.alignlink {
    position: absolute;
    bottom: 10px;
    right: 10px;
    margin: 0;
    padding: 0;
}
.equal_cols {
    display: table;
    width: 798px;
}
.largeleft {
    display: table-cell;
    width: 500px;
    border: 1px solid #ccc;
    position: relative;
    padding: 0 0 30px 0; /*ensures enough room for absoutely positioned .greybg link*/
}
.col10px {
    display: table-cell;
    position: relative;
    width: 10px;
}
.smallright {
    display: table-cell;
    width: 288px;
    border: 1px solid #ccc;
    position: relative;
    padding: 0 0 30px 0; /*ensures enough room for absoutely positioned .greybg link*/
}

Other than creating an HTML table, I can't think of a way around it. This must be possible with CSS...

tw16
  • 29,215
  • 7
  • 63
  • 64
andylamb
  • 147
  • 2
  • 13
  • 1
    Just for the record, this isn't a bug. The spec says `The effect of 'position:relative' on table-row-group, table-header-group, table-footer-group, table-row, table-column-group, table-column, table-cell, and table-caption elements is undefined.` Unfortunately, Firefox has acted like this for a long time. – tw16 May 15 '13 at 18:11
  • 2
    The only way I see to help, if you really want to use `table-cell` would be to put a div inside that cell like `
    – SpYk3HH May 15 '13 at 18:14
  • possible duplicate of [Does Firefox support position: relative on table elements?](http://stackoverflow.com/questions/5148041/does-firefox-support-position-relative-on-table-elements) – cimmanon May 15 '13 at 18:14
  • 3
    Bug report from 2000: https://bugzilla.mozilla.org/show_bug.cgi?id=63895 – cimmanon May 15 '13 at 18:15
  • 1
    @tw16 looks like from [CSS2 spec](http://www.w3.org/TR/CSS2/visuren.html#propdef-position), while [CSS3](http://www.w3.org/TR/css3-positioning/#position) says `"The effect of ‘position: relative’ on table elements is defined as follows: ... table-cell offset relative to its normal position within the table ..."` – Aprillion May 15 '13 at 18:23
  • @SpYk3HH Good idea, but I'm afraid it doesn't work. The block-level, relative div doesn't extend to the full height of the containing table-cell. I tried it earlier. – andylamb May 15 '13 at 18:31
  • why not setup your links to have vertical-align: bottom in your css? – Cam May 15 '13 at 18:32
  • @tw16 Thanks for the edit btw. I tried pasting the code in but it looked a mess for some reason. – andylamb May 15 '13 at 18:37

1 Answers1

3

By adding an extra inner wrapper and using some JS you can achieve this: http://jsfiddle.net/David_Knowles/wyTga/

//  This clean plugin layout provieds typical jQuery syntax such as $("element").plugin() or $.plugin("element")
(function($) {
    if (!$.equalHeights) {  //  checks to make sure this namespace is not already used in jQuery object (its not!)
        $.extend({  //  allows you to add methods to jQuery Object to be called, such as $.ajax
            equalHeights: function(elm) {   //  our function to be added
                //  the following simply checks to see if a jQuery Object is being passed in, or an element tag name/id/class
                if (typeof elm === "string") elm = $(elm);  //  now convert possible string to object
                //  the following maps all of our elements passed in and returns an array of their heights,
                //  then by using the math max method, we grab the biggest one
                var maxHeight = Math.max.apply(null, $(".inner").map(function () { return $(this).height(); }).get());
                //  the following maintains with jQuery's "chainability"
                return elm.each(function(index){ $(this).height(maxHeight); });
            }
        });
        $.fn.extend({   //  here we add element object methods, such as $("element").toggle
            equalHeights: function() {
                //  simply return our already made function, maintaining chainability
                return $.equalHeights($(this));
            }
        });
    }
})(jQuery);

$(function(){ 
    $(".inner").equalHeights();
    //  force resize on window height change if needed
    $(window).resize(function(e) { $(".inner").equalHeights(); });
});
SpYk3HH
  • 22,272
  • 11
  • 70
  • 81
Timidfriendly
  • 3,224
  • 4
  • 27
  • 36
  • 1
    +1, good approach, hope you don't mind, but i took the opportunity to beef up your plugin reference and provide a full explanation so it may be more properly used and repeated in the future. Again, gj! – SpYk3HH May 15 '13 at 19:40
  • Thanks @Timidfriendly. Unbelievable that this can't be achieved with CSS but there you go (thanks, Firefox). Looks like it's javascript with an HTML table fallback. Or maybe just an HTML table (not really; any excuse to use jQuery)! – andylamb May 15 '13 at 19:56
  • @andylamb I know it sucks. Just being pragmatic here and finding a solution nearish to what you already have. In the past I approach this differently; I place the links UNDER the columns – Timidfriendly May 15 '13 at 20:02
  • 1
    @ SpYk3HH your example doesn't execute on window.resize. By adding extra CSS declaration it does. $(".inner").css("height","auto").equalHeights(); – Timidfriendly May 15 '13 at 20:04