Skip to content

parley 0.12: a line holding only a zero-height atomic inline gets no strut

Generated from repros/parley-strut-zero-height-inline-box/README.md when the site was built at 7aa23e2.

No workaround. Found by Acid2 (.image-height-test relies on it). In blitz, a block whose only content is an atomic inline of zero height is 0px tall instead of one line tall: blitz takes the inline formatting context’s height straight from parley::Layout::height() (blitz-dom/src/layout/inline/layout.rs:1003-1010 at be60597), and parley returns 0. Measured in blitz at be60597 (body font:12px/12px sans-serif), compared with Chrome 156:

case Chrome blitz
<div><span style="display:inline-block;width:10px;height:0"></span></div> div height 12 0
<div><img style="width:10px;height:0"></div> div height 12 0
<div style="font:40px serif"><table><tr><td><span style="display:inline-block;width:10px;height:0"> td height 55 0

parley, not blitz. The line breaker only marks a line as having content when an inline box has non-zero ascent or descent (parley/src/layout/line_break.rs:466-481 at the fork rev, add_inline_box), and a line without content is an “invisible” zero-height line box (line_break.rs:918-925); parley’s own test asserted it (line_with_only_empty_inline_boxes_is_invisible: assert_eq!(line_height(0., InlineBoxKind::InFlow), 0.)). CSS 2 §9.4.2 only collapses line boxes with no in-flow content; an inline-block or image is content whatever its size, so the strut (§10.8) applies and the line is line-height tall.

Parley alone: root style font-size: 12px; line-height: 12px, one in-flow 10x0 inline box, no text:

line holding only an in-flow 10x0 inline box, line-height 12px
expected: layout height 12 (the strut, CSS 2 §10.8)
actual: layout height 0
Terminal window
CARGO_TARGET_DIR=~/.capy/work/repro-target cargo run

Exit status 1 while the bug reproduces. Uses system fonts (any sans-serif). The manifest uses niso’s parley fork (0.12.0 + #942); plain crates.io parley 0.12.0 (patch removed) gives the same actual: layout height 0.

Fixed on linebender/parley main 746fdcf0d53fab04c5da1e2d7bde89018cbbb2b4 (actual: layout height 12, exit 0). Bisected to https://github.com/linebender/parley/pull/902 (“Represent inline boxes with U+FFFC object replacement characters”, merged 2026-10-19 as 26052b9): its parent 0724f1b prints 0, 26052b9 prints 12, and #902 changed the test above to line_with_only_out_of_flow_boxes_is_invisible with assert_eq!(line_height(0., InFlow), 30.). No release has it (newest is 0.12.0, 2026-10-09), and blitz main does not build against parley main (see parley-trak-scaled-point-size/README.md), so it can’t reach niso yet.

Fixed by https://github.com/linebender/parley/pull/902 (merged). No parley issue. On the blitz side, https://github.com/DioxusLabs/blitz/pull/685 (open, “Enable parley line-box strut and plumb vertical-align for inline boxes”) and #834 (closed, “Fix atomic-inline baseline export, empty line boxes …”) are older attempts around struts; neither covers this.

Nothing to file against parley main. If asking for a point release (see the trak repro), add this to it:

#902 also fixes lines that hold only a zero-height in-flow inline box (e.g. <span style="display:inline-block;height:0">): 0.12.0 gives them no strut, so the line is 0px tall instead of line-height (CSS 2 §9.4.2, §10.8). Repro:

use parley::{FontContext, InlineBox, InlineBoxKind, Layout, LayoutContext, LineHeight, TextStyle, VerticalAlign};
fn main() {
let (mut fcx, mut lcx) = (FontContext::new(), LayoutContext::new());
let root = TextStyle { font_size: 12.0, line_height: LineHeight::Absolute(12.0), ..TextStyle::default() };
let mut builder = lcx.tree_builder(&mut fcx, 1.0, false, &root);
builder.push_inline_box(InlineBox { id: 0, kind: InlineBoxKind::InFlow, index: 0, width: 10.0, height: 0.0, baseline: None, vertical_align: VerticalAlign::BASELINE });
let (mut layout, _): (Layout<()>, _) = builder.build();
layout.break_all_lines(None);
assert_eq!(layout.height(), 12.0); // 0.12.0: 0; main: 12
}