@@ -4,9 +4,9 @@ use style::values::specified::box_::DisplayOutside;
44use style:: values:: { computed:: CSSPixelLength , generics:: text:: GenericTextIndent } ;
55use taffy:: {
66 AvailableSpace , BlockContext , BlockFormattingContext , BoxSizing , CollapsibleMarginSet ,
7- CoreStyle as _, Direction , LayoutInput , LayoutOutput , LayoutPartialTree as _ , MaybeMath as _,
8- MaybeResolve as _, Overflow , Point , Position , RequestedAxis , ResolveOrZero as _ , RunMode , Size ,
9- SizingMode ,
7+ CoreStyle as _, Direction , Display , LayoutInput , LayoutOutput , LayoutPartialTree as _,
8+ MaybeMath as _ , MaybeResolve as _, Overflow , Point , Position , RequestedAxis ,
9+ ResolveOrZero as _ , RunMode , Size , SizingMode ,
1010} ;
1111
1212#[ cfg( feature = "floats" ) ]
@@ -306,24 +306,33 @@ impl BaseDocument {
306306 } else {
307307 let is_scroll_container = style. overflow . x . is_scroll_container ( )
308308 || style. overflow . y . is_scroll_container ( ) ;
309+ let display = style. display ;
309310 let output = self . compute_child_layout ( taffy:: NodeId :: from ( ibox. id ) , child_inputs) ;
310311 // Per CSS, an in-flow inline-block is baseline-aligned to the baseline of its
311- // last in-flow line box, unless it is a scroll container or has no in-flow line
312- // boxes, in which case its baseline is its bottom margin edge (Parley's fallback
313- // when `baseline` is `None`, since `ibox.height` includes margins).
312+ // last in-flow line box, while inline flex/grid containers use their first
313+ // baseline. A scroll container or a box with no natural baseline uses its
314+ // bottom margin edge (Parley's fallback when `baseline` is `None`, since
315+ // `ibox.height` includes margins).
316+ let baseline = match display {
317+ Display :: Flex | Display :: Grid => output. baselines . first ,
318+ _ => output. baselines . last ,
319+ } ;
314320 ibox. baseline = if is_scroll_container {
315321 None
316322 } else {
317- output
318- . baselines
319- . last
320- . or ( output. baselines . first )
321- . map ( |baseline| ( margin. top + baseline) * scale)
323+ baseline. map ( |baseline| ( margin. top + baseline) * scale)
322324 } ;
323325 ibox. width = ( margin. left + margin. right + output. size . width ) * scale;
324- // Vertical margins adjust the space the box reserves in the line, but the
325- // reserved space cannot be negative.
326- ibox. height = ( margin. top + margin. bottom + output. size . height ) . max ( 0.0 ) * scale;
326+ // Vertical margins adjust the space the box reserves in the line. With an
327+ // explicit baseline the ascent/descent contributions may legitimately be
328+ // negative, but a bottom-aligned box (no baseline) contributes its height
329+ // as ascent, and the space it reserves cannot be negative.
330+ let height = margin. top + margin. bottom + output. size . height ;
331+ ibox. height = if ibox. baseline . is_some ( ) {
332+ height * scale
333+ } else {
334+ height. max ( 0.0 ) * scale
335+ } ;
327336 }
328337 }
329338
@@ -598,7 +607,7 @@ impl BaseDocument {
598607 // dbg!(&layout.size);
599608 // dbg!(&layout.location);
600609
601- state. append_inline_box_to_line ( box_break_data. advance , 0.0 , 0.0 , false ) ;
610+ state. append_inline_box_to_line ( box_break_data. advance , None , false ) ;
602611
603612 // if float.is_floated() {
604613 // println!("INLINE FLOATED BOX ({}) {:?}", ibox.id, float);
@@ -807,11 +816,18 @@ impl BaseDocument {
807816 layout. size = size;
808817 layout. location . x =
809818 ( ibox. x / scale) + margin. left + container_pb. left + inset_offset. x ;
810- // A negative `margin-top` shrinks the space the box reserves in the
811- // line but does not move the box itself, which stays anchored to the
812- // bottom of the reserved space.
819+ // For a baseline-aligned box, `ibox.y` is the top of the margin box,
820+ // so the border box sits `margin.top` below it. For a bottom-aligned
821+ // box (no baseline), a negative `margin-top` shrinks the space the box
822+ // reserves in the line but does not move the box itself, which stays
823+ // anchored to the bottom of the reserved space.
824+ let margin_top_offset = if ibox. baseline . is_some ( ) {
825+ margin. top
826+ } else {
827+ margin. top . max ( 0.0 )
828+ } ;
813829 layout. location . y = ( ibox. y / scale)
814- + margin . top . max ( 0.0 )
830+ + margin_top_offset
815831 + container_pb. top
816832 + inset_offset. y ;
817833 layout. padding = padding; //.map(|p| p / scale);
0 commit comments