v0.15.1
Flexbox layout is ~15-20% faster for deep trees.
- Fewer allocations and passes over flex items (#1327, #1328, #1333, #1336, #1343).
- Items stretched to a single line of definite cross size are no longer measured for their hypothetical cross size (#1332).
- Containers with no absolutely or fixed positioned children skip the out-of-flow layout pass (#1337).
CompactLength::is_length_percentage_or_calc()(#1320).
TaffyTree: reset the rounded layout of out-of-flow boxes in subtrees hidden withdisplay: none(#1358).- Block/float: apply
position: relativeinsets to floated boxes (#1305). - Block/float: don't clamp the first float of a block formatting context to the top of the context (#1304).
- Block/float: make a float that extends below all earlier floats constrain later floats and boxes over its full height (#1304).
- Block/Grid: don't move the container's baseline by the relative offset of the child that provides it (#1323).
- Flexbox: clamp a column container's baseline taken from a scroll container item to the item's border box (#1323).
- Flexbox: fix the intrinsic main size of containers with negative main-axis margins on items with no content size (#1335).
- Grid: take the container's baseline from the final layout of the item that provides it (#1322).
- Grid: don't resolve a form control's percentage max size against zero in its minimum contribution (#1351).
- Grid: count
calc()track sizes as fixed sizing functions inauto-fill/auto-fitrepetitions (#1320).
v0.15.0
The MSRV for this release is 1.71.
Support for position: static and position: fixed, and hoisting absolute/fixed boxes (#1140, #1194, #1204, #1205)
Position gains Static and Fixed variants, and Position::Static is now the default (matching CSS).
Statically positioned boxes are laid out like relatively positioned boxes, but ignore their inset styles: if you relied on insets applying under the old default then you will need to explicitly set position: Position::Relative.
Absolutely and fixed positioned boxes are now hoisted to their "containing block" like they are on the web, rather than always being laid out by their immediate parent. Boxes with auto insets are placed at their static position: where they would have been placed in their parent's normal flow. Custom tree implementations need to implement some new trait methods and call compute_oof_layout to support this (for users of TaffyTree, this is built-in).
Absolutely positioned boxes now support align-self and justify-self (as specified in css-position §3.8), and in-flow children of block containers now support justify-self.
normal is now a first-class alignment keyword. As a result, the align_items, justify_items, align_content and justify_content styles are no longer wrapped in Option: replace Some(AlignItems::CENTER) with AlignItems::CENTER, and None with AlignItems::NORMAL.
Grid layout is now ~60% faster, and Flexbox layout ~15% faster.
Containers asked only for their size in one axis now return as soon as that size has been determined (#1219, #1221), and Grid avoids measuring items whose contributions cannot affect the size of any track or whose size is already known (#1177, #1222, #1229), along with various other optimizations (#1200, #1225, #1226, #1253, #1263, #1264).
Taffy previously supported a no-std, no-alloc mode that used fixed-sized arrays. This was always of questionable utility, only ever supported Flexbox, and added maintenance burden to Taffy. It has now been removed. No-std-with-alloc remains supported.
- BREAKING:
Position::Staticis now the defaultposition. Static boxes ignore theirinsetstyles (#1140). - BREAKING:
Layout::locationof an absolutely positioned box is now relative to its containing block's border box rather than its parent, and the box contributes to the scrollable overflow of its containing block rather than its parent (#1194). - BREAKING:
Style::align_items,justify_items,align_contentandjustify_content(and the corresponding style trait getters) are no longer wrapped inOption.align_selfandjustify_selfremainOptions in whichNonerepresentsauto(#1254, #1255). - BREAKING: With the
serdefeature,align_items,justify_items,align_contentandjustify_contentserialize as"Normal"rather thannull, and no longer deserialize fromnull(#1254, #1255). - BREAKING:
CoreStyle::is_compressible_replaced()now covers form controls such as<input>and<select>as well as replaced elements. Use the newis_replaced()for replaced elements alone (#1256). - BREAKING: A definite
LayoutInput::available_spaceis now always the space available to the node's border box: parents subtract the child's margins, andcompute_leaf_layoutandcompute_flexbox_layoutno longer subtract the node's own margins (#1234). - BREAKING: Custom trees must call
compute_oof_layouton the output of a layout algorithm inside theircompute_cached_layoutclosure: layout algorithms now only collect absolutely positioned candidates (#1194). - BREAKING:
compute_oof_layoutandcompute_root_layoutrequire the newLayoutContainingBlocktree trait, andcompute_root_layoutnow also requiresCacheTree(#1194). - BREAKING:
RoundTreegainsis_out_of_flow,hoisted_child_countandget_hoisted_child_idmethods (#1194). - BREAKING:
LayoutOutputis no longerCopy, and gains anoof_positioning_areafield (#1194). - BREAKING:
DetailedLayoutInfois now generic over the string type, and detailed layout info is no longer gated behind thedetailed_layout_infofeature (which is now a no-op) (#1194). - BREAKING:
CompactLengthtag values have been reassigned, which changes the numeric values of the*_TAGconstants and theserderepresentation ofpercent,frand sizing keyword values (#1246). - BREAKING:
CompactLength::is_calc()has been renamed tois_plain_calc(). Usehas_calc()to also matchfit-content(calc())(#1247). - BREAKING:
DetailedGridInfo's track-list serializers take azoomargument (pass1.0for the previous behaviour) (#1280). - BREAKING:
DetailedGridTracksInfogains a publiccollapsed_tracksfield, recording collapsedauto-fittracks (#1266). compute_root_layoutnow uses an initial containing block with the size of the viewport (the definiteavailable_space) rather than the root's padding box, and respects the root's ownposition,insetand margins (#1204, #1205).Style::align_selfandStyle::justify_selfare no longer gated behind theflexbox/gridfeatures (#1206).DetailedGridInfoline names no longer include the implicit<area>-start/<area>-endnames generated bygrid-template-areas, matching browsers' serialization ofgrid-template-rows/grid-template-columns(#1185).- Block:
Layout::marginof an in-flow block child now holds the child's own margins rather than the result of collapsing them with its descendants' margins (#1287). round_layoutnow rounds positions in cumulative coordinates, so rounded children always tile exactly within their rounded parent (#1189).
Position::FixedandPosition::Sticky. Sticky positioning is not implemented: sticky boxes are laid out likestaticboxes, except that they act as a containing block for absolutely positioned descendants (#1140).AlignItemsKeyword::NormalandAlignContentKeyword::Normal(#1254, #1255).AlignmentSafety::Default, representing the absence of asafe/unsafekeyword, which is used by the bare constants likeAlignItems::START. It behaves likeUnsafeexcept for absolutely positioned boxes: use!is_safe()rather than matching onUnsafeto detect "not safe" (#1206).CoreStyle::is_containing_block(), which can be overridden to make properties such astransformorfilterestablish a containing block (#1194).TaffyTree::hoisted_children, which returns the absolutely positioned boxes for which a node is the containing block (#1194).compute_oof_layout,compute_oof_layout_for_area,resolve_static_offset,AxisStaticPositionand theOofItemStylestyle trait (#1194, #1206).CoreStyle::is_replaced(),Style::item_is_replacedandStyle::item_is_compressible_replaced(#1256).BlockItemStyle::align_content: block children with a non-normalalign-contentnow establish an independent formatting context (#1251).compute_block_align_content_offset, for integrations which lay out inline content outside of Taffy (#1251).AlignItems::with_safetyandAlignContent::with_safety(#1206).Defaultimplementations for the alignment types, andAlignSelf::is_stretch_or_normal(#1254, #1255).fit-content()now accepts acalc()limit (Dimension::fit_content_calc,MaxTrackSizingFunction::fit_content_calc) (#1247).transpose()methods onSize,Rect,RequestedAxis,LayoutInputandLayoutOutput, for tree implementations laying out vertical writing modes (#1265).
- BREAKING: The heapless (no
stdoralloc) build mode. Taffy now always requiresalloc, and theallocfeature is retained as a no-op (#1199).
- Cache: don't reuse results computed with a different
sizing_modeor margin collapsibility (#1214). TaffyTree::removeandTaffyTree::clearnow drop the removed nodes' contexts (#1181).- The
serdefeature now compiles without thestdfeature (#1199). - Absolute positioning: only resolve
automargins against free space in an axis where both insets are set (#1202). - Absolute positioning: don't stretch
auto-sized replaced elements between their insets (#1203). - Absolute positioning: exclude insets from the space available to shrink-to-fit boxes (#1234).
- Absolute positioning: apply
safestatic alignment within the inset-modified containing block (#1267). - Block/float: absorb
f32rounding errors in horizontal fit checks (#1161). - Block: floor the content width and children's available and stretch widths at zero (#1178).
- Block: don't use a container's own height as the percentage basis for its children when measuring its content size (#1183).
- Block: resolve children's vertical percentage padding and border against the container's width (#1187).
- Block: decide whether margins collapse through a box using its used height (#1188).
- Block: treat collapsible margins as zero when resolving
height: stretch(#1242). - Block/float: propagate the height of floats in a child relative to the child's final position (#1251).
- Block/float: include float-avoidance offsets in the used
automargins of boxes beside floats (#1252). - Block/float: floor child context widths at padding + border (#1279).
- Flexbox: include main-axis margins in intrinsic contributions floored by the flex basis (#1164).
- Flexbox: don't wrap auto-height column containers against available space from an ancestor (#1176).
- Flexbox: clamp the max-content contribution of column items by their flex base size alone (#1183).
- Flexbox/Grid: floor the stretch size and available space of items at zero (#1178).
- Flexbox: measure items at their min/max-clamped cross size when computing the container's intrinsic main size (#1208).
- Flexbox: resolve vertical percentage padding and border against the container's width (#1209).
- Flexbox: treat percentage flex bases as
contentwhen the container's main size is indefinite (#1286). - Grid: fix edge cases in
resolve_absolute_grid_area(#1167). - Grid: don't create phantom implicit tracks for
autostart / definite end placements (#1169). - Grid: resolve the static position of out-of-flow children against the grid's content box (#1194).
- Grid: include out-of-flow boxes placed in a grid area in their containing block's scrollable overflow (#1205).
- Grid: fix stale item contributions and wrong axis in the track sizing re-run checks (#1227).
- Grid: only consider spanned tracks when determining an item's automatic minimum size (#1228).
- Grid: subtract an item's margins from its available space when computing its intrinsic contributions (#1234).
- Grid: resolve percentage tracks and gaps against the container size when it was initially indefinite (#1243, #1244).
- Grid: only distribute growth limit space to infinitely growable tracks, capped by
fit-content()limits (#1245). - Grid: resolve cyclic percentages in an item's minimum size against zero (#1257).
- Grid: fix resolution of named lines and named spans in grid placement (#1258, #1259, #1264).
- Grid: treat percentage min track sizing functions as
autowhen the container size is indefinite (#1261). - Grid: fix sparse auto-placement of items with a definite row or column (#1263).
- Grid: exclude collapsed
auto-fitgutters when resolving grid areas for absolutely positioned boxes (#1266). - Grid: floor clamped automatic minimum sizes at padding + border (#1278).
- Grid: don't stretch replaced items under
normalalignment (#1281). - Grid: clamp a definite preferred size by min/max sizes in an item's minimum contribution (#1282).
- Grid: use the min-content contribution as the minimum contribution of items sized with a sizing keyword (#1283).
- Grid: don't size flexible tracks to zero under a block-axis min-content constraint (#1284).
v0.14.0
The MSRV for this release is 1.71.
The width, height and flex-basis properties now support min-content, max-content, fit-content, fit-content(), and stretch keywords. flex-basis additionally supports the content keyword. The min-width/max-width (and height) properties have been switched to use LengthPercentageAuto rather than Dimension, as they do not yet support these keywords.
Taffy now supports flex-wrap: balance and flex-line-count from CSS Flexbox Level 2, behind the default flexbox_balance feature.
See Balancing Text in CSS: The Flex-Wrap Last Row Problem for an explainer.
The layout effects of contain: layout, contain: paint, and contain: content are now supported, including independent formatting contexts, baseline suppression, and overflow containment. contain: size is not yet supported.
DetailedGridTracksInfo'sguttersandsizesfields are replaced by a singlepositionsvec.positionscontains the offset of every grid line in the implicit grid. This allows it to account for offsets introduce by content-alignment. And also allows for O(1) access to grid area sizes.- All data in
DetailedGridTracksInfois now stored in logical order (so right-to-left fordirection: rtlgrids) - Added
DetailedGridInfo::resolve_absolute_grid_areawhich can resolve a grid area for an item given it's position styles. This is useful for positioning hoisted absolutely positioned boxes relative to a grid containing block. - Added
grid_template_rowsandgrid_template_columnsmethods which serialize those properties into a string according to the CSS standard.
Caching logic is now more correct (#1010, #1155)
- Tagged-pointer style types now have
expand()methods that expose their values as plain enums (#1129). Layout::content_sizeis nowscrollable_overflow_rect: Rect<f32>. Itsrightandbottomfields replace the old width and height values;scroll_width()andscroll_height()are unchanged (#1118).LayoutOutput::first_baselinesis nowbaselines: Baselines, withfirstandlastbaseline fields (#1107).Style::min_sizeandmax_sizenow useLengthPercentageAutorather thanDimension(#1099).compute_layout_with_measurenow passes aLayoutInputand returnsLayoutOutput; callcompute_leaf_layoutexplicitly to preserve the old leaf-measurement behaviour (#1091).- Block and Flexbox no longer measure absolutely positioned children whose dimensions are already known (#1120).
CacheTree::cache_getandCache::getnow take&mut self, and the measure cache uses second-chance (clock) eviction (#1010).
- Cache: prevent axis-specific measurements from being reused for the wrong axis and avoid caching margin-collapse metadata (#1010).
- Flexbox: fix intrinsic sizing with negative margins and zero flex bases (#1152).
- Flexbox: apply inherent style sizing on top of content-size measurements (#1155).
- Flexbox: transfer definite stretched cross sizes through aspect ratios when calculating flex base sizes (#1155).
- Block/float: account for
clearwhen computing the intrinsic width of floats (#1150). - Flexbox: generate container baselines from the visually startmost line or item in reverse layouts (#1127).
- Block/Grid: clamp scroll-container baselines to the border box and synthesize missing Block baselines (#1108, #1126).
- Flexbox/Grid: exclude items with auto cross-axis margins from baseline alignment (#1109, #1125).
- Grid: exclude items with cyclic percentage block sizes from baseline alignment (3dbf2e46b).
- CSS parser: preserve unnamed grid lines when parsing
grid-template-rowsandgrid-template-columns(#1138). - Block/float: don't include overflowing in-flow content in the float contribution to a BFC's height (#1128).
- Block: resolve percentage heights and relative vertical insets against the correct definite height (#1122).
- Block: prevent bottom-margin collapsing when
min-heightdetermines the used height (#1082). - Block: resolve percentage padding and borders against the containing block's width (#1083).
- Block: resolve absolutely positioned auto margins against the clamped used size (#1096).
- Block/float: apply non-
normalalign-contentto formatting contexts and floated children (#1087, #1089). - Flexbox: correctly track definite sizes through nested layouts and percentage-sized descendants (#1003, #1123).
- Flexbox: don't distribute free space through
justify-contentafter auto margins consume it (#1115). - Flexbox: skip unnecessary automatic min-content measurements (#1119).
- Block/Flexbox/Grid: correct scrollable overflow handling for start-side overflow, RTL, and end padding (#1114, #1116, #1117).
TaffyTree::removenow marks the former parent dirty (#1085).- Grid: fix named-line numbering for repetitions and validate their line-name counts (#1035).
- Grid: prevent infinite loops during track sizing and auto-placement (#1036, #1037).
- Flexbox: wrap indefinite containers against their maximum main size (#1101).
- Grid: don't skip intrinsic sizing for tracks with an intrinsic minimum and fixed maximum (#1097).
- Grid: correctly distribute content contributions across flexible tracks (#1084).
v0.13.0
The MSRV for this release is 1.71.
-
Support for the
self-startandself-endalignment keywords (AlignItems::SELF_START/SELF_ENDand safe variants). These resolve against thedirectionof the item itself rather than that of its container, so they only differ fromstart/endwhen the item's direction differs from its container's. Supported foralign-self/align-itemsandjustify-self/justify-itemson both in-flow and absolutely positioned Flexbox and Grid items (#1074) -
Support for
display: flow-root. The newDisplay::FlowRootvariant lays out children using the block layout algorithm but always establishes a new block formatting context (its margins do not collapse with those of its children, it contains its own floats, and it avoids external floats)
- Numeric style helpers (
length,percent,fr,flex) now acceptInput: Into<f64>instead ofInput: Into<f32>. This allows bare float literals such aslength(800.0)to be used without triggering thefloat_literal_f32_fallbackfuture-compatibility lint, while widening the set of accepted numeric input types (#974) - Grid:
grid_template_areasis nowOption<GridTemplateAreas<S>>, where the newGridTemplateAreasstruct includesrow_count/column_countfields. This allows templates containing unnamed (.) cells beyond the extents of the named areas (e.g.grid-template-areas: "a .") to be represented. - Block/float:
BlockContext::place_floated_boxtakes an additionaladjoins_unresolved_strut: boolparameter indicating whether the float is being placed while the position of the current margin-collapse strut is still unresolved
A large number of miscelaneous bug fixes are included in this release:
- Flexbox: clamp the flex base size, automatic minimum size and hypothetical main/cross sizes with min/max sizes transferred through the aspect ratio, instead of baking them into the item's used min/max sizes (#989)
- Flexbox: resolve
justify-content: start/endandalign-self: start/end/self-start/self-endas writing-mode relative (rather than flex-relative) in the static position of absolutely positioned children; use the flex-relative start forjustify-content: space-between/normal, and a fallback ofstartforalign-self: baseline(#1072) - Flexbox: only let
automargins on absolutely positioned children absorb free space when the box is inset-constrained in that axis; otherwise they resolve to zero per CSS2 §10.3.7/§10.6.4 (#1072) - Grid: jump the auto-placement search past entire colliding occupied intervals rather than advancing one track at a time (#1038)
- Grid: resolve the grid lines used by absolutely positioned items to the edges of the adjacent tracks, so that free space distributed by
align-content/justify-contentis not included in the abspos grid area (#1071) - Grid: exclude absolutely positioned children from the implicit grid size estimate, as they do not take part in grid placement and must not create implicit tracks. Previously their out-of-range lines resolved to phantom implicit tracks instead of being treated as
auto(#1075) - Grid: align an empty grid (one whose tracks have all collapsed) within its container, rather than always placing it at the start (#1078)
- Grid: only distribute space "beyond limits" to tracks whose max track sizing function is
max-content(orfit-content()) (#1033) - Grid: don't clamp an explicitly specified preferred or minimum size by the spanned tracks' fixed max track sizing functions when computing an item's minimum contribution (#1022)
- Grid: ignore the tracks' growth limits when distributing an item's intrinsic size contribution "beyond limits" (#1022)
- Grid: convert the container's min/max size to a content-box size before using it in the track sizing algorithm (#1023)
- Grid: compute the flex factor sum over only the spanned tracks eligible to receive space when distributing intrinsic size contributions to flexible tracks (#1019)
- Grid: don't grow tracks past their growth limits when distributing free space to multiple tracks with asymmetric limits (#1001)
- Block/Grid: measure
Layout::content_sizefrom the container's padding-box origin and include the container's own end-side padding, matching Flexbox and browserscrollWidth/scrollHeightsemantics. Grid items in tracks that overflow the container now also contribute their position within the container, not just their own size (#1051) - Block: don't stretch-size replaced elements; an auto width now resolves to the intrinsic size (#1002)
- Block: don't let boxes that establish an independent formatting context overlap floats: they narrow to fit beside the float, or move down below it if they don't fit (#991)
- Block: detect floats placed by the subtree of a preceding in-flow sibling, not just floats among direct siblings, when placing a box that establishes an independent formatting context (#1049)
- Block: apply a negative margin as usual on a BFC root's float-free side, instead of clamping it to the containing block edge (#1061)
- Block: compute clearance from the hypothetical position of the cleared element (including its collapsed top margin), supporting negative clearance (#1042)
- Block: prevent the cleared element's top margin from collapsing with preceding margins and with the parent's top margin (#1043)
- Block: force clearance for floats placed while the position of the enclosing margin-collapse strut is unresolved, and position such floats including the pending collapsible margins (#1046)
- Block: collapse the top and bottom margins of a self-collapsing element with clearance with each other and apply them inside the parent, rather than collapsing them with the parent's bottom margin (#1044)
- Block/float: treat
clearas a no-op when no float has been placed on the relevant side(s) (#1041) - Block: allow elements containing only floated children to be collapsed through (#1040)
- Block/float: record zero-width floats in the float context, so their edge acts as an obstacle for boxes establishing an independent formatting context (#1062)
- Block/float: a float establishes a new block formatting context, so its margins no longer collapse with the margins of its children (#1065)
- Block/float: honour CSS2 §9.5.1 rules 3 & 7 when placing floats: a float unconstrained by other floats may overflow its containing block, but one placed beside another float may not (#1064)
- Block/float: apply CSS2 §9.5.1 rule 5 (float ceiling) and
clearpast zero-sized floats, which occupy no float segment and so were previously ignored when positioning later floats and cleared elements (#1056) - Block/float: sum float contributions when computing a float container's intrinsic width under definite available space (clamped between the widest single float and the available width), instead of dropping them entirely (#1055)
v0.12.1
This release container a couple of critical fixes for layout/caching bugs in the 0.12.0 release.
- Block: don't commit deferred in-flow layouts to the tree when only computing size (#971)
- Block: pass through the requested
run_modewhen performing final layout on in-flow children, instead of always usingMeasureSize(#972)
v0.12.0
The MSRV for this release is 1.71.
Block containers now implement align_content along the block axis for their in-flow children.
- The cache key now includes the axis, parent size, and available space, and ignores available space in an axis when a known dimension is set there. This is a performance hit (~10% in common cases, ~60% in pathalogically ones) but is necessary for correctness. It does also enable early-return optimizations (in cases where only the horizontal size is needed, which can allow that performance to be recouped in some cases (#911)
- Flexbox: fall back to safe
align-selfofstarton absolute-position overflow (#958) - Block: derive definite height from
aspect-ratioat final layout. A block container withaspect-ratioand an automatic height now becomes definite when its width is filled/stretched, so children's percentage heights resolve correctly and the ratio is preserved (#965)
v0.11.0
The MSRV for this release is 1.71.
Taffy now implements safe alignment (in addition to unsafe alignment).
The alignment style types are now structs consisting of an AlignmentKeyword and an AlignmentSafety modifier. For most users this will mean changing from using enum variants like AlignContent::Start to associated constants like AlignContent::START.
This change applies to the AlignContent, JustifyContent, AlignItems, JustifyItems, AlignSelf, and JustifySelf types.
- Grid: resolve item percentages against grid area rather than grid container (#960)
v0.10.0
The MSRV for this release is 1.71.
The direction property is now supported, allowing for RTL layout of boxes in Block, Flexbox, and CSS Grid layout modes.
The float and clear properties are now supported. Support consists of a general-purpose FloatContext in the compute module, and integration of float layout into Block layout. Block layout now also has a BlockContext that allows a FloatContext to be shared across an entire Block formatting context.
Float support is feature flagged by the float_layout feature.
All of Taffy's style types (except the top-level Style struct) now have FromStr implementations that parses the type from the CSS representation of that value (e.g. 30px or 50% for LengthPercentage. A future version of Taffy will likely add support for parsing Style from ;-seperated CSS.
CSS parsing is feature flagged by the parse feature.
- Make
DetailedGridTracksInfostruct accessible from a public module (#899) - Add
TaffyTree::write_treemethod to debug print the tree into an arbitrary writer (#925) - The cache
setandsetAPIs now take&LayoutInputrather than individual values (#933)
- Flexbox: apply gap even when there are auto margins (#938)