Repeating table header when splitting via column-count
Asked Answered
I

4

9

I am outputting a list of products in Magento, as a simple list wrapped in a table.

As this list can get quite long (100 products+), I've used the ideas from here to automatically split the table into two, to help with readability etc.

    #container {
    column-count:2;
    -moz-column-count:2;
    -webkit-column-count:2;
    }

However, this method just flows the table into 2 columns. Does anyone know how I can get the table header to also repeat in the second column?

Using the linked answer, you can see this fiddle which shows where I am at: http://jsfiddle.net/J3VB5/51/

Insignificant answered 22/2, 2015 at 20:1 Comment(1)
This seems like a design problem more than a technical problem. You should probably get yourself an all-encompassing header as opposed to doing backflips to circumvent the column convention.Windsor
S
4

Would an extra markup + CSS solution help?

Duplicate your header (with repeated columns) right above your current container.

<div id="container1">
    <table id="tbl">
        <thead>
            <tr>
                <th>header1</th>
                <th>header2</th>
            </tr>
            <tr>
                <th>header1</th>
                <th>header2</th>
            </tr>
        </thead>
    </table>
</div>
<div id="container">
    <table id="tbl">
     ...

Hide the actual header in your table with CSS trickery

<table id="tbl">
    <thead>
        <tr class="dummy">
            <th><span>header1</span></th>
            <th><span>header2</span></th>
        </tr>
     ...

CSS

#container1, #container {
    column-count:2;
    -moz-column-count:2;
    -webkit-column-count:2;
}

.dummy > th > span {
    display: block;
    height: 0;
    opacity: 0;
}

The solution is admittedly hacky. It works pretty well even with long header content.

Fiddle - http://jsfiddle.net/uqz76rL1/ Fiddle with a long header - http://jsfiddle.net/3343Lg4x/

However it will NOT work if your td content is what is driving the table layout as is obvious from this fiddle - http://jsfiddle.net/kezztx55/

So, if you have a fixed table layout (or if you can put in a dummy row in container1 containing the content that drives your column width) it will work.

Servia answered 5/6, 2015 at 12:51 Comment(0)
F
1

I'll admit this took a while, but it works. So as an alternative to potatopeelings's answer, I present this CSS monster:

#container {
    column-count:2;
    -moz-column-count:2;
    -webkit-column-count:2;
    
}
tbody tr:nth-child(7n+1) td{
    white-space: pre;
}
tbody tr:nth-child(7n+1) td:first-child:before {  
    content:"Header 1 \A";
}
tbody tr:nth-child(7n+1) td:last-child:before {  
    content:"Header 2 \A";
}
tbody tr:nth-child(7n+1) td:before { 
    background-color:red;
    height:20px;
    width:100%;
}
<div id="container">
<table id="tbl">
<tbody>
    <tr>
        <td>aaaa</td>
        <td>bbbb</td>
    </tr>
    <tr>
        <td>aaaa</td>
        <td>bbbb</td>
    </tr>
    <tr>
        <td>aaaa</td>
        <td>bbbb</td>
    </tr>
    <tr>
        <td>aaaa</td>
        <td>bbbb</td>
    </tr>
    <tr>
        <td>aaaa</td>
        <td>bbbb</td>
    </tr>
    <tr>
        <td>aaaa</td>
        <td>bbbb</td>
    </tr>
    <tr>
        <td>aaaa</td>
        <td>bbbb</td>
    </tr>
    <tr>
        <td>aaaa</td>
        <td>bbbb</td>
    </tr>
    <tr>
        <td>aaaa</td>
        <td>bbbb</td>
    </tr>
    <tr>
        <td>aaaa</td>
        <td>bbbb</td>
    </tr>
    <tr>
        <td>aaaa</td>
        <td>bbbb</td>
    </tr>
    <tr>
        <td>aaaa</td>
        <td>bbbb</td>
    </tr>
    <tr>
        <td>aaaa</td>
        <td>bbbb</td>
    </tr>
    </tbody>
</table>    
</div>

This relies on several factors though.

Firstly, the current layout only works with 2 columns (it can work with more, just tweak a few things).

The main point: you need to have a defined maximum per column. Now I'm guessing you probably do have a maximum, however you did not specify one so I'm hoping you do.

