W3C home > Mailing lists > Public > public-houdini@w3.org > February 2015

RE: Specifying, measuring and creating anonymous boxes

From: François REMY <francois.remy.dev@outlook.com>
Date: Fri, 6 Feb 2015 19:08:00 +0100
Message-ID: <DUB405-EAS1427FAD2DB53C939DD7E9A1A5380@phx.gbl>
To: "'Toru Kawakubo'" <kwkbtr@vivliostyle.com>, <public-houdini@w3.org>
<skipping some private chat here>
± Your opinion to the topics I mentioned in my post would be definitely helpful
± for directing the discussion to a right direction (and I also want to learn more
± from your opinion before the meeting), so if you don't mind, please post
± your opinion to the list!

My high-level opinion on the matter is that it's extremely important but needs more analysis work before we can even think about implementations as it's also quite complex. 

I bet you can interpret the previous sentence as a big "I'm not even sure about the soundness of what I'm proposing here" warning ^_^

± De : Toru Kawakubo [mailto:kwkbtr@vivliostyle.com]
± Hello,
± I would like to share my ideas which I think are in the scope of project
± Houdini.
± I would be glad to hear your opinions.
± 1. Specifying and measuring anonymous boxes
± AFAIK there is currently no API to get anonymous boxes such as one
± generated around a text that is sibling to a block, a column in a multicolumn
± environment, a line box, etc.
± Being able to access and measure such boxes from API is very important for
± script authors to do layout/typography experiments and write polyfills.
± For example, information of line box dimensions are indispensable for
± controlling fragmentation (page, column, region) break, especially when
± widows and orphans are considered.
± The idea of measure API shown on the project wiki page[1] may be
± extended to be applicable to anonymous boxes, given a way to get objects
± representing such boxes is provided.
± Possible solutions in my mind are:
±  a. Define selectors for several types of anonymous boxes
±     and provide APIs to get box objects with them
±     e.g. :nth-line() for line boxes, :nth-column() for columns etc.
±     Since querySelector() only works for elements, we need
±     new APIs to get the boxes with such selectors.
±  b. Expose the box tree through API
±     I imagine (very roughly) something like this:
±     // get a box of an already laid-out element
±     var containerBox = element.layoutBox;
±     // get boxes laid out inside the containerBox
±     var childBoxes = containerBox.childBoxes;
±     // get a line box in a box
±     var lineBox = childBoxes[0].lineBoxes[0];
±     // or get a line box in the box with specified coordinates
±     var lineBox = childBoxes[0].lineBoxFromPoint(x, y);

I'm finding the idea of introducing (low-profile) selectors like :nth-line(*) very elegant but probably not very efficient. It would probably be easier to define a "element.currentLineBoxes" property returning an immutable non-live copy of the currently defined line boxes. Though it maybe isn't completely true, I'm not an expert on the matter.

What's sure is that a first issue will be to get the group to define what a Box is exactly, and then what we should be able do with it (I suspect getBoxQuads() and getDOMRanges() are two useful candidates). An open question is how many different kind of boxes do we need. Maybe one if sufficient, maybe we need an array of gradually more complex kinds of boxes.

±     // or that of an element not attached to the DOM [1]
±     var containerBox = measureBlock(element, {sizing-info}, {style-info});± 

Once we're there, I think you're right: we should be able to measure an element as if it was a child of a box with the given style properties. However, I would go a bit further by having functions to ask the "minimum width", "minimum preferred width", "maximum preferred width" and "maximum width" of an element without generating a full box tree. Also very important to me would be to get the various boxes flavors (margin-box, border-box, padding-box, content-box) and manipulate boxes quads relative to each other easily.

Moreover, I think we should be able to send to "measureBlock" a collection of DOM ranges and not just an element, even if it requires browser to get the ranges semantics right (kinda like a copy/paste with style information being retained and in the case of replaced elements the intrinsic properties at the very least).

± 2. Creating a layout box and attaching a DOM range to it
± As of now, polyfills trying to simulate fragmentations, such as regions[3] and
± pages[4] are forced to break the DOM into pieces to emulate fragmentainers
± with elements.
± We want to avoid destroying the DOM, which may leads to incompatibility
± with other scripts or difficulty with editing the document.
± A solution to this would be to provide APIs to create a new box not
± associated with an element, style and place it, and attach a DOM range to be
± laid out inside it.
± With such APIs, polyfills would be able to do layout experiments much more
± easily without modifying the DOM.

I like your idea of moving a step further from "measureBlock" and say we should be able to create an anonymous box from an element or a set of dom ranges (like we can for "measureBlock") and then somehow make it render on the page without impacting the DOM. I'm a longtime proponent of extending the "content" property to include slots which could be named by name, like this:

     #SomeElement { content: slot(::before) slot(abc) contents slot(::after) }

... where "abc" would be a slot which may be defined either statically via CSS ("@slot abc { content: ... }") or via scripting ("new CSS.Slot('abc', elementOrArrayOfRanges)").

This would be really useful when making new layout polyfills, where you could magically render a bunch of slots instead of the actual content of an element. The hard thing here would be to forward events back and forth (I think keeping the slot up-to-date should be easier than expected because browsers already have means to detect when a selection needs to be updated/redrawn).

In my opinion, a slot is a kind of "drawable" box, meaning it sits just between the DOM and the Layout tree. I think purely-declarative slots would be a good addition to CSS even without a way to declare them from a script (i.e. we can be incremental here, which is good for implementation progress).

That being said, my current thoughts on this matter are still very open, and I'm really interested into seeing what other people in the task force think about the Box Tree stuff, because I believe some people already have been looking deeper into it than I did.

Kind regards,

± [1] https://wiki.css-houdini.org/explaining-css-layout#measurebox-tree
± [2] http://dev.w3.org/csswg/css-display/#the-display-inside
± [3] https://github.com/FremyCompany/css-regions-polyfill
± [4] https://github.com/fiduswriter/simplePagination.js
± --
± Toru Kawakubo
± Vivliostyle Inc.
± http://vivliostyle.com
Received on Friday, 6 February 2015 18:08:32 UTC

This archive was generated by hypermail 2.4.0 : Friday, 17 January 2020 19:53:22 UTC