Responsive tables, the smart way

2020-01-27 07:06发布

问题:

I've got a table that contains data. Tabular data. And it looks like this.

See this fiddle.

Now what I'd like is, when it's displayed on a narrower screen, for the table to look like this, so that you don't get a horizontal scroll bar and it keeps the same visual structure:

(or if you want, like this fiddle.)

Now my question is, how do you do that? I'd prefer a CSS only way, but so far, I haven't managed to do that in only CSS. (The second fiddle contains rowspan attributes, which don't have CSS equivalents.)

The HTML is generated server side, so I could generate one of the two layouts depending on the window width, but then it wouldn't respond to a window resize.

I'm not against a little Javascript, but in this case, to translate the first table into the second on a window resize, it would need to be taken apart and rebuilt, cell by cell, and I think that's overkill. Still looking for a media query that can do all the work.

Experimenting a bit, I came this close, but that doesn't work in IE8 and IE9.

So, does anybody have any ideas how to tackle this? The ideal solution would work on table cells of varying height (2 lines of text or more) and any number of columns.

回答1:

ya as your html is same you can change the styles for the css properties according to the media query a better solution would be- fiddle

@media only screen and (min-width: 769px) {
       #content {
    border:1px solid;
    border-collapse:collapse;
}
#content td, #content th {
    border:1px solid;
    text-align:left;
    padding:.07em .2em;
    white-space:nowrap;
    font-weight:400;
}
}
@media only screen and (max-width: 768px) {
#content {
    border:1px solid;
    border-collapse:collapse;
}
#content tr {
    height:4em; border-bottom:1px solid;
}
#content th {
    border:1px solid;
    text-align:left;
    padding:.07em .2em;
    white-space:nowrap;
    font-weight:400;
    height:4em;
}
#content td {
    padding:.07em .2em;
    white-space:nowrap;
    height:1.4em;
    display:inline;
}
#content td:not(:last-child)::after {
    display:block; content:'';
    height:0;
    border-bottom:1px solid;
}

}

one possible solution is to use media queries an hide the respective blocks or change styles accordingly

here is a fiddle
changed smaller table id to content2

@media only screen and (max-width: 768px) {
    #content{
        display:none !important;
    }
}
@media only screen and (min-width: 769px) {
    #content2{
        display:none !important;
    }
}


回答2:

I know this isn't exactly what you want but I created a jsfiddle some time ago as a reference which might help: jsfiddle.net/webbymatt/MVsVj/1

essentially the markup remains the same, there's no JS and the content just reflows as expected. you just need to add the data-type attribute to the table cell.



回答3:

Check this CodePen.

I found this solution long ago in css-tricks.com.

The table gets a little messy:

<table>
    <tr>
        <td>
            Description 1
        </td>
        <td>
            <table class="responsive" cellpadding="0" cellspacing="0">
                <tbody>
                    <tr>
                        <td class="text-center">Data 1A</td>
                        <td class="text-center">Data 1B</td>
                        <td class="text-center">Data 1C</td>
                    </tr>
                </tbody>
            </table>                
        </td>
    </tr>
    <tr>
        <td>
            Description 2
        </td>
        <td>
            <table class="responsive" cellpadding="0" cellspacing="0">
                <tbody>
                    <tr>
                        <td>Data 2A</td>
                        <td>Data 2B</td>
                        <td>Data 2C</td>
                    </tr>
                </tbody>
            </table>                
        </td>
    </tr>
</table>

And this is the css:

    /* Small display targeting */
    @media only screen and (max-width: 767px) {
        /* Force table to not be like tables anymore */
        .responsive, .responsive thead, .responsive tbody, .responsive th, .responsive td, .responsive tr {
            display: block;
        }

        /* Hide table headers (but not display: none;, for accessibility) */
        .responsive thead tr {
            position: absolute;
            top: -9999px;
            left: -9999px;
        }

        .responsive td {
            /* Behave  like a "row" */
            position: relative;
        }

        .responsive td:before {
            /* Now like a table header */
            position: absolute;
        }
    }


回答4:

You could inline block the elements. I haven't had much time to play, but something like the following:

#content {
    border:1px solid;
    border-collapse:collapse;
}
#content td, #content th {
    border:1px solid;
    text-align:left;
    padding:.07em .2em;
    white-space:nowrap;
    font-weight:400;
}
#content td {
    display: inline-block;
    width: 100px;
}

It's not the prettiest creation, though!

http://jsfiddle.net/8H3bN/