Re: [css3-regions] Comments on Editor's Draft

On 11/07/2011 20:46, Vincent Hardy wrote:
> On 6 Jul 2011 13:00:19 -0700 Anton Prowse wrote:
>> I've just been reading through the Regions proposal.  The underlying
>> idea feels rather natural.  However, I couldn't grasp some significant
>> aspects of model.
>
> Thanks for your careful review, it is really helpful. Sorry for the
> late answer, I was out last week. I assume your comments are based on
> the July 1rst version, is that right?

No problem!  Yes, I was using the July 1 public version.

>> Is it possible for an element to be both a region and to be added
>> to a named flow?
>
> Yes, that would be possible.

OK.

>> Is it possible for an element to be both a region and to be added
>> to a named flow that is then assigned to that same region?
>
> [No,] we should mention in the spec that it is an error.

OK.

> But moving the _content_ of B to the named flow and then using that
> content (the case you mention below) would work:
>
> #B * { flow: article; }

>> The underlying difficulty seems to be that, when assigning an
>> element to a named flow, we don't get the choice of whether the
>> element and its children are in the flow or whether just the
>> children are in the flow.
>
> With the proper CSS selector, we can move either the element
> or just its children into the flow.

OK, that's what I expected the answer to be.  However, whilst I agree 
with (and planned to suggest) Alex's subsequent recommendation that the 
child combinator (>) be used instead of the descendant combinator, even 
then I'm cautious about this approach.

The first thing that came to mind was the issue of specificity.  If a 
child #C of #B were also placed into a named flow, we'd need to be 
careful to avoid that the rule for "#B > *" override the rule for the child:

Bad:
#C {flow: sidebar}
#B > * {flow: article}

Good:
#B > * {flow: article}
#C {flow: sidebar}

Perhaps this is an acceptable and expected situation, but both my 
authoring experience and my language design instinct make me uneasy 
about using things like "> *".  It feels... kludgy (and indeed only 
works in this case because you've explicitly defined the model so that 
named flows are populated in document tree order).


>> adding a region's own content to a named flow that that's
>> flowed into the same region isn't so strange an idea:
>>
>> <div id="article">
>>     <p>text</p>
>> </div>
>>
>> I might want to flow *extra* content from elsewhere into the
>> #article box in addition to its own document content.  To do this I
>> would have to add its own document content to a named flow, along
>> with the extra content.

Indeed, using your above way of thinking, this would be achieved as follows:

#article {
	content: from-flow(article)
}
#article > * {
	flow: article
}
#elsewhere {
	flow: article
}

Note that because there is no flow-order property, whether the content 
from #elsewhere comes before or after the children of #article depends 
on whether #elsewhere precedes or follows #article.  This lack of 
control may or may not be a serious problem depending on how important 
you think the use case is.


>> Flows
>> -------
>>
>> 2.1 (Named flows):
>>
>>   # the absolutely positioned elements are part of a special flow
>>   # (called positioned flow)  which is subject to a special layout by
>>   # its container box (i.e., its container box positions it into the
>>   # containing block's box
>>
>> 2.4.4 (Generated flow):
>>
>>   # pseudo-elements [under certain conditions] create a generated
>>   # flow which they format visually.
>>
>> Is there just one positioned flow and just one generated flow, or
>> does each abspos give rise to a new (anonymous) positioned flow,
>> for example?  [...]
>
> In the proposed model, there is one positioned flow per
> container.

OK.

>> 2.4.2 (Positioned flow) suggests otherwise, that in fact there are
>> multiple flows:
>
> Hum.. this is the section I was just quoting. As I wrote, it
> was intended to say there is one positioned flow per container, but
> you understood this differently. Could you say what gave you that
> understanding?

No worries, my point (namely that 2.1 appears to suggest otherwise) was 
missed but your answer above is exactly what I was looking for!

> Note that this section is proposing consistent
> model for flows and explain how positioned content can be modeled
> with flows. It has no impact on how regions themselves work.

Sure.  I won't take these editorial issues further until the spec has 
progressed to LCWD!  I just needed to get enough clarification in order 
to understand the model.


