W3C home > Mailing lists > Public > www-style@w3.org > April 2009

Re: Tabbed Interfaces in CSS

From: Tab Atkins Jr. <jackalmage@gmail.com>
Date: Tue, 21 Apr 2009 18:28:23 -0500
Message-ID: <dd0fbad0904211628q2821043dh7ce7cdb9dc6729fd@mail.gmail.com>
To: Andrew Fedoniouk <news@terrainformatica.com>
Cc: Brad Kemper <brad.kemper@gmail.com>, Giovanni Campagna <scampa.giovanni@gmail.com>, www-style list <www-style@w3.org>
On Tue, Apr 21, 2009 at 5:49 PM, Andrew Fedoniouk
<news@terrainformatica.com> wrote:
> '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.

It may have been defined badly, but it *can* be defined well.  When
that is done, it *is* exactly like your flow property.

>>> 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.

I definitely recall you have something table-like.  I think it was
grid units?  Like, you could do "width:1#;" or something, and it would
define an implicit grid based on the elements?

> 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'm not sure what you mean here.  I *think* you're saying that you
have an interface for extracting semantics from <table> elements in
your layout engine.  That has absolutely nothing to do with making
elements use the table display rules, however.

>>> 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.

Nah, in that case all you'd do is make sure that the slider ticks are
labelled appropriately.  Then displaying all of the privacy setting
descriptions is still useful (it's just a list of what each tick on
the slider means).

When CSS is available, then you hide the tick labels and apply some
variant of tabbed behavior to the descriptions, keyed to the slider.

Of course, this may not ever be appropriate to specify in pure CSS.
It may not ever be possible to do it in a sufficiently simple way to
justify the effort.  You'd just use JS to do it, then.  There's really
no problem with that, either.  This is something that hits *really*
close on the style/behavior dividing line.

>> 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 :)

Heh, I actually agree.  It's the big reason I didn't like the Advanced
Layout proposal for tabbed layouts - it *depended* on automatic
generation.  However, it had a point - you *need* to have some degree
of automatic generation if you want to be able to apply tabbed layouts
to documents that weren't ever intended for it.

(Well, you need auto-generation if you don't want CSS to basically
become javascript, which would give you full control over the tab's
structure and behavior.  There is in fact another jQuery plugin which
pulls the tab data automatically out of the card, and you can
customize its behavior to do what you want by passing it some

>>> 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;

Indeed, but they do so in an way that is easier to rad and write, and
that works within CSS's syntax and intent.

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

Exactly.  That makes us hesitate when we introduce something that is
arguably a behavior rather than a pure style issue.  It also lets us
tailor the language to the problem, making it as easy to use as
possible.  There's a reason there's such hype over domain-specific
languages, you know.  ^_^

> 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 problem is that you don't have all the rest of the tools that a
real programming language provides, such as the ability to define
further structure and pack behavior into abstractions that hide much
of the detail.

>> 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.

The first is arithmetic, nothing more.  It's just arithmetic that we
authors are physically unable to perform on our side - it depends on
the user.

The second, though, has comparisons and control flow.  It's
programming.  There's no way to argue against that.

Of course, that can be duplicated by using a media query, but then
you're using a domain-specific language tailor-made for a class of
useful comparisons.  You gain a lot of clarity by phrasing it in
media-query terms.

>>> 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; }
> ?

They just define style.  I've used nearly identical CSS for purposes
that are unarguably simple style definitions (such as making the
selected option more visible).

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

It's me abusing some HTML behavior (radio buttons which have a useful
form of click-memory) to apply particular styles where and when I want

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

1) Because CSS is easier than JS (or at least, can be).
2) Because then I don't have to send several extra kilobytes of
behavior over the wire to someone viewing my website.
3) Because the browser can apply the appropriate rules before
displaying the page, avoiding a flash of unstyled content that it
almost unavoidable when doing some of these things in JS.
4) Because browser developers can write a single, efficient
implementation optimized for their code-base, as opposed to hundreds
of authors defining their own version atop a framework, and likely
prioritizing ease of authoring and comprehensibility over efficiency.
5) Because this sort of issue lies at the boundary of style and
behavior.  It's not definitely one or the other.

You can take your pick.  ^_^

Received on Tuesday, 21 April 2009 23:36:15 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Tuesday, 22 May 2012 03:46:58 GMT