Re: Tabbed Interfaces in CSS

Tab Atkins Jr. wrote:
> 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.
>   
'display' has classic meaning. But the 'flow' is not 'display-model' 
strictly speaking.
It is 'display-model: block-inside' + definition of how those blocks 
shall be replaced.
'display-model' in the way it was defined had almost no value indeed 
that is why it
was abandoned.

>   
>> 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.
>   
Tables are defined in initial style sheet simply as
table {  flow:table; }
that is a layout manager that handles *HTML* table layout.
That layout manager knows how to layout tr, td, th and caption elements 
only.
It has not too much value for other elements thus it can be used only in 
initial (built-in)
style sheet only.
flow:table layout /behavior/ in my case also knows how to handle 
IAccessibile (Section 508 related).
I am not sure how display:table is supposed to behave in this respect.
>   
>> 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.
>   
About fallback... in most cases it is not even possible.  Think about that
"Internet Options -> Privacy tab in IE" case.
It will not help you if you will see all four options at once, right?
I mean that in most cases fallback will make things even worse.

I suspect that in reality it should be something like 
<script>/<noscript> kind of fallback.
> 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).
>   
"automatic generation" sounds scary to be honest. Probably in the same 
way as CSS script language :)
>> 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.
>   
Think about media query expressions and say the calc(). These are early 
birds.
As deeper as more procedural things you will see there. Don't forget 
about  animation and
transition modules. They by the way introduce their own model of saying:

   if (animation-progress >= 50% && animation-progress < 75%)
       self.color = #aabbcc;
   else if (animation-progress >= 75%)
       self.color = #bbccdd;

So those "programming languages" are here already. The problem is that 
with each new module
we will have new variation of it.

My CSSS! stuff is just an attempt to summarize all these requirements in 
unified form. E.g. in
my case you can say:

div { height: calc( self.chidren() * 12px + 2em );  }

It is better to start thinking about unified procedural approach now 
than when it would be
too late. Again: we are not so rich to buy cheap stuff [CSS attributes 
and values].
> 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!
>   
CSSS! is safe thing in the same way as CSS is safe. As soon as you will 
allow XBL things to be
bound through it as you will open new can of worms. I am not speaking 
here about security only.
CSSS! runtime is intentionally made as a stack based machine that has no 
and does not require
GC - it in principle cannot leak memory. It is really an extension of 
CSS with computation model
where CSS selectors, lengths an all other CSS units are first class 
types/values. And for sure it is not
a programming language of common use.

That is really interesting (and yet philosophic) question what is 
programming language and what is not.
Seems like people tend to think that this:
  
   width: calc( 10% + 12px );

is not a programming and this

   width:   calc( screen-width < 800? 5% : 10% + 12px );

would be precisely it.
>> 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).
>   
Yet another philosophical question about boundaries.

Are these two rules define behavior or styles:

input[type="radio"] + div { display:none; }
input[type="radio"]:checked + div { display:block; }

?

And that attempt of yours to define tabs/cards *behavior* by pure CSS...
is really what?

It is easy to define behavioral things in JS but why people again and 
again are trying to find
"pure CSS" solutions?

--
Andrew Fedoniouk.

http://terrainformatica.com

Received on Tuesday, 21 April 2009 22:50:10 UTC