Re: [css3-regions] Separating regions markup

On 11/29/12 12:36 PM, "Bert Bos" <bert@w3.org> wrote:

>On Wednesday 28 November 2012 00:11:18 Alan Stearns wrote:
>> Hey all,
>> 
>> As I mentioned last week, I've edited the sample code in Appendix A
>> [1] in CSS Regions to move the regions elements to a separate file
>> using custom elements from Web Components [2].
>> 
>> Bert, Håkon - does this approach satisfy your requirement for
>> separating content markup from layout?
>
>I think it can work.

This is very good to hear. Thank you for all of your feedback below.

>
>There are some other details missing, such as what the default
>formatting of these regions is. But those can be added.
>
>The previous time we discussed using an XML syntax for defining regions
>(XBL or generic XML) we didn't continue with the idea, I believe,
>because the CSS syntax (the template syntax) was shorter and more
>readable. It can be short, because it only handles regions that are
>aligned to a grid, but that seems to cover most of the cases.
>
>I don't mind also allowing an external resource to define regions. (Some
>systems already use such an XML file to define the layout; it could now
>be processed on the client side, rather than on the server side, which
>seems an improvement.) But being able to define a grid in one line in
>the style sheet itself is very convenient ('grid: "a b" "c d"'). I don't
>want to abandon that.

I agree. I think it makes sense to be able to define a template aligned to
a single grid in CSS, but to also have the ability to create a more
complex (and possibly nested) template with external markup. I want to
pursue both avenues.

>
>1) Using an external format for defining a display structure is similar
>to using an external image for a background. If something gets
>complicated (whether an image or a layout) it is good to put it in a
>separate file.

Yes, and it's particularly useful to have a separate file if the
complicated thing can be re-used.

>
>2) Serving that external resource as text/html is not a good idea,
>though. That suggests that you can read it, print it, etc. as if it were
>an HTML document. Better would be to use a new MIME type, something like
>application/component+xml.

That's feedback for the Web Components guys, which should go to the
public-webapps mailing list. I don't have a strong opinion on this, so
I'll let you decide whether to raise the issue there.

>
>3) For linking to that external resource, I suggest merging the 'grid'
>and 'decorator' properties. That avoids that we have to define which one
>takes priority (or how they combine). Using only one property allows the
>author to choose if he wants
>
>    DIV {
>      grid: "a b c"  "d e f"     /* define regions with CSS syntax */
>    }
>
>or prefers
>
>    DIV {
>      grid: url(regions.xml#r1)   /* define regions in XML */
>    }

I think it may be useful to keep these separate. There are probably uses
for having the contents of an element laid out in a grid, but then have
the entire grid wrapped in a decorator. It's already defined how they
interact - the grid layout goes into the <content> element of the template.

>
>4) You can refer to CSS-defined slots by their name:
>
>    P {flow-into: a}              /* flow into slot "a" */
>
>and there are scope rules (viz., the document tree) for finding which
>slot is meant if there are several of the same name. In the example in
>the wiki, the slots also have names (given by "class" attributes), so
>that seems to match nicely:
>
>    P {flow-into: region}         /* flow into slot "region" */

This is an interesting idea, but I'm not sure what would happen if there
are multiple class names on an element in a <template> that match a
particular named flow. It might be better to limit this to slots defined
in a grid template, as they can only have one name given to them.

>
>5) Regions will also have to be chained. The proposal for chaining grid
>slots is
>
>    DIV {
>      chain: a c f            /* make slots a c f into a single flow */
>    }
>
>That could work the same with external regions:
>
>    DIV {
>     chain: start region
>    }
>
>And two slots with the same name would be implicitly chained, in the
>order they appear in the external file. (E.g., the example on the wiki
>has two slots both named "region" which therefore form a single flow.)

I think this runs into the same issue I have with (4) above - what about
multiple class names? It's less magic to not have to declare 'flow-from'
but I think it may be necessary (again, only for a markup template. I
think this could work for a CSS grid template declaration).

