Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

CSS

table, fixed header, scrolling body, how to make the header columns same as body columns?

I've boiled this down to the least html and css I can to illustrate. Want each header to be over the column it is the title for and to have the header same width as the column. I've got the scrolling table working but haven't found a solution to match the headers to the columns.

Perhaps someone here knows the secret sauce? HTML and CSS only please.

Below are the bare bones html and css. Comments are in the css. It pretty much seems to come down to the table selector. You'll see what I've tried in the css comments. Would love a solution.

Thanks.

<!DOCTYPE html>
<html lang="en">

    <head>
        <title>Scrolling Table Dev Work</title>
        <meta charset="utf-8">
        <link rel="stylesheet" type="text/css" href="table_scratch.css">
    </head>

    <body>
        <div class="vp_top">
            Hello World this is div class="vp_top"
        </div>
        <div class="vp_main">
            this is div class="vp_main"
            <div class="sidebar">
                this is div class="sidebar"
            </div>
            <div class="content">
                this is div class="content" the table is in here
                <table>
                    <thead>
                        <th>Col 1</th>
                        <th>Col 2</th>
                        <th>Col 3</th>
                        <th>Col 4</th>
                    </thead>
                    <tbody>
                        <tr><td>a</td><td>b</td><td>c</td><td>d</td></tr>
                        <tr><td>aa</td><td>bb</td><td>cc</td><td>dd</td></tr>
                        <tr><td>eee</td><td>fff</td><td>ggg</td><td>hhh</td></tr>
                        <tr><td>i</td><td>jjjj</td><td>kkkkkkkk</td><td>mmmmmm</td></tr>
                        <tr><td>1</td><td>2</td><td>3</td><td>4</td></tr>
                        <tr><td>5</td><td>6</td><td>7</td><td>8</td></tr>
                        <tr><td>9</td><td>0</td><td>11</td><td>13</td></tr>
                    </tbody>
                </table>
            </div>
        </div>
        <div class="vp_bottom">
            this is div class="vp_bottom"
        </div>
    </body>
</html>
* {
    margin: 0;
    padding: 0;
}

/* display: flex required so sidebar and content div allign horizontal             */
.vp_main {
    display: flex;
    border: 2px solid #700000;
}

.vp_top,
.vp_sidebar,
.content,
.vp_bottom {
    border: 2px solid #000055;
}

/* with no display statement the 1st col title appears centered over entire table   */
/*      and the remaing titles are to right of vertical scroll bar                  */
/* with "display: block" column titles are all adjacent beginning at left of table  */
/*      in other words, they don't line up over the columns                         */
/* with "display: flex; flex-direction: column;" the column titles display the same */
/*      as when "display: block" is used                                            */
/* WHAT needs to be done so column titles allign with the columns??                 */
table {
    display: block; 
/*
    display: flex;
    flex-direction: column;
*/
}

/* display: block required so overflow works and scrollbar is displayed regardless  */
/*      display setting for table                                                   */
tbody {
    height: 100px;
    overflow-y: scroll;
    display: block;
}

2 Answers

Steven Parker
Steven Parker
229,967 Points

You could give your columns an explicit width.

While this does not cause the table to to size itself based on the content, one way to accomplish your goal with minimal changes to your existing code would be by assigning explicit column widths.

For example:

th, td { width: 100px; }

All columns would not need to be the same, you could also set them differently:

th:nth-child(-1n+2), td:nth-child(-1n+2) { width: 40px; }
th:nth-child(3), td:nth-child(3) { width: 66px; }
th:last-child, td:last-child { width: 80px; }

Also, your thead should have a tr element, enclosing the th cells. This has nothing to do with the display, it's just the requirement for thead.

Steven Parker , didn't mean each column the same. Meant each header right fit for column it is the title for. In other words set width of each column dependent on widest value (be that title in the header or value in a cell) in the column.

I noted after posting that tr was missing in my thead. However adding the tr has no effect on the display. With/without tr around the th's the thead displays the same.

Found guidance at this link that is supposed to do the trick but so far, not working for me. http://stackoverflow.com/questions/37272331/html-table-with-fixed-header-and-footer-and-scrollable-body-without-fixed-widths

Steven Parker
Steven Parker
229,967 Points

Explicit widths don't need to be the same. I added another example to my answer above. :arrow_heading_up:

I noticed that the auto-sizing example does not use block display mode.

Just to be clear, I am trying to avoid any explicit sizing of the columns. I would prefer that the content (data or column title whichever is widest) cause the column width to be dynamically set.

Had not noted the detail about block display that you mention. Still trying to get it to work. Have found several examples that work if taken exactly as posted. And had success with one table on one page I built. I believe there must be inheritances affecting the tables though because my attempts to graft the html and css onto existing pages fail.

If (when) I get it worked out will update what's posted here with what I get to work.