-
Notifications
You must be signed in to change notification settings - Fork 131
feat(htmlcss): inline-block siblings via Taffy flex-wrap emulation #691
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -126,6 +126,19 @@ fn build_taffy_node( | |
| apply_replaced_intrinsic_size(&mut style, replaced, images); | ||
| } | ||
|
|
||
| // Emulate inline-block sibling flow via Taffy flex-wrap. Taffy has no | ||
| // inline formatting context, so a block container holding only | ||
| // inline-block siblings would otherwise stack them vertically. Only | ||
| // apply when ≥2 inline-block element children exist and no text or | ||
| // non-inline-block elements would be misrouted through flex. | ||
| if style.display == taffy::Display::Block && should_emulate_inline_block_container(el) { | ||
| style.display = taffy::Display::Flex; | ||
| style.flex_wrap = taffy::FlexWrap::Wrap; | ||
|
Comment on lines
+135
to
+136
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
After switching a block container to flex for inline-block emulation, the code keeps whatever Useful? React with 👍 / 👎. |
||
| // Override default `stretch` so inline-blocks keep their | ||
| // own block-size instead of filling the container's line height. | ||
| style.align_items = Some(taffy::AlignItems::Start); | ||
| } | ||
|
|
||
| // Build child nodes | ||
| let mut child_ids: Vec<TaffyNodeId> = Vec::new(); | ||
|
|
||
|
|
@@ -176,6 +189,26 @@ fn build_taffy_node( | |
| taffy.new_with_children(style, &child_ids).unwrap() | ||
| } | ||
|
|
||
| /// Returns true when `el` should lay out its children as a horizontal | ||
| /// flex-wrap row to emulate inline-block flow. Only safe when the | ||
| /// container holds ≥2 inline-block element siblings and no text or | ||
| /// non-inline-block element children (those would require a real inline | ||
| /// formatting context to mix with inline-blocks correctly). | ||
| fn should_emulate_inline_block_container(el: &StyledElement) -> bool { | ||
| let mut inline_block_count = 0usize; | ||
| for child in &el.children { | ||
| match child { | ||
| StyledNode::Element(child_el) => match child_el.display { | ||
| types::Display::InlineBlock => inline_block_count += 1, | ||
| types::Display::None => {} | ||
| _ => return false, | ||
| }, | ||
| StyledNode::Text(_) | StyledNode::InlineGroup(_) => return false, | ||
| } | ||
| } | ||
| inline_block_count >= 2 | ||
| } | ||
|
|
||
| /// Taffy context for text/inline leaf nodes. Stores inline items so the | ||
| /// measure function can build a Skia Paragraph with placeholders at any | ||
| /// available width. | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| <!doctype html> | ||
| <html lang="en"> | ||
| <head> | ||
| <meta charset="utf-8" /> | ||
| <title>Layout: display: inline-block</title> | ||
| <style> | ||
| html, | ||
| body { | ||
| min-height: 800px; | ||
| box-sizing: border-box; | ||
| } | ||
| body { | ||
| margin: 0; | ||
| padding: 24px; | ||
| background: #fff; | ||
| } | ||
|
|
||
| .row { | ||
| font-size: 0; | ||
| } | ||
|
|
||
| .box { | ||
| display: inline-block; | ||
| width: 80px; | ||
| height: 80px; | ||
| vertical-align: top; | ||
| } | ||
|
|
||
| .a { | ||
| background: #c00; | ||
| } | ||
| .b { | ||
| background: #0a0; | ||
| } | ||
| .c { | ||
| background: #05f; | ||
| } | ||
| .d { | ||
| background: #fa0; | ||
| } | ||
| </style> | ||
| </head> | ||
| <body> | ||
| <div class="row"> | ||
| <div class="box a"></div> | ||
| <div class="box b"></div> | ||
| <div class="box c"></div> | ||
| <div class="box d"></div> | ||
| </div> | ||
| </body> | ||
| </html> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Marking every sized
display:inline-blockas non-inline here forces it out ofInlineGroup, but the later emulation only runs when the parent has no text/inline groups and at least two inline-block elements. In mixed content (for exampletext + inline-block + text) or a single inline-block, the parent stays block and this node is laid out as a block child, inserting unintended line breaks around content that should remain in one inline formatting context.Useful? React with 👍 / 👎.