Search code examples
cssresponsive-designpseudo-elementpseudo-class

How to use nth-of-type with :before and targeting all but the last element, or the last element targeted differently


I'm using the css tricks responsive table (https://css-tricks.com/responsive-data-tables/), but wondering how to get rid of the mobile-view's last td "before" content.

Basically for this code, which writes the text in the td's for the responsive view:

table td:nth-of-type(1)::before { content: "Expenses"; }
table td:nth-of-type(2)::before { content: "2015"; }
table td:nth-of-type(3)::before { content: "2016"; }

For the first line (which writes "Expenses" in the cell), how do I have that happen for all but the LAST cell? What's happening is my last is the "totals" row for this table, so I don't need the "td content before" written to the last td (if that makes any sense... I'm also wondering if my table format needs tweaking, or I just have to deal with the "totals" line differently all together with these responsive tables -- there's no clear cut example on CSS tricks for a responsive table with a "totals" row).

I've been trying last-child, nth-last-of-type, etc. but having no luck. Here's an example of something I've tried:

 table td:nth-last-of-type(1)::before { content: " "; }

but, it does not work. I've read you can combine pseudo elements and psuedo classes... I've tried combinations with :not also, display: none, and have tried to change the HTML, but no luck. Maybe even write a display none with jQuery to the last td and add a class to then display none? I'm running in circles with this.

Can anyone help me?

thanks!

UPDATE: Here is a JSFiddle showing this: https://jsfiddle.net/gamehendgeVA/vh7bjscy/


Solution

  • If I understood your question correctly, you just want to remove the last descriptor "Expense" for the "total expenses" row? For this, you have to specifically target the last row first, and then its first td:

    table tr:last-of-type td:nth-of-type(1)::before{content: "";}
    

    table {border-collapse: collapse;width: 100%;color: #444;}
    tr:nth-of-type(2n+1) {background: #eee none repeat scroll 0 0;}
    th {background: #696969 none repeat scroll 0 0;color: #fff;font-weight: bold;}
    td, th {border: 1px solid #ccc;padding: 6px;text-align: left; vertical-align: middle;}
    /* responsive code */
    @media
    only screen and (max-width: 760px),
    (min-device-width: 768px) and (max-device-width: 1024px)  {
        /* Force table to not be like tables anymore */
        table, thead, tbody, th, td, tr {
            display: block;
        }
        /* Hide table headers (but not display: none;, for accessibility) */
        thead tr {
            position: absolute; top: -9999px; left: -9999px;
        }
        tr { border: 1px solid #ccc; }
        td {
            /* Behave  like a "row" */
            border: none; border-bottom: 1px solid #eee; position: relative; padding-left: 50%;
        }
        td:before {
            /* Now like a table header */
            position: absolute;
            /* Top/left values mimic padding */
            top: 6px; left: 6px; width: 45%; padding-right: 10px; white-space: nowrap;
        }
        /* Grants and Contracts table */
        table td:nth-of-type(1)::before { content: "Expense"; }
        table td:nth-of-type(2)::before { content: "2014"; }
        table td:nth-of-type(3)::before { content: "2015"; }
        table td:nth-of-type(4)::before { content: "2016"; }
    
        table tr:last-of-type td:nth-of-type(1)::before {content: "";}
    <table id="expenses">
    <thead>
    <tr><th>Expense</th><th>2014</th><th>2015</th><th>2016</th></tr>
    </thead>
    <tbody>
    <tr><td>Salaries</td><td>$85,256</td><td>$65,487</td><td>$94,626</td></tr>
    <tr><td>Publication costs</td><td>22,698</td><td>69,548</td><td>66,555</td></tr>
    <tr><td><strong>Total Expenses</strong></td><td><strong>$126,061</strong></td><td><strong>$169,013</strong></td><td><strong>$65,887</strong></td></tr>
    </tbody>
    </table>

    As discussed in the comments, I would personally prefer a different labeling because tables break with the usual ltr-reading paradigm, but that's of course up to your liking.

    The optimal/correct formatting (in my humble opinion) of your table would be the following:

    table {
        border-collapse: collapse;
        width: 100%;
        color: #444;
    }
    tr:nth-of-type(2n+1) {
        background: #eee none repeat scroll 0 0;
    }
    th {
        background: #696969 none repeat scroll 0 0;
        color: #fff;
        font-weight: bold;
    }
    th span{float:right}
    td, th {
        border: 1px solid #ccc;
        padding: 6px;
        text-align: left;
        vertical-align: middle;
    }
    /* responsive code */
    @media
    only screen and (max-width: 760px),
    (min-device-width: 768px) and (max-device-width: 1024px)  {
        /* Force table to not be like tables anymore */
        table, thead, tbody, th, td, tr {
            display: block;
        }
        /* Hide table headers (but not display: none;, for accessibility) */
        thead tr {
            position: absolute;
            top: -9999px;
            left: -9999px;
        }
    
        tr { border: 1px solid #ccc; }
        td {
            /* Behave  like a "row" */
            border: none;
            border-bottom: 1px solid #eee;
            position: relative;
            padding-left: 50%;
        }
        td:before {
            /* Now like a table header */
            position: absolute;
            /* Top/left values mimic padding */
            top: 6px;
            left: 6px;
            width: 45%;
            padding-right: 10px;
            white-space: nowrap;
        }
        /* Grants and Contracts table */
        table td:nth-of-type(1)::before { content: "2014"; }
        table td:nth-of-type(2)::before { content: "2015"; }
        table td:nth-of-type(3)::before { content: "2016"; }
    <table id="expenses">
    <thead>
    <tr>
    <th>Expense \ Year</th><th>2014</th><th>2015</th><th>2016</th>
    </tr>
    </thead>
    <tbody>
    <tr>
    <th>Salaries</th><td>$85,256</td><td>$65,487</td><td>$94,626</td>
    </tr>
    <tr>
    <th>Publication costs</th><td>22,698</td><td>69,548</td><td>66,555</td>
    </tr>
    <tr>
    <th><strong>Total Expenses</strong></th><td><strong>$126,061</strong></td><td><strong>$169,013</strong></td><td><strong>$65,887</strong></td>
    </tr>
    </tbody>
    </table>