>> what happens if multiple named flows are assigned to a single
>> region?  How do they compete?  For example, what happens if a
>> region with content (ie a region which implicitly has normal flow
>> children) is assigned a named flow? Or is it the case that a region
>> can only be assigned at most one positioned flow and one
>> non-positioned flow?
>
> Conceptually, we could imagine mutliple flows with different
> positioning schemes because CSS already allows that with the normal
> flow and the positioned flows. But with the syntax proposed, it is
> not possible to assign multiple named flow to a region.

Ah yes, I was off-track there; just as for any property, there is only 
one winning declaration for the 'flow' property in the case that there 
are several competing declarations.

The answer to my question of what happens when a region with content is 
assigned a named flow can be found in your answer further down.  (The 
content becomes disconnected unless it is itself assigned to a named flow.)


>> Container boxes
>> --------------------
>>
>> 2.1 says:
>>
>>   # [...] there is a notion of flow containing a sequence of
>>   # elements and there is a notion of (block) container box into
>>   # which the elements flow.
>>
>> I'm not sure that the container box referred to is really a block
>> container block.  Indeed, at the end of the section, examples of a
>> container's layout scheme are the normal layout (block and inline
>> formatting), table layout, and multi-column layout.  Yet whilst a
>> table box (as opposed to table wrapper box) and a multicolumn box
>> are indeed containers in the sense that they define a layout scheme
>> for children, neither of them are *block* container boxes as
>> defined by CSS21.  So "container" is being used in a more general
>> sense in the proposal than in CSS21.
>
> Can you point to the definition of 'container' in CSS 2.1 you
> are referring to (9.2.1?) ?

Yes, 9.2.1.  Note that the definition there is specifically of a _block 
container_, ie a box that contains (only) blocks(*). There is no 
explicitly defined notion of other types of containers in CSS21 
(although of course a table box is an example of such from CSS21).  So 
the point I was making is that at some point in the future the more 
general term "container block" will need to be defined.  For the time 
being (since this is mainly an editorial issue) I'm just going to assume 
some reasonable definition of container block for the purposes of this spec.

(*) Or alternatively, ironically enough, a block container can be a box 
that doesn't contain *any* blocks.  I was never too happy with the 
"block container" terminology!

>> On a related note, 2.4.2 (Positioned flow) says:
>>
>>   # An absolutely positioned element is placed into the positioned
>>   # flow of its container. The container positions this element into
>>   # its containing block.
>>
>> However, the abspos element's containing block isn't necessarily
>> established by its nearest ancestor block container box, so it's
>> not clear which container box is referred to in 2.1.  Quite
>> possibly it's supposed to be the box which establishes the
>> containing block.
>
> The proposed model is that the flow is attached to the
> container element which lays out its positioned flow into the
> containing block, as per the CSS 2.1 definition of containing block
> (10.1).

OK, so I think this means that the container of interest for an abspos 
element is the box which establishes the containing block for the 
abspos.  That container then lays out its positioned flow into said 
containing block (which is a rectangle based on the dimensions of the 
container's own box model components).


>>   # A flow gets formatted visually when associated with one or
>>   # several elements' container box(es)
>>
>> This seems reasonable (under the wider definition of container).
>> It's not clear why these more general container boxes are required
>> to arise from an element though, although that could be made true
>> if such containers were assigned a corresponding pseudo-element in
>> the case where there is no corresponding document element.
>
> The wording should be more generic and not restricted
> to elements. It should use the term pseudo-element. The section on
> grid layout should make that clear, but the wording should be
> tightened up.

Hmm, actually I was already assuming that "element" encompassed 
pseudo-elements (as per CSS21).  What I was really querying was whether 
it were possible or useful to devise a way for a flow to be associated 
with a box which didn't arise directly from an element (eg an anonymous 
block box).  Of course, we would need to come up with a way of assigning 
a flow to that box.


>>   # A region is an element that generates a block container box and
>>   # has an associated named flow
>>
>> Here, as above, candidates for regions are explicitly restricted
>> to elements; but furthermore they are restricted to elements which
>> themselves generate a container box.  This immediately rules out
>> columns of a multicolumn element (as stated in 5.2.2 albeit with
>> incorrect reasoning), since columns don't arise directly from an
>> element.  [Given that the proposal talks a lot about multicol, it
>> took me a while to realize that multicol doesn't itself conform to
>> the regions model (despite motivating it) since, whilst it does
>> amount to a flow into various areas (columns), it's not a flow into
>> *regions*.  (It would be good to change that word in 2.3.4.)]
>
> I think this reflects the recent change in the spec.
> Originally, the intent was to ask that column-boxes be addressable
> as pseudo-elements and be allowed to be regions. However, the WG
> has decided to not go that way and the section was modify to just
> say that multi-column boxes are not addressable and therefore
> cannot be made regions.