>
>6) The example on the wiki uses the existing selector syntax to refer to
>external slots:
>
>    DIV { grid: url(url(region-layout.html/#region-layout) }
>    DIV .start { height: 60vh }
>
>where .start selects a pseudo-element, created by the style sheet
>itself. I think I like that syntax, because it is short. (But it may be
>confusing that the pseudo-element isn't a sibling of any real element,
>even though this syntax suggests that it is.)

The way Web Components work, the .start div is an actual element in the
(shadow) DOM, not a pseudo-element. I'm still learning how selectors work
around the shadow boundary, but the .start element is a real element with
the standard parent and sibling relationships.

>
>7) The grid templates proposed for CSS come with default rules for how
>to size and position the slots. We will need rules also to position and
>size the externally defined slots. (E.g., they could be like child
>elements that come after the ':before' pseudo-element and before any
>real child elements.)

As above, it's actual DOM (albeit in a shadow DOM subtree). So you get all
the normal positioning and sizing (and scripability, and accessibility) of
real elements.

>
>8) I think there is an error in the example in the wiki. The regions
>should be defined on a common ancestor of the ARTICLE and the IMG,
>because both of those should flow into the regions. But the .bar
>selector selects the image. I think the syntax should be like this:
>
>    <style>
>    article {
>      flow-into: region;
>    }
>    .start {             /* A slot in the imported layout */
>      height: 60vh;
>    }
>    body {               /* Corrected selector */
>      decorator: url(region-layout.html/#region-layout);
>    }
>    </style>
>    <body>
>      <article>
>        ...
>      </article>
>      <img class="bar" src="foo" alt="separate content">
>    </body>

With flow-into and flow-from, it's not a requirement that the element
using a custom element or decorator be a common ancestor of all the
content flowing into the template. I wanted to point that out in the wiki
by using an <img> element, but I did use the <body> element in the
specification text. I think in general it's a crutch to be using the
<body> element in this way in examples, though. I expect that in most
real-world cases you'd be modifying something within the <body> element.

>
>9) The external layout definition can have nested elements (so that you
>can align slots to one another easily), but you can only flow content
>into leaf elements (i.e., empty elements). E.g.,
>
>    <decorator id=d1>
>      <div class=group>
>        <div class=slot1/>
>        <div class=slot2/>
>      </div>
>    </decorator>
>
>allows
>
>    P { flow-into: slot2 }
>
>but not this:
>
>    p { flow-into: group }  /* ERROR! */

I see why you might want to prohibit this, but it could be useful. Say you
have a template that is carefully constructed such that those slots are
useful in a desktop layout, but a single region would be better on mobile.
You could use media queries to determine which parts of the template you
use.

>
>10) The Web Components syntax has a <content/> element to indicate the
>default slot (where the own contents of the element with the external
>layout go). That is equivalent to the "*" slot in a grid template. I
>didn't see in the Web Components spec if there is always exactly one
>such element. More than one would be an error, but none doesn't have to
>be. We'd just have to define which slot is the default in the absence of
>a <content/> element.

There can be more than one <content> element. Take a look for samples that
look like this (there's one in the explainer):

<content select=".some-selector">

That will render anything that matches the given selector (I think only
within the component's scope). I think the first match is always used, so
if there's more than one <content> element without a select attribute,
only the first renders content.

>
>
>
>> [1] http://dev.w3.org/csswg/css3-regions/#intro-example-code
>> [2]
>> http://dvcs.w3.org/hg/webcomponents/raw-file/tip/explainer/index.html
>
>> >[1] http://lists.w3.org/Archives/Public/www-style/2012Nov/0260.html
>> >[2]
>> >http://dvcs.w3.org/hg/webcomponents/raw-file/tip/explainer/index.html
>> >[3] http://wiki.csswg.org/spec/css3-regions/sequestering-regions

Thanks again,

Alan

Received on Friday, 30 November 2012 02:19:43 UTC