You'll notice that I deleted the thead tags, and to define your header titles, you'll need to use the content property in the css. The "\A" and white-space: pre; are vital.

Flutterboard answered 9/6, 2015 at 21:34 Comment(0)
A
1

I found you can actually repeat the <thead> in Chrome only by adding break-inside: avoid; to the style (see https://codereview.chromium.org/2021703002/#ps20001). Apparently the print media type relies on this attribute to repeat the <thead> on each page.

#container {
    column-count:2;
    -moz-column-count:2;
    -webkit-column-count:2;

}

#tbl thead {
    break-inside: avoid;
}
<div id="container">
    <table id="tbl">
        <thead>
        <tr>
            <th>header1</th>
            <th>header2</th>
        </tr>
        </thead>
        <tr>
            <td>aaaa</td>
            <td>bbbb</td>
        </tr>
        <tr>
            <td>aaaa</td>
            <td>bbbb</td>
        </tr>
        <tr>
            <td>aaaa</td>
            <td>bbbb</td>
        </tr>
        <tr>
            <td>aaaa</td>
            <td>bbbb</td>
        </tr>
        <tr>
            <td>aaaa</td>
            <td>bbbb</td>
        </tr>
        <tr>
            <td>aaaa</td>
            <td>bbbb</td>
        </tr>
        <tr>
            <td>aaaa</td>
            <td>bbbb</td>
        </tr>
        <tr>
            <td>aaaa</td>
            <td>bbbb</td>
        </tr>
        <tr>
            <td>aaaa</td>
            <td>bbbb</td>
        </tr>
        <tr>
            <td>aaaa</td>
            <td>bbbb</td>
        </tr>
        <tr>
            <td>aaaa</td>
            <td>bbbb</td>
        </tr>
        <tr>
            <td>aaaa</td>
            <td>bbbb</td>
        </tr>
        <tr>
            <td>aaaa</td>
            <td>bbbb</td>
        </tr>
    </table>    
</div>

However, it seems the <thead /> only repeats if column-count≤4.

This trick doesn't work on Firefox (column-count doesn't break tables properly) or Safari (<thead /> doesn't repeat even in print mode).

Adest answered 17/11, 2022 at 20:16 Comment(2)
AFAICT the thead repeats depending on the number of rows. If you add more rows then it will repeat the head on all columns. It appears as long as every column has at least 4 rows they will all get a repeated theadGeorgianngeorgianna
@Georgianngeorgianna Interesting discovery! Thanks!Adest
J
0

Basic easy js solution

This works without having to change the existing HTML markup.

You can just copy the complete table, and display the copy next to it. Then iterate the TR elements and hide upper half elements in the first table and, and hide the lower half elements in the cloned table.

var myDiv = document.getElementById("container");
var myTable = document.getElementById("tbl");

var newTable = document.createElement("table");
myDiv.appendChild(newTable);

newTable.setAttribute("id", "newTable");
newTable.innerHTML =  myTable.innerHTML;

var rows = myTable.getElementsByTagName("tr");
var rowsCopy = newTable.getElementsByTagName("tr");

//start from 1 instead of 0 because first row are the headers
for(var i=1;i<rows.length;i++)
{
    if(i>(rows.length/2))
    {
        rows[i].style.display = "none";
    }else
    {
        rowsCopy[i].style.display = "none";
    }
}

Working JSFiddle here: http://jsfiddle.net/J3VB5/90/

This works with having both even and odd number of rows, as well as more columns.

Janusfaced answered 10/6, 2015 at 10:18 Comment(5)
See jsfiddle.net/J3VB5/88 - yours is making a simple mistake. Do like the idea though!Slander
you mean the ordering left right ? wouldn't call that a mistake since it wasn't asked and the css could still adjust it ...but replace smaller then with bigger then if(i>(rows.length/2)) to fix it ;) jsfiddle.net/J3VB5/89Janusfaced
It seems obvious to me that you'll want your table to go from left to right. You don't read right to left columns, or blog posts do you?Slander
Seems perfect - I'll wait one more day, and if no better answers pop up, I'll award the bounty to you :-).Slander
hi guys, sorry - seems like discovered by question sometime after I wrote it!! I'll see if I can test your solution soon. But if someone else proves it works - then yes, bounty to you! :)Insignificant

© 2022 - 2024 — McMap. All rights reserved.