Monday, June 6, 2016

Scrolling, Scrolling

When you're short on real estate on your web page, one of the easiest things to do is shorten the height of an element and make it scrollable. This works especially well with a table, but if you're not careful, the header of the table will scroll along with all the content, making the column headers invisible and rendering the table more difficult to use. Fortunately, fixing this problem is relatively easy - as you'll see below.

First, you really should start with good, clean, semantic markup. That means a THEAD tag and a TBODY tag. So we'll start with something like the following...

HTML
<table class="scrollable">   <caption>10 of the world's busiest airports</caption>   <thead class="thead">     <tr>       <th>Country</th><th>City</th><th>Activity</th><th>Name</th><th>Latitude</th><th>Longitude</th>     </tr>   </thead>   <tbody>     <tr><td>US</td><td>ATL</td><td>68343</td><td>Hartsfield Jackson Atlanta International</td><td>33.636719</td><td>-84.428067</td></tr>     <tr><td>US</td><td>ORD</td><td>59692</td><td>Chicago O'Hare International</td><td>41.978603</td><td>-87.904842</td></tr>     <tr><td>US</td><td>DFW</td><td>56496</td><td>Dallas Fort Worth International</td><td>32.896828</td><td>-97.037997</td></tr>     <tr><td>US</td><td>LAX</td><td>51396</td><td>Los Angeles International</td><td>33.942536</td><td>-118.408075</td></tr>     <tr><td>CN</td><td>PEK</td><td>48226</td><td>Capital International</td><td>40.080111</td><td>116.584556</td></tr>     <tr><td>US</td><td>CLT</td><td>44583</td><td>Charlotte Douglas International</td><td>35.214</td><td>-80.943139</td></tr>     <tr><td>US</td><td>DEN</td><td>44438</td><td>Denver International</td><td>39.861656</td><td>-104.673178</td></tr>     <tr><td>US</td><td>LAS</td><td>41164</td><td>McCarran International</td><td>36.080056</td><td>-115.15225</td></tr>     <tr><td>US</td><td>IAH</td><td>39808</td><td>George Bush Intercontinental</td><td>29.984433</td><td>-95.341442</td></tr>     <tr><td>GB</td><td>LHR</td><td>37680</td><td>London Heathrow</td><td>51.4775</td><td>-0.461389</td></tr>   </tbody> </table>


Next, we need to adjust the CSS to override the default styles.

First, make sure that you have at least some specificity, otherwise all your tables, even those that take up very little vertical space will be affected. You'll notice from line 1 of our HTML that we're doing this by adding scrollable as a class on the table.

Second, we're adjusting both the TBODY and the TR tags to override the default. We're going to add a rule for overflow (on the y-axis) on the TBODY and for the height. A note about the height - the default line-height for a table row is 1.5 em, so if you don't adjust the line-height, using a multiple of 1.5 will give you a full line at the bottom - assuming you don't have borders around the TR or TD. In the example, I'm using a 6em height, which shows 4 full lines.

One might think that setting the height and overflow-y on the TBODY is enough, but alas it is not. The display mode is still table, which overrides the height specification. To correct this, I'll change the display to block. Unfortunately, that has the sad side-effect of rendering the cells within the table using an auto width. I'll correct this - in part by setting the display on the TR to table - and in part by setting the width on each of the columns. This gives us the CSS below.

CSS
table.scrollable > tbody {   display:block;   height:6em;   overflow-y:scroll; } table.scrollable > thead, table.scrollable > tbody tr {   display:table; } table.scrollable th:nth-child(1), table.scrollable td:nth-child(1) {   width:5.5em; } table.scrollable th:nth-child(2), table.scrollable td:nth-child(2) {   width:4em; } table.scrollable th:nth-child(3), table.scrollable td:nth-child(3) {   width:5.5em; } table.scrollable th:nth-child(4), table.scrollable td:nth-child(4) {   width:17em; } table.scrollable th:nth-child(5), table.scrollable td:nth-child(5) {   width:5.5em; } table.scrollable th:nth-child(6), table.scrollable td:nth-child(6) {   width:6.5em; }

If you would rather have evenly-spaced columns, you can set the width on the TR within the TBODY to 100% and change the table-layout to fixed, e.g., change line 8 in the CSS to display:table; table-layout:fixed; width:100%; and remove lines setting width on all columns.

That's it. Your table is now scrollable with a stationary header.
10 of the world's busiest airports
CountryCityActivityNameLatitudeLongitude
USATL68343Hartsfield Jackson Atlanta International33.636719-84.428067
USORD59692Chicago O'Hare International41.978603-87.904842
USDFW56496Dallas Fort Worth International32.896828-97.037997
USLAX51396Los Angeles International33.942536-118.408075
CNPEK48226Capital International40.080111116.584556
USCLT44583Charlotte Douglas International35.214-80.943139
USDEN44438Denver International39.861656-104.673178
USLAS41164McCarran International36.080056-115.15225
USIAH39808George Bush Intercontinental29.984433-95.341442
GBLHR37680London Heathrow51.4775-0.461389


Happy coding.

No comments:

Post a Comment