Jonathon
Jonathon

Reputation: 113

How can you determine the minimum width of a html table using javascript?

If a html table is set to table-layout: auto;, it has a minimum width set by the browser determined by the contents of the table. So even with width: 100%, the table will go beyond its container. Is there a way using javascript to find this minimum width?

I'm trying to make a responsive table solution. I made something similar to this: http://jsbin.com/apane6/14

At mobile, the table's contents are hidden and you click on it to see a full screen version of it. Right now I'm using media queries, but I'd like to know the exact width the table would have to switch to this mobile view. You can even see in the example at one point the table stretches beyond the width of the page creating a scroll bar, which I'm trying to avoid.

Here is my CSS:

table {
    border-collapse: collapse;
    border-spacing: 0;
    table-layout: auto;
    width: 100%;
}

@media (max-width: 768px) {
    table {
        table-layout: fixed;
        white-space:nowrap;
    }
    th, td {
        overflow: hidden;
        height: 15px;
        font-size: 0;
        color: transparent
    }
}

Upvotes: 1

Views: 2054

Answers (2)

TimSPQR
TimSPQR

Reputation: 2984

Just for the fun of it, I played around with the code this afternoon and came up with this complicated FIDDLE which is really only a start.

It breaks down the block model into each component of each part of the table. If all of your tds are the same width, then you'll need to only do one td (:eq(0)), if not, you'll have to iterate through all the columns. You can adjust the inner width to whatever size you want, assuming no contents.

It's a bit complex, but if you sum the relevant parts of the element it should give you an answer down to the pixel.

JS

var tableleftmargin = $('table').css("margin-left").slice(0, -2);
var tableleftborder = $('table').css("borderLeftWidth").slice(0, -2);
var tableleftpadding = $('table').css("padding-left").slice(0, -2);

var tdleftborder = $('table tr td:eq(0)').css('borderLeftWidth').slice(0, -2);
var tdleftpadding = $('table tr td:eq(0)').css('padding-left').slice(0, -2);

var tdinnerwidth = $('table tr td:eq(0)').css('width').slice(0, -2);

var tdrightpadding = $('table tr td:eq(0)').css('padding-right').slice(0, -2);
var tdrightborder = $('table tr td:eq(0)').css('borderRightWidth').slice(0, -2);

var rightpaddingwidth = $('table').css("padding-right").slice(0, -2);
var rightborderwidth = $('table').css("borderRightWidth").slice(0, -2);
var rightmarginwidth = $('table').css("margin-right").slice(0, -2);

$('.putmehere').html(
                     "Table left margin = " + tableleftmargin + "<br />" +
                     "Table left border = " + tableleftborder + "<br />" +
                     "Table left padding = " + tableleftpadding + "<br />" +
                     "td left border = " + tdleftborder + "<br />" +
                     "td left padding = " + tdleftpadding + "<br />" +
                     "td inner width = " + tdinnerwidth + "<br />" +
                     "td Right padding = " + tdrightpadding + "<br />" +
                     "td Right border = " + tdrightborder + "<br />" +
                     "Table right padding = " + rightpaddingwidth + "<br />" +
                     "Table right border = " + rightborderwidth + "<br />" +
                     "Table right margin = " + rightmarginwidth + "<br />"
                    );

Upvotes: 1

Jonathon
Jonathon

Reputation: 113

Well this isn't exactly how I wanted to do it, but it works. Because I was copying the table to display as an overlay, I could grab it's width instead of trying to figure out what the original table's width was (I couldn't because it's CSS was changed). Hope this JS makes sense.

$(document).ready(function (){  

    $('.overlay-element').on("click", function() {

        var overlayID = $(this).attr('id') + "-overlay";

        //animate overlay opening
        $("#"+overlayID).addClass('open');

        //drag.js allowing you to move the container within overlay with mouse
        drag("#"+overlayID+' .overlay-container').bind();

        //exit overlay
        $("#"+overlayID+' .overlay-exit').on("click", function() {
            $("#"+overlayID).removeClass( 'open' );
        });

    });


});


$(window).load(function() {

    //create overlay elements
    $('.overlay-element').each( function() {
        var overlayID = $(this).attr('id') + "-overlay";
        $("body").append(
                "<div id='"+overlayID+"' class='overlay overlay-scale'>
                    <div class='overlay-exit'></div>
                    <div class='overlay-container'>"
                         + $(this)
                            .clone()
                            .removeAttr('id')
                            .removeClass('overlay-element closed')[0]
                            .outerHTML 
                    + "</div>
                </div>"
            );

        //switch to mobile view for tables if their min width is larger than parent
        if ($("#"+overlayID+' table').width() > $(this).width()) {
            $(this).addClass('closed');
        }
    });

});

$(window).resize(function() {

    //switch to mobile view for tables if their min width is larger than parent
    $('.overlay-element').each( function() {
        var overlayID = $(this).attr('id') + "-overlay";

        if ($("#"+overlayID+' table').width()>$(this).width()) {
            $(this).addClass('closed');
        } else {
            $(this).removeClass('closed');
        }
    });

});

Upvotes: 0

Related Questions