OK, that certainly explains a lot.

> I did not understand what you meant by incorrect reasoning.

The reason given in 5.2.2 for why a column cannot be a region is that 
css3-multicol does not specify a selector for column boxes.  However, 
2.2 defines a region to be an element that generates a block container 
box, and so, in fact, the technically correct reason is that a column 
box is not generated by an element.  (The fact that there is no selector 
is not directly relevant, although of course that fact is precisely what 
lies behind your chosen definition of region in the first place.)  This 
is just an minor editorial detail, to be revised in some future WD.


>> Technical details
>>  ---------------------
>>
>> 3.1 (The ‘flow’ property):
>>
>>   # The containing block for absolutely positioned descendants of an
>>   # element with a specified flow is the region into which the
>>   # element is rendered.
>>
>> Really?  That means it's no longer necessary to add
>> position:relative to "layout cells" as is common practice in
>> CSS21-era float-based layouts for example.  Of course, it also
>> means that you can't "break out" of the region and do abspos'ing
>> with respect to some ancestor positioned element.  Is this change
>> from CSS21 justified, bearing in mind that you /could/ manually add
>> position:relative to the region if desired?
>
> The options we considered were:
>
> a. do not alter the containing block definition. In that case, it
> means that it would have been defined by the containing block of
> the element in the flow, which may be totally unrelated.
> b. defined as in the draft.
>
> Do you think we have other options?

No.  But I think (a) also has use cases.  On the other hand, I think I 
agree with your implicit argument that in the most common cases authors 
would want the containing block to be established by the region 
containing the abspos; possibly it would be annoying to have to set 
position:relative on the region every time just to achieve that.


>>   # All the elements participating inside a named flow are rendered
>>   # as children of an anonymous block that spans across all the
>>   # regions associated with the specified named flow.
>>
>> I'm not sure what this means, nor what the technical role is of
>> this anonymous block.

Would you or Alex mind shedding some light on this?


>>   # Regions create a new stacking context, but inherit the floats
>>   # that are already defined by the parent context.
>>
>> I don't understand what that means, and the following Example
>> didn't help!

> Regarding the float part, it means that floats defined in the
> parent content impact the flow in the region.

So you mean that normal CSS21 behaviour is observed in the vicinity of 
the float; for example, the float doesn't impact the margin box of the 
region, but the region's inline content flows around the sides of the 
float.  That is, the second clause of the quoted sentence is redundant 
(and somewhat confusing!).  I'm guessing that the point you were really 
trying to make is that a region does not necessarily establish a new 
block formatting context.


>> 3.2 (The ‘content’ property):
>>
>> Under all values of 'content' other than none and normal, it's not
>> specified what happens to normal flow descendants.  Are they not
>> rendered (ie disconnected)?
>
> Yes, that was the intent and wording is missing.

Ah thanks, that does clarify things.


>> 3.6 (The @region rule):

>> And aren't the following two snippets more or less equivalent
>> (excepting specificity) for limited properties that are valid for
>> ::region-lines?
>>
>> @region<region1_sel>  { ::region-lines {...} }
>>
>> @region<region1_sel>  { <region1_sel>  {...} }
>>
>> In more generality, are the following two equivalent (excepting
>> specificity)?
>>
>> @region<region1_sel>  { p {...} }
>>
>> @region<region1_sel>  { <region1_sel>  p {...} }
>
> Well, the @region<region1_sel>  is avoiding having to redefine
> what the descendent selector is. Because if we said that
> "<region1_sel>  p" selected a p that is in region_1, then we would
> use the descendent selector syntax and bend what a descendent is.
> So it 'scopes' the selectors but does not modify the selector
> syntax or definition.

Ah yes, I follow you.  The two rule sets that make up the latter pair 
are certainly not equivalent, for example, since the first matches a 'p' 
that's found in region X whilst the second only matches a 'p' that's 
found in region X and which is also a document descendant of the element 
that establishes region X.

Thanks for taking the time to respond in detail.  I appreciate it!

Cheers,
Anton Prowse
http://dev.moonhenge.net

Received on Tuesday, 12 July 2011 19:30:26 UTC