See also the index of all tips.
The two tables below can be shown in full or with one or more columns omitted. This page demonstrates two methods to switch between the different views. Either
Item | Info | Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
First | 1st | 56 | 28 | 85 | 24 | 67 | 27 | 67 | 20 | 21 | 74 | 45 | 48 |
Second | 2nd | 34 | 28 | 84 | 74 | 95 | 77 | 21 | 31 | 54 | 34 | 84 | 47 |
Item | Info | Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
First | 1st | imo | boo | ba | fie | ro | ore | yu | ek | quo | phe | lei | ats |
Second | 2nd | eu | eo | suh | ohn | hye | lef | wa | bu | orf | ir | soi | se |
Usually, to hide an element from view, you use the 'display' property and set it to 'none'. But CSS also has a property called 'visibility', which hides elements in a different way. In particular, we use 'visibility: collapse' here, which is designed especially for hiding table columns and rows.
With this method, the layout of the table is actually computed with the collapsed column still present, but that column is then not displayed. The effect is to leave unused space at the right edge of the table.
The 'collapse' value is meant for interactive use: at first all columns are visible, then something (we'll see below what) changes the value of 'visibility' on some columns from 'visible' to 'collapse'. Those columns disappear, but the contents of the remaining columns is not changed in any way. The columns only move closer together. When the value changes back to 'visible', the collapsed columns reappear and the other columns move back, again without changing the layout of any cells. That not only makes the process quick, it also helps your eyes to recognize each column after it moved.
To put style rules on table columns, there have to be elements
in the document that represent those columns. In HTML, those are
the <col>
elements. The HTML code for the
tables above looks like this:
<table> <col> <col> <col class=m01> <col class=m02> <col class=m03> <col class=m04> <col class=m05> <col class=m06> <col class=m07> <col class=m08> <col class=m09> <col class=m10> <col class=m11> <col class=m12> <thead> <tr> <th>...
The class attributes are there to make it easier to write the style rules. One of those style rules is:
col.m04 { visibility: collapse }
This folds away any columns with class m04. Next we need a way to toggle this rule on and off.
The first method involves alternative style sheets (see the article “Alternative style sheets”). This page has no less than eleven alternative styles called “View for…”, corresponding to eleven different ways to display the tables. The HTML code looks like this:
<link rel="alternate stylesheet" href="foldingstyle/month02.css" title="View for February"> <link rel="alternate stylesheet" href="foldingstyle/month03.css" title="View for March"> <link rel="alternate stylesheet" href="foldingstyle/month04.css" title="View for April"> ...
Each of those alternative styles is only two lines: a line to import the default style sheet, and a line to collapse the relevant columns. E.g., here is the complete month04.css file. It hides the .m01, .m02 and .m03 columns, i.e., the columns for January, February and March:
@import "../../CSS/w3c-2010/main.css"; .m01, .m02, .m03 { visibility: collapse }
Alternative style sheets are an easy method. As you see, the style rules are short and simple. On the other hand, switching between styles is typically not very quick, because the user has to select a style from a menu. That involves a number of mouse movements or several key presses.
The second method relies on the ':target' selector. It selects the (at most one) element in a document that is the target of the link that you followed to reach that document. (See the article “A tabbed interface” for more about ':target'.)
We can use that selector here to style the table differently based on which element is the current target. Then we only have to provide links to those targets and with every click on a link, a different element becomes the target and a different style applies.
We need as many potential targets in the document as we have
different styles, and hyperlinks to those targets. This page uses
empty <div>
elements as targets and puts the
<a>
elements inside the column headers:
<div class=hack id=view02></div> <div class=hack id=view03></div> <div class=hack id=view04></div> ... <table> ... <th><a title="Click to hide earlier columns" href="#view02">Feb<a> <th><a title="Click to hide earlier columns" href="#view03">Mar<a> <th><a title="Click to hide earlier columns" href="#view04">Apr<a> ...
(The title attributes explain a bit what happens for each link.)
These extra <div>
and <a>
elements have no other function than to support
the style and that is why I call this method a hack. In some future
extension of CSS there will probably be a way to toggle the style
of elements directly (see below).
The style rules are a bit complicated. Here is one of them:
#view02:target ~ * .m01 { visibility: collapse }
It says to collapse the element .m01 if it is a descendant of an element that is itself a following sibling of the element that has the ID “view02” and is the current target. See the “view.css” style sheet for the full set of rules. (There are 66 of them for this particular example.)
These rules allow the reader to show and hide columns by clicking on column headers. An extra advantage is that each different way to display the tables has its own URL. E.g., http://www.w3.org/Style/Examples/folding#view06 opens the page with the columns Jan, Feb, Mar, Apr and May already hidden.
Normally, when you follow a link, the browser scrolls the window such that the target element is displayed near the top. In this case the targets are hidden from view:
.hack { display: none }
No specification defines what the browser should scroll to in that case, but hopefully it simply doesn't scroll at all.
As this page uses two different methods to fold columns, one of the two must take precedence. In this case, the alternative styles win: if you selected the “View for June” style and then click on the August column, the June column will not collapse.
It is easy, however, to reverse the precedence. The link to the style sheet with the ':target' rules looks like this:
<link rel=stylesheet href="foldingstyle/view.css" title="Main">
which means the style sheet is only loaded together with other styles called “Main” and not with any of the styles called “View for…” Just removing the title attribute is enough to make the style sheet apply no matter what alternative style is loaded.
This page shows two tables whose columns fold and unfold the same way and that is to illustrate the limitations of the two methods: It would in fact be impossible to collapse columns in the two tables independently.
As said above, the method with the ':target' selector requires the addition of extra elements in the source. Also, if you want to use hyperlinks for other purposes, e.g., for a table of contents, then you cannot use them for folding tables anymore. (On the other hand, you could build a similar trick with the ':checked' selector instead of the ':target' selector. That frees up the hyperlinks, but has other constraints. Another page shows an example with ':checked'.)
For these reasons, CSS should eventually get a feature to toggle directly between two or more styles for an element, without needing explicit hyperlinks.
As of July 2011, the CSS working group has not yet published a Working Draft with such a feature, but there are ideas. One such idea is to introduce a pseudo-class ':alternative'. A rule such as
ul:alternative { content: "+" }
would mean that <ul>
elements can be
toggled between two states and when the user toggles the element to
the second, alternative state, a “+” is displayed instead of the
contents of the element.
Created 7 July 2011;
Last updated Wed 06 Jan 2021 05:40:49 AM UTC