Re: Tabbed Interfaces in CSS

On Tue, Apr 21, 2009 at 9:20 PM, Brad Kemper <brad.kemper@gmail.com> wrote:
> On Tue, Apr 21, 2009 at 3:44 PM, Tab Atkins Jr. <jackalmage@gmail.com> wrote:
>> How would this work?  Given the following markup:
>>
>> <fieldset>
>>  <legend>foo</legend>
>>  <div>card one</div>
>> </fieldset>
>> <fieldset>
>>  <legend>bar</legend>
>>  <div>card two</div>
>> </fieldset>
>> (You can alter the markup if necessary to better match your proposal.)
>>
>> What CSS would your proposal require,
>
> Slightly modified from the first time I sent it:
>
> fieldset { radio-group:mytabs; appearance:tab-card; display:inline-block;
> position:absolute; left:0; }
> fieldset:not(:checked) { appearance:none; z-index:-1; }
> fieldset:not(:checked) * { display:none; }
> fieldset:not(:checked) legend { appearance: tab-top-back;
> display:inline-block; }
> fieldset:checked legend { appearance: tab-top-front; display:inline-block; }
>
> See below for an explanation of each line and how it would affect the
> rendering...

...snip explanation...

That seems to depend a *lot* on very undefined behavior for the
appearance property, which *shouldn't* have anything to do with
behavior at all.  As Giovanni says, appearance is just a shorthand way
of saying "set all these properties so that the element looks like X
widget in the UA".

You're relying on appearance to group tabs, move them around the page,
and defeat a display:none applied to their parent.  In addition to all
this behavior, it presumably applies a UA-default style to the tabs,
and possibly cards, making it difficult/impossible to restyle them as
desired.

It seems like Template Layout could solve this much more easily and
extensibly, actually.

form { display: "a" "b"; }
fieldset:not(:checked) { display:none; position:b; radio-group:my-tabs; }
fieldset legend { position:a; /* insert generic tab styling here */ }
fieldset:checked legend { /* style the active tab */ }
fieldset:not(:checked) legend { /* style the inactive tabs */ }

The only potential problem is the display:none.  It hides the element
and *all* children.  I presume that Template Layout doesn't interact
with normal inheritance, so it would still cause problems.  You use
appearance:none to address this issue in some unspecified way, but
perhaps there's another way to say "hide the element and static-flow
children"?  That seems useful to me in general - it would allow abspos
elements who live outside of the parent anyway to possible stay
visible.


>> > Yours requires a link behaviors spec to prevent unwanted
>> > scrolling (or that people find it acceptable for clicking on a tab would
>> > scroll the page).
>>
>> Maybe.  It's also possible that it just includes magic which would fix
>> the issue.  This magic also has the benefit of eventually being
>> translatable into proper rules if Link Behaviors gets properly adopted
>> (and has this ability) - a simple ":tab{target:no-change;}" (or
>> whatever) added to the UA default stylesheet would do it.
>
> Fair enough. I was trying to minimize magic-reliance in mine, but for the
> best effect I have a little for appearance to do, or a reliance on
> floating-to-a-named-spot-type-of-thing, or else a somewhat less ideal
> presentation (see last part of my tabs example explanation).

Floating to a named spot is more-or-less covered by template layout
now, and can be done as I outlined above.  I find it much preferable
to hacking appearance into doing this.

>> > Mine has neither of these requirements, but just extends
>> > an existing pseudo-class to more elements, and adds a couple properties
>> > to
>> > indicate radio groups and for defaults.
>>
>> But without some magic generation of tabs from card content, it has
>> bad fallback behavior.
>
> Nope. Good fallback behavior is its best quality. It only prefers a little
> magic for lining up the tabs, or using one of the other proposals for moving
> things around. It might even be able to use template layout for that. So
> magic is not an absolute requirement.

Yes, once you've added the ability to extract tabs from the cards
(solving the issue of hiding the card without hiding the extracted tab
in the process), then fallback is just fine.  It still has bad
fallback when you're doing a more complex tabbed layout with the tabs
defined outside of the cards, though (which is why I based my proposal
on links, which are still good in this case).  This can potentially be
patched.

~TJ

Received on Wednesday, 22 April 2009 14:52:33 UTC