Re: Tabbed Interfaces in CSS

On Tue, Apr 21, 2009 at 2:53 PM, Andrew Fedoniouk
<news@terrainformatica.com> wrote:
> Tab Atkins Jr. wrote:
>>
>> (Though, honestly, we *will* have to deal with the role/model
>> dichotomy in time.  The only reason it's not immediately obvious that
>> this is necessary is because all of the 'common' display values are
>> roles, and have trivial default associations to models (block-inside
>> and inline-inside, depending), so we are used to just dealing with
>> that.  We gained our first taste of the problems caused by the
>> conflation of role and model with the table and inline-table values
>> (arguably inline-block was the first, with role:inline and
>> model:block-inside), and we see it again with the stopgap solution in
>> the current Template Layout draft (an optional "inline" value
>> preceeding the template).  It will only get worse as we add more
>> models, and we already have a few roles that have problems combining
>> with other values.  It's impossible to make an <li> into a table,
>> frex, without losing the list-bullet (as that's part of
>> display:list-item).  Table's a model, though, while list-item is a
>> role.  Hell, it's impossible to make an <li> *inline* and have it keep
>> its bullet.  People have to abuse floats just to get a horizontal list
>> with bullets, because float's not a display value and won't interfere.
>>  Gah, this actually just means that list-item shouldn't be a display
>> type at all - all it means currently is "display:block, and generate a
>> ::marker pseudoelement filled by an appropriate counter".
>>
>> In short: display is all kinds of messed up, it's just not very apparent
>> yet.)
>>
>
> The 'flow' allows to replace lists horizontally without any problems:
>
> ul { flow:horizontal; padding:0;}
> li { padding-left: 2em; width:*; [display:list-item;] }
>
> I would suggest to consider 'display' as an attribute that defines
> requirements of the element to its container.
> And the 'flow' as a definition of the way how container does layout of its
> children.
> Ideally 'none', 'block', 'inline' and 'inline-block' have to be the only
> values of the 'display'. I would even exclude
> 'none' from the list and move it into 'visibility' list of values.
> I agree: currently 'display' is a mess of different things.

Yes, the display/flow split in your HTMLayout engine is roughly the
same role/model split, with display being the role and flow being the
model.

> But we already at the point when 'display' cannot be changed (table stuff
> can probably be safely removed if it is not too late).

It's only necessary to 'remove' things from display if you are
creating an entirely new property like 'flow'.  If you make display
into a shortcut property you can special-case all the existing display
values into their appropriate default roles/models.

In your layout engine, tables are basically defined by a flow, right?
I'm just making sure we're on the same page here.

> I do not see how the 'display' is related to tabbed interfaces though.
> Conceptually it is just two sets of elements where something like
> :checked in one group is bound with visibility of elements in other group.
> There are too many various way to style tabs and
> cards appearance - we'd better not even to try make it fixed in
> display:cards or so.

Indeed, the general solution that I'm wanting doesn't use display at
all, for precisely that reason (existing authoring practices show a
wide variety in display and layout of tabs and cards that can't be
reproduced automatically through display).  The reality isn't quite as
simple as your 'conceptual' example, though, since you have to take
fallback into account.

However, it's also desirable to be able to automatically generate this
sort of layout, in which case you are stuck with some form of
automatic generation and some limit on how you can style and lay out
the tabs/cards.  I've got some ideas for that (though they probably
won't involve the display property).

> In general you need to be able to define something like this (pseudocode):
>
> ul .tabs > li
> {
>  behavior:radio; /* behaves as member of radio group, :checked */
> }
> ul .tabs > li:not(:checked)
> {
>  set: $(div.card:nth-child(index)).visibility = collapsed,
> }
> ul .tabs > li:checked
> {
>  set: $(div.card:nth-child(index)).visibility = visible,
> }
>
> But that is pretty much that CSSS! thing I was talking.

Embedding a programming language into CSS is still an *enormous* step
that has not shown any signs of being necessary.  It would make CSS
much more difficult to both read and write.  It also would almost
certainly encourage writing CSS that doesn't degrade well - the code
you just posted would mean that, in the absence of CSS, you have a
random <ul> of section labels sitting around that doesn't do anything.
 Under my proposal there'd still likely be a <ul> of section labels,
but they'd also serve as links to the specific sections, which is
useful.

The simplicity and *lack* of generality in CSS is a *good* thing.  It
means that we can put thought into the solutions developed to make
sure that they work well in multiple circumstances.  If you want a
scripting language, you already have one - it's called javascript, and
it already handles all these complicated things.  It has the added
benefit of being well-defined and well-supported *as a scripting
language*, and allows people to put together packages (like the jQuery
UI tabs) that are super-easy to apply and still degrade well even when
scripting is turned off!

> There are many other use cases when CSS would need something like
> event/state handling.
> This card *behavioral* thing is one of them, others are animations, printing
> (think about page-start, page-end events)
> and may others. As an example think of <input type="slider" min=1, max=4>
> bound with visibility of four different paragraphs.
> ( See: Internet Options -> Privacy tab in IE). I mean that there are too
> many variations of even "simple" tab/card functionality
> to be able to define their behavior and layout in CSS.

There are good approaches that could solve that in CSS in an
easy-to-author manner, and when that fails, javascript still exists.
We're pushing up against the boundaries of what constitutes appearance
and what constitutes behavior, and both CSS and JS are possibly
appropriate here.  Let's let CSS handle things that it can do in a
simple way, and let JS handle the rest (since it's usually simple as
well).

~TJ

Received on Tuesday, 21 April 2009 20:23:43 UTC