- From: Tab Atkins Jr. <jackalmage@gmail.com>
- Date: Mon, 20 Apr 2009 11:51:33 -0500
- To: Giovanni Campagna <scampa.giovanni@gmail.com>
- Cc: www-style <www-style@w3.org>
On Mon, Apr 20, 2009 at 11:05 AM, Giovanni Campagna <scampa.giovanni@gmail.com> wrote: > 2009/4/20 Tab Atkins Jr. <jackalmage@gmail.com>: >> Greetings, list. >> >> [...] >> >> >> Problems in Advanced Layout Module tabbed layout >> ================================================ >> The draft is no longer up, so I'll summarize how the proposal worked. >> >> display:card elements were placed into a display:stack container, >> defining their stack explicitly in the markup. An element within the >> card was given display:tab. This causes it to be pulled out of the >> card's display, and used to fill the automatically generated tab >> display docked on one side of the stack. >> >> There are several weaknesses with this draft: >> >> 1. It was a slight abuse of display (display:stack and display:card >> elements were treated as display:block by default). > > Not really. It was display-model:stack (this element, while being > whatever, block/inline/list-item/table-cell, displays only one of its > children) and display-role:card (this element, while displaying its > content as whatever, block-inside/math/svg/table, takes the role of a > card in respect to his parent). I see no reason why an element couldn't be both a card and a table. Using display in this manner (even with the separation of role and model) forces you into using container elements if you do anything nontrivial. >> 2. It forced the designer to put the card's stack relationship >> explicitly in the markup. In many basic tabbed displays this is fine, >> but there can be legitimate reasons to *not* do this. > > Not really, again. You're not required to use display:tab, as UAs are > still required to show cards that matches the :target pseudo-class. > You just need an hash-link. ?_? That statement said nothing about tabs. It was about cards and stacks. >> 3. The tabs were extremely limited. They must come from the card's >> descendants, they must be next to the card stack, and their display is >> essentially browser chrome, limiting the author's ability to change >> the style of the tabs. > > If you want to pull tabs out of the card, you're limited (not really, > once more, because you can reset the "appearance" and set what you > want on the tab element). If you don't want to use display:tab, you > don't need. The advantage of this is that you don't need hash-links. If you don't use display:tab, you can't indicate which card is currently active. The hash-links are stateless in this respect. >> 4. Tabs and cards are forced into a one-to-one relationship, >> preventing an author from creating complex layouts like I outlined >> above in my example. > > No, unless you want the default, native-looking and link-free, tab > layout. You can have multiple links with the same href. That's what I meant. Hash-links don't respond to the state of the card they're activating. You have to use display:tab to get that. >> 5. Accordions are completely impossible, even though they are >> functionally identical to a tabbed layout. > > Accordions are different, because they don't need tabs, just cards. What? Accordions certainly need tabs. What do you think the things you click on to expand a given section are? Are you perhaps thinking of something different than me? I'm talking about markup like this: <div class="accordion"> <h1>Section one</h1> <p>foo</p> <h1>Section two</h1> <p>bar</p> </div> Where "Section one" and "Section two" are always displayed, and you can click on them to show the "foo" or "bar" elements. > And stacked cards are achievable with current CSS support,tweaking a > bit the :target, for example with the following markup (designed to > degrade) > <section id="tab-1"><h1><a href="#tab-1">Tab > Title</a></h1><p>content</p></section> > you can have an accordion using > section:not(:target) > :not(h1:first-child) { display:none; } Indeed, that's perfectly possible, just as I illustrated that tabbed layouts are possible with current CSS. However, you can only have a single accordion per page (to be precise, all the accordions will act like one big distributed accordion) and if you try to use a hash-link for anything else on the page it will close the accordion. In other words, it suffers from the exact same problems that I outlined for my pure-CSS tabbed display. In trivial cases it's more-or-less usable, but it's not robust. >> A Proposal for a Tabbed Layout >> ============================== >> My proposal takes the flexibility of JS-based tabbed layouts and >> marries it to the simplicity and rigor that CSS can bring. It >> requires only a single new property and a handful of pseudoclasses. >> No pseudoelements or new values for existing properties are needed. >> It revolves around the use of hash-links and ids, but without leaning >> on the :target pseudoclass and with significant intelligence to help >> in styling. >> >> New Property: card-stack >> ------------------------ >> Values: none | <string> >> Initial: none >> Applies to: all elements >> Inherited: no >> >> The card-stack property identifies an element as a card in a tabbed >> layout, and defines the stack it belongs to. Only a single card (the >> 'active' card) from a given stack is displayed at a time - the rest of >> the cards in the stack are treated as display:none. > > I don't really believe we need card-stack, we are fine with > display-model:stack and display-role:card. If you want, you can still > move content in the stack element (XSL-T or Named Flows) My entire argument is that we *aren't* fine with the old display:stack and display:card. They're too limiting, sort of hacky, and require too much magic. XSLT transforms the document *before* CSS gets to it (you may be thinking of XBL2). Named Flows, while still a pet project, is currently nothing more than a dream. I think this can be defined well without it. >> A card is made 'active' by either it or one of its descendants being >> expressly targetted by a hash-link. Once a card is 'active', it >> remains 'active' until another card in the same stack is made >> 'active'. Cards in other stacks can be made 'active' without >> affecting cards in any other stack. > > Ok, but in a different way: "navigating to a different fragment > identifier should not change the currently active card in a different > stack". That's a good way to phrase it. > And I don't like that descendants can raise the card, I prefer > sticking with the card element itself. Uh, why? If you target an element, you expect the display to scroll to it. Inactive tabs aren't explicitly hidden, just sort of 'unavailable' at the moment. >> Any card with a string value for card-stack matches the pseudoclass >> :card. Currently active cards also match the :active-card >> pseudoclass. ((Is an :inactive-card pseudoclass desirable? It's not >> necessary, but it may make things slightly easier - you won't have to >> set inactive properties with :card and then explicitly override them >> with :active-card. It would also make defining the UA defaults easier >> - just say ":inactive-card{display:none !important;}". Alternately, >> drop :card and just use :active-card and :inactive-card.)) > > I prefer :card and :active:card (that is, both :active and :card > pseudoclasses). :inactive-card is the same as :card:not(:active) Doesn't work. It means that a card is only active *while you are manipulating elements inside of it*. It would be impossible to use multiple stacks of cards. Hell, it would be impossible to have *one* stack of cards, with a card visible while you're interacting with the non-tabbed part of the page. >> Any link which is targetting a card on the page is considered a 'tab', >> and will match the :tab pseudoclass. A link targetting a currently >> active tab will also match the :active-tab pseudoclass. ((Again, do >> we want an :inactive-tab pseudoclass instead of/in addition to the >> :tab pseudoclass?)) Links targetting descendants of a card will >> activate the card when followed, but do not count as tabs themselves. > > Again, I'd rather :tab , :active:tab and :not(:active):tab, although a > link is still a link (and :active has a different meaning for links), > so :active-tab may be necessary. Doesn't work, for the same reasons. It actually *extra* doesn't work here, as the active tab is *nothing* like the semantics of :active. :active-tab is a tab associated with an active card; it has nothing to do with whether you are currently manipulating the tab. (You would use :tab:active to change the display of a tab while it's being clicked.) >> Questions/Issues >> ---------------- >> Currently, *all* cards start out inactive when you enter a page >> (unless the page had a hash, of course). Most JS-based tabbed layouts >> will automatically activate the first card (with 'first' defined in >> some consistent manner). Should we adopt this? Should there be a >> control for this? How would it work? > > I think that the first card child, in css content order, inside the > stack, should be active unless the user interacts in other ways. In CSS content order? Do you mean DOM order? I'd agree with that. My proposal doesn't have a stack that something can be inside of. A stack in my proposal is just a unique identifier that cards associate themselves with. Are you talking about the older proposal? >> Once a card has been activated from a stack, there's no way currently >> to close all cards from that stack - you'll always have one open. >> Most js-based tabbed layouts allow you to click an active tab to close >> the card. This seems reasonable to me, but it would require a slight >> complexification of the card handling. > > I don't know, but it does not seem more complex to me: you have to > track the currently active card for the stack, you can notice that > you're reactivating the same card. > This works only if you define the card handling imperatively (a set of > processing on the navigate action) instead of declaratively (a set of > states), something new to CSS but that does not really affect the > author, only the implementation. Yeah, it's not much more complex, it's just that the language has to change. I already require hidden states (card *activation* is determined by the hash, but a card *staying* active is based on hidden history tracked by the CSS engine), it would just require slightly more here. >> Should I expand the wording concerning activation and tab-selection to >> allow other means of targetting (such as XPointer)? I don't see any >> particular reason *not* to. > > You could say that the same algorithm used to resolve :target should > be used for associating (explicit) tabs with cards, so if an UAs > implements XPointer for target it will implement that also for Tabbed > Layout. You need to say that only the first matching element is > considered. Sounds good. > I expect that if Tabbed Layout will rely so much on fragment > identifiers, UAs will consider adding XPointer to avoid having an ID > for each tab. Hmm, that would be nice. Something to poke at for the future. > Lastly, for what concerns activation and autoscrolling, a new property > in the Hyperlink Presentation Module (like target:no-change) may be > fine. Yeah, current hash-link behavior isn't ideal for tabs. It's workable, but could be better. >> I still liked that the original draft allowed you to easily transform >> existing markup into a tabbed layout. Can anyone see an easy way to >> merge the two solutions? > > Display:card inside a display:stack, and tabs with hyperlinks. That doesn't do it. If we have to add links to the document for tab activation, we might as well #id the cards as well and just use this proposal. I'm talking about how the original proposal could take a document that was *completely* not intended for tabbed display, and still handle it well (assuming the document met certain structural requirements, namely that all the desired cards were siblings). ~TJ
Received on Monday, 20 April 2009 16:52:19 UTC