Separate contained grid contributions from stretch

This commit is contained in:
SGavrl committed 2026-07-31 00:34:56 +00:00
1 parent fadf4a7ac8
commit ef4be1b5d9
5 files changed
+148 -26

No files matched your search

+17
View File
@@ -31,6 +31,8 @@ pub(in super::super) struct GridItem {
/// Is it a compressible replaced element?
/// https://drafts.csswg.org/css-sizing-3/#min-content-zero
pub is_compressible_replaced: bool,
/// Whether descendants are ignored for intrinsic size contributions in each axis.
pub intrinsic_size_containment: Size<bool>,
/// The item's overflow style
pub overflow: Point<Overflow>,
/// The item's box_sizing style
@@ -108,6 +110,7 @@ impl GridItem {
row: row_span,
column: col_span,
is_compressible_replaced: style.is_compressible_replaced(),
intrinsic_size_containment: style.intrinsic_size_containment(),
overflow: style.overflow(),
box_sizing: style.box_sizing(),
size: style.size(),
@@ -425,6 +428,13 @@ impl GridItem {
available_space: Size<Option<f32>>,
) -> f32 {
let known_dimensions = self.known_dimensions(tree, grid_area_size);
if self.intrinsic_size_containment.get(axis) {
let padding =
self.padding.resolve_or_zero(grid_area_size.width, |val, basis| tree.calc(val, basis));
let border =
self.border.resolve_or_zero(grid_area_size.width, |val, basis| tree.calc(val, basis));
return known_dimensions.get(axis).unwrap_or((padding + border).sum_axes().get(axis));
}
// The child sees the grid area as its containing block during intrinsic measurement, so
// percentage box properties resolve against the grid area when that size is definite.
// Spec:
@@ -469,6 +479,13 @@ impl GridItem {
available_space: Size<Option<f32>>,
) -> f32 {
let known_dimensions = self.known_dimensions(tree, grid_area_size);
if self.intrinsic_size_containment.get(axis) {
let padding =
self.padding.resolve_or_zero(grid_area_size.width, |val, basis| tree.calc(val, basis));
let border =
self.border.resolve_or_zero(grid_area_size.width, |val, basis| tree.calc(val, basis));
return known_dimensions.get(axis).unwrap_or((padding + border).sum_axes().get(axis));
}
// See the min-content path above. Max-content measurement uses the same containing-block
// basis so percentage-dependent item geometry is measured from the grid area rather than
// from the container.
+6
View File
@@ -237,6 +237,12 @@ pub trait GridContainerStyle: CoreStyle {
/// The set of styles required for a CSS Grid item (child of a CSS Grid container)
pub trait GridItemStyle: CoreStyle {
/// Whether descendants are ignored for intrinsic size contributions in each axis.
#[inline(always)]
fn intrinsic_size_containment(&self) -> Size<bool> {
Size { width: false, height: false }
}
/// Defines which row in the grid the item should start and end at
#[inline(always)]
fn grid_row(&self) -> Line<GridPlacement<Self::CustomIdent>> {
+15
View File
@@ -442,6 +442,11 @@ pub struct Style<S: CheapCloneStr = DefaultCheapStr> {
/// Is it a replaced element like an image or form field?
/// <https://drafts.csswg.org/css-sizing-3/#min-content-zero>
pub item_is_replaced: bool,
/// Whether descendants are ignored for intrinsic size contributions in each axis.
///
/// Ordinary final layout is unaffected, allowing an auto-sized grid item to
/// retain stretch alignment after its contained intrinsic contribution is removed.
pub intrinsic_size_containment: Size<bool>,
/// Should size styles apply to the content box or the border box of the node
pub box_sizing: BoxSizing,
/// Sets the direction of text, table and grid columns, and horizontal overflow.
@@ -591,6 +596,7 @@ impl<S: CheapCloneStr> Style<S> {
display: Display::DEFAULT,
item_is_table: false,
item_is_replaced: false,
intrinsic_size_containment: Size { width: false, height: false },
box_sizing: BoxSizing::BorderBox,
direction: Direction::Ltr,
overflow: Point { x: Overflow::Visible, y: Overflow::Visible },
@@ -1150,6 +1156,10 @@ impl<T: GridContainerStyle> GridContainerStyle for &'_ T {
#[cfg(feature = "grid")]
impl<S: CheapCloneStr> GridItemStyle for Style<S> {
#[inline(always)]
fn intrinsic_size_containment(&self) -> Size<bool> {
self.intrinsic_size_containment
}
#[inline(always)]
fn grid_row(&self) -> Line<GridPlacement<S>> {
// TODO: Investigate eliminating clone
@@ -1172,6 +1182,10 @@ impl<S: CheapCloneStr> GridItemStyle for Style<S> {
#[cfg(feature = "grid")]
impl<T: GridItemStyle> GridItemStyle for &'_ T {
#[inline(always)]
fn intrinsic_size_containment(&self) -> Size<bool> {
(*self).intrinsic_size_containment()
}
#[inline(always)]
fn grid_row(&self) -> Line<GridPlacement<Self::CustomIdent>> {
(*self).grid_row()
@@ -1208,6 +1222,7 @@ mod tests {
display: Default::default(),
item_is_table: false,
item_is_replaced: false,
intrinsic_size_containment: Size { width: false, height: false },
box_sizing: Default::default(),
#[cfg(feature = "float_layout")]
float: Default::default(),