Skip to content

Commit 46ce4a1

Browse files
committed
[css-layout-api] Create a README.md for the layout api.
1 parent f7c8a38 commit 46ce4a1

File tree

1 file changed

+115
-0
lines changed

1 file changed

+115
-0
lines changed

css-layout-api/README.md

+115
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
# CSS Layout API
2+
3+
The CSS Layout API is designed to give authors the ability to write their own layout algorithms in
4+
additon to the native ones user agents ship with today.
5+
6+
For example the user agents currently ship with
7+
- Block Flow Layout
8+
- Flexbox Layout
9+
10+
With the CSS Layout API, authors could write their own layouts which implement
11+
- Constraint based layouts
12+
- Masonary layouts
13+
- Line spacing + snapping
14+
15+
### Concepts
16+
17+
##### The `Box`
18+
19+
A `Box` refers to a CSS box, that is a node that has some sort of style. This can refer to:
20+
21+
- An element with an associated style, (an element that has `display: none` for these purposes does
22+
not have a style).
23+
24+
- The `::before` and `::after` pseudo elements with an associated style, (note for layout purposes
25+
the `::first-letter`, `::first-line`, `::selection` are *not* independent boxes, they are more a
26+
special kind of selector that can override style on *part* of another box).
27+
28+
- A `TextNode` with some style.
29+
30+
This is effectively the DOM tree but with some extra things. One important thing to node is that a
31+
`Box` doesn't have any layout information, it is the _input_ to layout.
32+
33+
For the layout API specifically a box is represented like:
34+
35+
```webidl
36+
interface Box {
37+
readonly attribute StylePropertyMapReadonly styleMap;
38+
FragmentRequest doLayout(ConstraintSpace space, OpaqueBreakToken breakToken);
39+
};
40+
```
41+
42+
The `styleMap` contains the required computed style for that `Box`.
43+
44+
##### The `Fragment`
45+
46+
A `Fragment` refers to a CSS fragment, that is it is the part of the layout result of a box. This
47+
could be for example:
48+
49+
- A whole box which has undergone layout. E.g. the result of laying out an `<img>` tag.
50+
51+
- A portion of a box which has undergone layout. E.g. the result of laying out the first column of
52+
a multicol layout. `<div style="columns: 3"></div>`
53+
54+
- A portion of a `TextNode` which has undergone layout, for example the first line, or the first
55+
portion of a line with the same style.
56+
57+
- The `::first-letter` fragment of a `TextNode`.
58+
59+
One can think of this as the _leaf_ representation you can get out of:
60+
```js
61+
let range = document.createRange();
62+
range.selectNode(element);
63+
console.log(range.getClientRects());
64+
```
65+
66+
For the layout API specifically a fragment is represented like:
67+
68+
```webidl
69+
interface Fragment {
70+
readonly attribute double inlineSize;
71+
readonly attribute double blockSize;
72+
73+
attribute double inlineStart; // inlineOffset instead?
74+
attribute double blockStart;
75+
76+
readonly attribute sequence<Box> unpositionedBoxes;
77+
78+
readonly attribute OpaqueBreakToken? breakToken;
79+
80+
readonly attribute BaselineOffset dominantBaseline;
81+
readonly attribute BaselineOffset? ideographicBaseline;
82+
// other baselines go here.
83+
};
84+
```
85+
86+
### Performing Layout
87+
88+
The Layout API is best described with a simple dummy example:
89+
90+
```js
91+
registerLayout('really-basic-block', class {
92+
*layout(constraintSpace, children, styleMap, opt_breakToken) {
93+
let inlineSize = 0;
94+
let blockSize = 0;
95+
const childFragments = [];
96+
97+
for (let child of children) {
98+
let fragment = yield child.doLayout(constraintSpace);
99+
blockSize += fragment.blockSize;
100+
inlineSize = Math.max(inlineSize, fragment.inlineSize);
101+
childFragments.push(fragment);
102+
}
103+
104+
return {
105+
inlineSize: inlineSize,
106+
blockSize: blockSize,
107+
children: childFragments,
108+
};
109+
}
110+
});
111+
```
112+
113+
The first thing to notice about the API is that the layout method on the class returns a generator.
114+
115+
TODO finish writing this.

0 commit comments

Comments
 (0)