1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291
|
<!---
The live version of this document can be viewed at:
https://chromium.googlesource.com/chromium/src/+/main/third_party/blink/renderer/core/layout/README.md
-->
# Blink Layout
The `renderer/core/layout` directory contains the implementation of layout objects.
It covers the following document lifecycle states:
* LayoutSubtreeChange (`InLayoutSubtreeChange` and `LayoutSubtreeChangeClean`)
* PreLayout (`InPreLayout`)
* PerformLayout (`InPerformLayout`)
* AfterPerformLayout (`AfterPerformLayout` and `LayoutClean`)
See [LayoutNG](layout_ng.md) for the implementation details.
The layout code is maintained by the
[layout team](http://dev.chromium.org/teams/layout-team).
## Box model
[The CSS box model](https://www.w3.org/TR/css-box-3/#the-css-box-model) is based
on a series of nested boxes, from outside to inside:
* Margin box
* Border box: the main coordinate space of a `LayoutBox`
* Padding box: a.k.a. client box
* Content box
When there are non-overlay scrollbars, according to [css-overflow-3](https://www.w3.org/TR/css-overflow-3/#scrollbar-layout),
they should be inserted between the inner border edge and the outer padding edge.
The following graph is modified from the graph in the css box model spec, showing
scrollbars:
|-------------------------------------------------|
| |
| margin-top |
| |
| |---------------------------------------| |
| | | |
| | border-top | |
| | | |
| | |--------------------------|--| | |
| | | | | | |
| | | padding-top |##| | |
| | | |##| | |
| | | |----------------| |##| | |
| | | | | | | | |
| ML | BL | PL | content box | PR |SW| BR | MR |
| | | | | | | | |
| | | |----------------| | | | |
| | | | | | |
| | | padding-bottom | | | |
| | | | | | |
| | |--------------------------|--| | |
| | | scrollbar height ####|SC| | |
| | |-----------------------------| | |
| | | |
| | border-bottom | |
| | | |
| |---------------------------------------| |
| |
| margin-bottom |
| |
|-------------------------------------------------|
BL = border-left
BR = border-right
ML = margin-left
MR = margin-right
PL = padding-left
PR = padding-right
SC = scroll corner
SW = scrollbar width
Note that the vertical scrollbar (if existing) will be on the left in right-to-left
direction horizontal writing-mode. The horizontal scrollbar (if existing) is always
at the bottom.
## Scroll origin vs. offset vs. position
When a LayoutBox has scrollable overflow, it is associated with a PaintLayerScrollableArea.
PaintLayerScrollableArea uses a "scroll origin" to represent the location of the top/left
corner of the content rect (the visible part of the content) in the coordinate system
defined by the top/left corner of the overflow rect, when the box is scrolled all the way
to the beginning of its content.
For content which flows left-to-right and top-to-bottom, the scroll origin will be (0, 0),
i.e., the top/left of the content rect is coincident with the top/left of the overflow rect
when the box is scrolled all the way to the beginning of content.
For content which flows right-to-left (including direction:ltr, writing-mode:vertical-rl,
and flex-direction:row-reverse), the x-coordinate of the scroll origin will be positive;
and for content which flows bottom-to-top (e.g., flex-direction:column-reverse and
vertical writing-mode with direction:ltr), the y-coordinate of the scroll origin will be
positive.
In all cases, the term 'scrollOffset' (or just 'offset') is used to represent the distance
of the scrolling viewport from its location when scrolled to the beginning of content, and
it uses type ScrollOffset. The term 'scrollPosition' (or just 'position') represents a
point in the coordinate space defined by the overflow rect, and it uses type gfx::PointF.
For illustrations of these concepts, see these files:
doc/ltr-tb-scroll.png
doc/rtl-bt-scroll.png
doc/rtl-tb-scroll.png
When computing the scroll origin, if the box is laid out right-to-left and it has a scrollbar
for the orthogonal direction (e.g., a vertical scrollbar in a direction:rtl block), the size
of the scrollbar must be added to the scroll origin calculation. Here are two examples --
note that it doesn't matter whether the vertical scrollbar is placed on the right or left of
the box (the vertical scrollbar is the `|/|` part):
content
rect
|<-------->|
scroll
origin
|----------->|
_______________________
| |/| |
| |/| |
| |/| |
direction:rtl | |/| box |
| |/| |
| |/| |
|__________|/|__________|
overflow rect
|<--------------------->|
content
rect
|<-------->|
scroll
origin
|----------->|
_________________________
| | |/|
| | |/|
| | |/|
writing-mode: | | box |/|
vertical-rl | | |/|
| | |/|
|____________|__________|/|
overflow rect
|<--------------------->|
## Coordinate Spaces
Layout and Paint work with and frequently refer to four coordinate spaces
(really two, with two variants):
* Physical coordinates: Corresponds to physical direction of the output per the
physical display (screen, printed page). Generally used for painting, thus
layout logic that feeds into paint may produce values in this space. CSS
properties such as `top`, `right`, `bottom`, and `left` are in this space.
* Logical coordinates: Used in layout to allow for generalized positioning that
fits with whatever the `writing-mode` and `direction` CSS property values may
be. Properties named with `before`, `after`, `start` or `end` are in this
space. These are also known respectively as 'logical top', 'logical bottom',
'logical left', and 'logical right'.
* Logical coordinates without flipping inline direction: those are "logical
block coordinates", without considering text direction. Examples are
"LogicalLeft" and "LogicalRight".
Example with `writing-mode: vertical-rl; direction: ltr`:
'top' / 'start' side
block-flow direction
<------------------------------------ |
------------------------------------- |
| c | s | |
'left' | o | o | | inline 'right'
/ | n | m | | direction /
'after' | t | e | | 'before'
side | e | | | side
| n | | |
| t | | |
------------------------------------- v
'bottom' / 'end' side
Another example -- consider a relative-positioned element:
<style>
html {
writing-mode: vertical-rl;
}
</style>
<div id="container" style="background-color: lightBlue; width: 300px; height: 200px;">
<div id="relpos" style="position: relative; top: 50px; left: -60px; width: 70px; height: 80px; background-color: red;"></div>
</div>
The final location of these within an 800x600 frame is as:
container: (492, 8 300x200)
relpos: (662, 58 70x80)
The 8px is the default margin of HTML body element
per https://html.spec.whatwg.org/multipage/rendering.html#the-page,
which is specified in ../html/resources/html.css.
See the [diagram](resources/flipped-blocks-relpos.svg) for full detail on
dimensions of the involved elements.
For more examples of writing mode and direction combinations, see this
[demo page](http://pauljadam.com/demos/csstext.html) though note `horizontal-bt`
is obsolete.
### Containing block vs container
Note there are two primary similar, but slightly different, methods regarding
finding the containing block for an element:
* `LayoutObject::Container()` which returns the containing block for an element
as defined by CSS.
* `LayoutObject::ContainingBlock()` which returns the enclosing non-anonymous
block for an element. If the containing block is a relatively positioned inline,
it returns that inline's enclosing non-anonymous block.
There are other containing block methods in `LayoutObject` for special purposes
such as fixed position, absolute position, and paint invalidation. Code will
sometimes just refer to the 'containing' element, which is an unfortunately
ambiguous term. Paying close attention to which method was used to obtain the
containing element is important.
## Geometry mapping
TODO(wkorman): Elaborate on:
* `mapToVisualRectInAncestorSpace()`
* `mapAncestorToLocal()`
* `Widget` and `FrameView` trees. Note the former will be done away with at some
point per http://crbug.com/637460.
* `GeometryMapper` (or just point to its section in paint README). For now, see
the
[Web page geometries](https://docs.google.com/document/d/1WZKlOSUK4XI0Le0fgCsyUTVw0dTwutZXGWwzlHXewiU/preview)
design document.
## Scrolling
TODO(wkorman): Provide an overview of scrolling. For now, the BlinkOn talk
on
[Scrolling in Blink](https://docs.google.com/presentation/d/1pwx0qBW4wSmYAOJxq2gb3SMvSTCHz2L2TFx_bjsvm8E/preview)
is a good overview.
*Root layer scrolling* is an ongoing refactoring of Blink's scrolling
architecture, which makes the root `PaintLayer` responsible for the scrolling
that was previously done by `FrameView`. For more details, see:
[Root Layer Scrolling](https://bit.ly/root-layer-scrolling).
## Glossaries
Here we provide a brief overview of key terms relevant to box flow, inline flow,
and text orientation. For more detail see
[CSS Writing Modes Level 3](https://www.w3.org/TR/css-writing-modes-3/).
The
[CSS Logical Properties Level 1](https://drafts.csswg.org/css-logical-props/)
specification represents the latest CSSWG thinking on logical coordinate space
naming. CSSWG has standardized on `block-start`, `block-end`, `inline-start`,
and `inline-end`, or just `start` and `end` when the axis is either implied or
irrelevant.
Note that much of the Blink code base predates the logical properties
specification and so does not yet reference logical direction consistently in
the stated manner, though we would like to head in that direction over time.
See also the *physical*, *flow-relative*, and *line-relative*
[abstract box terminology](https://www.w3.org/TR/css-writing-modes-3/#abstract-box)
specification.
* `writing-mode`: either horizontal or vertical, with vertical having either
left-to-right or right-to-left block flow. Geometry is transposed for vertical
writing mode. See calls to `transposed{Rect,Point,Size}()`.
* `direction`/`dir`: "inline base direction" of a box. One of `ltr` or
`rtl`. See calls to `isLeftToRightDirection()`.
* `text-orientation`: orientation of text in a line. Only relevant for vertical
modes.
* orthogonal flow: when a box has a writing mode perpendicular to its containing
block. This can lead to complex cases. See
[specification](https://www.w3.org/TR/css-writing-modes-3/#orthogonal-flows)
for more.
|