Daniel Pietzsch

Personal blog. Mostly photos.

Horizontally scrolling table with fixed headings

For my Focal Length Equivalent utility, I created a alternative view for when you don’t have JavaScript enabled (as you should, if you can).

Instead of dynamically showing the conversion based on the position of the range slider input element, I simply show a good old table with calculated equivalents at pre-defined focal lengths.

I wanted this table to list the focal lengths vertically – with one film- or sensor-format on one row – so you can easily parse the result. As such a table gets easily too wide for the parent elements container, I wanted

  1. the table to be scrollable horizontally and
  2. have the format name headings keep their position, so that you never lose track of which row represents which format.

Here’s the simplified table markup:

<figure><table><tbody><!-- ... --><tr><th scope="row">35mm</th>
        <td>10 mm</td>
        <td>16 mm</td>
        <td>24 mm</td>
        <td>28 mm</td>
        <td>35 mm</td>
        <td>50 mm</td>
        <td>85 mm</td>
        <td>100 mm</td>
        <td>135 mm</td>
        <td>200 mm</td>
        <td>300 mm</td>
        <td>500 mm</td>
      </tr><!-- ... --></tbody></table></figure>

The “scrolling” bit is easily done: simply put a overflow-x: scroll; on the table’s container element, which in my case is a <figure> element (a <div> or any other block element would also do of course, if the <figure> semantic doesn’t work for you):

figure {
  overflow-x: scroll;
}

In order for the film-format name headings to keep their position, I resorted to a fairly new value of the CSS position property: sticky. I added this to the th selectors, in combination with left: 0; so the headings stay at their original positions:

figure table tr th {
  position: sticky;
  left: 0;
  // you might also want a bg color, so the th covers the table
  // that scrolls through underneath
  background-color: white;
}

You can take a look at this when you go to the tool and disable JavaScript in your browser. Or you can simply look at this table here:

Micro 4/35 mm8 mm12 mm15 mm18 mm26 mm44 mm52 mm70 mm104 mm156 mm260 mm
APS-C7 mm11 mm16 mm19 mm23 mm33 mm57 mm67 mm90 mm133 mm200 mm333 mm
35mm10 mm16 mm24 mm28 mm35 mm50 mm85 mm100 mm135 mm200 mm300 mm500 mm
6x4.516 mm26 mm39 mm45 mm56 mm81 mm137 mm161 mm217 mm322 mm483 mm805 mm
6x618 mm29 mm44 mm51 mm64 mm92 mm155 mm183 mm247 mm366 mm548 mm915 mm
6x720 mm32 mm48 mm56 mm71 mm101 mm171 mm202 mm272 mm404 mm604 mm1009 mm
6x822 mm35 mm53 mm62 mm77 mm110 mm187 mm220 mm297 mm440 mm660 mm1100 mm
6x923 mm37 mm56 mm65 mm82 mm117 mm198 mm233 mm315 mm467 mm700 mm1167 mm
4x536 mm57 mm85 mm99 mm124 mm177 mm301 mm354 mm478 mm708 mm1061 mm1769 mm
8x1071 mm113 mm170 mm198 mm248 mm354 mm601 mm707 mm955 mm1415 mm2122 mm3537 mm

Here’s the full CSS.