Re: Tabbed Interfaces in CSS

On Apr 22, 2009, at 6:18 AM, Giovanni Campagna wrote:

> We are leaking from Tabbed Layout into Advanced User Interface,
> Behavioural Extensions to CSS, CSS Object Model, Selectors Level 4...
>
> 2009/4/22 Brad Kemper <brad.kemper@gmail.com>:
>>>
>> 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...
>>
>>> and what would be the expected
>>> rendering?  (I ask for this again just to ensure that I am  
>>> absolutely
>>> comprehending your proposal properly.  I had the advantage of  
>>> starting
>>> a thread with a formal proposal; yours developed somewhat  
>>> organically
>>> within the thread.)  Make sure that there's a way to distinguish the
>>> active tab as well.
>>
>> fieldset { radio-group:mytabs; appearance:tab-card; display:inline- 
>> block;
>> position:absolute; left:0; }
>> This first rule says that both fieldsets in your example are part  
>> of the
>> same radio group, given the identifier of "mytabs", and that they  
>> should
>> have the OS appearance for the display area of a tabbed display (an  
>> author
>> could specify their own style instead of using appearance if he  
>> wished). By
>> putting these into a radio group, the UA should track the "checked"  
>> state of
>> each one according to radio-button standards, not according to  
>> check-box
>> standards. By default, the first fieldset ("foo") has a "checked"  
>> state, and
>> any others ("bar") do not. The absolute positioning and the inline- 
>> block
>> display makes all the fieldsets appear at the same x/y coordinates.
>
> Ehm... the fact is that the tracking of :checked state (according to
> Selectors Level 3) depends only on the markup language. And neither
> HTML4 nor HTML5 (nor XHTML1.0 / 1.1 / 2) define :checked for fieldset
> (actually, for everything outside input[type="checkbox"] and
> input[type="radio"]).

This proposal, like all proposals, would require some change to specs  
and adoption by implementors.

> So you need to define how the element is
> checked.

See the four bullet points near the top of the e-mail I sent to you  
and the list yesterday at 2:55 Pacific Time, which was in direct  
response to your allegation that there was "no way to define when  
checked or not checked."

>> fieldset:not(:checked) { appearance:none; z-index:-1; }
>>
>> This second rule says that any of these fieldsets that do not have  
>> a checked
>> state would not have any OS appearance (including no shadows or  
>> borders in
>> OS X), and that they should be lower in the stacking order than  
>> fieldsets
>> with a checked state (an author might also want to explicitly  
>> remove any
>> borders, padding, etc. here that might be part of the default  
>> fieldset
>> styling).
>
> I don't understand why appearance:none;

Because the legends are inside them, I could not completely hide the  
inactive fieldsets, so I hid their contents instead so that the  
fieldsets would not be big enough to be seen behind the front fieldset  
(there are other ways to accomplish the same goal, such as setting  
height and width to zero with a hidden overflow). But even so, there  
are some appearances that extend out beyond the box dimensions, such  
as a box shadow effect in Mac OS X, and that needed to be suppressed  
as well

>> fieldset:not(:checked) * { display:none; }
>>
>> This third rule says that those non-checked fieldsets should not  
>> display any
>> of their contents. Combined with the previous rule, it means that  
>> only the
>> checked fieldset will be visible (but without using display or  
>> visibility on
>> the fieldset itself).
>
> I'd rather fieldset:not(:checked) > :not(legend) { display:none; }
> And notice that this does not hide anonymous boxes (ie text content
> inside the fieldset)

Suit yourself, if you think there are better ways to use :checked to  
get the effect. This is only an example of one way to do it. It is  
meant to be flexible. Your way does the same thing, and works just as  
well.

>> fieldset:not(:checked) legend { appearance: tab-top-back;
>> display:inline-block; }
>>
>> These make an exception to the rule right before it: it allows the  
>> legend
>> element to be displayed (so far, only the unchecked version) and  
>> gives it an
>> OS appearance of an unselected ("back") tab of the variety that you  
>> see
>> along the top of a tabbed display. This is more specific than just
>> "appearance:tab", which does not seem to be enough to describe the  
>> different
>> states or positional types for tabs. Maybe there would be a better  
>> way to
>> indicate the appearance state, or maybe the UA would be able to  
>> figure this
>> out on its own as part of appearance magic, but I am trying to  
>> reduce the
>> reliance on magic. The author could also use non-appearance-based  
>> styling
>> here to indicate non-selected-tab instead, if he wished.
>
> Why clicking the legend should change the :checked state of its parent
> (that is not an input, btw)?

Because of event propogation. You are clicking inside a fieldset when  
you click on a fieldset's legend.

> This represent the behavior (event handling).

So does clicking on radio buttons and checkboxes, or hovering over a  
link.

> You need some way to
> attach behavior (BECSS)

Not if the UA does it for me, as it does with those other events that  
change what CSS rules select.

> and to change the pseudo-classes that apply to
> an element (CSSOM).
> "appearance", per Basic User Interface, includes only "color", "font",
> "cursor", "margin", "padding", "border", "outline" and
> "text-decoration":

Typical OS appearances may replace those properties, but they also add  
to them and create appearances that are often not achievable by  
setting CSS on a single element.

> no "binding", no "xml-events", no "onclick", no
> "behavior", no "left", not even "width", "height" or "display".
> But, if we can define a value for "appearance", we can safely define a
> set of keywords or UAs native URIs for "binding". You don't even need
> "radio-group" (formerly "toggle-group").

I proposed radio-group as an indicator that the item was part of a  
radio grouping and would have the state tracking that radio buttons  
have. If there was something already called "toggle-group" to do the  
same thing, then fine. I was proposing that as something for Selectors  
or for HTML, not Appearance. I would want it to work even if  
Appearance was not used to style the tabs.

Sorry, got to run. can't finish response right now.

Received on Wednesday, 22 April 2009 14:40:31 UTC