- From: Bert Bos <bert@w3.org>
- Date: Thu, 19 Sep 2002 04:41:03 +0200
- To: www-style@w3.org
On Wednesday 18 September 2002 13:54, George Lund wrote:
> It would be nice to have another possible value for list-style-type,
> namely 'collapsible'. This would mean that browsers implementing
> this suggestion could display the list in a collapsible tree-view
> style.
>
> This would eliminate the need for a lot of JavaScript, and would mean
> that what is a relatively common GUI widget could be specified by
> authors with minimal fuss. It would improve HTML coding, because
> such lists could be marked up with the <ul> element for non-CSS3
> browsers.
I have a proposal...
[Long intro, can be skipped:]
Collapsing text is an old idea. It was used in the earliest hypertext
systems. Indeed, there are people that believe that expanding text
should be the normal mode for hypertext, with the Web's current
behavior of replacing one text with another reserved for exceptional
situations.
Of course, it should not just apply to lists, although lists are a very
common case.
I've been thinking about this a bit and I have some ideas, but it is
hard to come up with something that is at the same time easy to specify
for the common cases and still flexible enough for less common ones.
First, I'd like to be able to apply expanding/collapsing to any element
in a document, but also to a link. In the latter case, clicking will
put the linked document in place of the link. (Amaya can do that, to a
limited extent, via its "make book" option.) The two ways of expanding
do not necessarily have to use the same properties, though sharing some
would be good.
Then, when an element is collapsed, I'd like to be able to say what is
shown in its place. That might be an icon, the contents of a TITLE
attribute, a certain child element of the collapsed element, etc.
Since the CSS WG is already planning to extend the 'content' property to
apply to elements (it applies only to ':before' and ':after' in CSS2),
we could use that to specify what is shown instead of the normal
contents.
It looks, then, that we have two states for each element and for both
states we can set properties, including the 'content' property. But if
we make the 'content' property sufficiently general, the "collapsed"
state might actually have more text than the "expanded" state. Maybe we
should forget about "expanded" vs "collapsed" and just say that every
element has two states. But why two? Why not more?
Taking the lead from DSSSL ("modes") and XSL-FO ("multi-fo"), we can
make every element have as many states as we want. Let's simply number
them, to avoid having to invent names, to make cascading easier and to
create an implicit ordering. By default, the element is in state 0.
Clicking it moves it to state 1, if defined, otherwise to the next
state that is. If there are no more states, the next click moves back
to state 0.
A click only affects the nearest enclosing element with states, not all
ancestor of that element. There is still a problem if an element has
multiple states and is also the source anchor of a hyperlink: what does
the click do? Let's assume for now that it advances the state. (We may
need a separate property to say that loading a new document takes
priority over advancing to the next state.)
[Start reading again here:]
Let's say I want a DIV to be collapsed to an icon that has to be clicked
to show the actual DIV contents. This is the style that replaces the
DIV by an image:
DIV {content: url(mypic.png)}
And this is state #1, which the user reaches by clicking the element in
state #0:
DIV:1 {content: normal}
Another example. I want an IMG to show the image initially, then the ALT
text on the first click and the LONGDESC target on the second click:
IMG {content: target(SRC)}
IMG:1 {content: attr(ALT)}
IMG:2 {content: target(LONGDESC); display: inline-block}
I added 'inline-block', because the longdesc is probably more than one
paragraph. Note that 'attr()' inserts the contents of the attribute,
but 'target()' inserts whatever the attribute points to (assuming it
can be interpreted as a URL reference).
Here is a collapsing list. It starts in collapsed state. In the
collapsed state, it shows the UL's TITLE attribute:
UL:0 {
display: list-item;
list-style: url(plus.png) disc;
content: attr(TITLE) }
Since there is one explicit state, there are two states in total. The
other state, say #1, matches the rule for generic UL (which is not
shown, but presumably does the normal thing for lists).
Note that rules for UL apply to a UL in any state, while UL:0 applies
only to state #0. It is slightly more involved than saying, e.g., 'UL
{display: collapsed}' or some such, but it is more flexible.
Here is a hyperlink source anchor, that, when clicked, makes room for
the target to be displayed inline:
A[HREF]:1 {content: target(HREF); display: block}
And this makes it work if we neither know the name of the source anchor
nor which attribute holds the URL (but, we assume, the browser knows
the document type and can fill in the blanks):
*:link:1 {content: target(); display: block}
And here is a challenge: given this HTML 2.0 fragment:
<section>
<h>The section title</h>
<p>...
</section>
how do I collapse the section to show only the heading?
Here is a solution, but it is not a very intuitive one:
section:0 > h {display: block}
section:0 > * {display: none}
Here is an interesting test case:
body {color: magenta}
section:0 p:0 {color: red}
section:0 p:1 {color: blue}
section:1 p:0 {color: green}
section:1 p:1 {color: black}
If the p is red, how many times and where do you have to click to make
it magenta?
Bert
--
Bert Bos ( W 3 C ) http://www.w3.org/
http://www.w3.org/people/bos/ W3C/INRIA
bert@w3.org 2004 Rt des Lucioles / BP 93
+33 (0)4 92 38 76 92 06902 Sophia Antipolis Cedex, France
Received on Wednesday, 18 September 2002 22:41:12 UTC