react / react/yoga

Layout wrong with measured nodes, max-width percentage and absolute position

Open
#727 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Algorithm
Dominant language
C++
Stars
18.9k
Forks
1.6k
Avg merge
1m
Merged PRs (30d)
1

Description

Report

Wrapping text with position: absolute and max-width: 90% computes a parent size smaller than that of its contained content.

Issues and Steps to Reproduce

The following layout exhibits the issue:

<div style="width: 85px">
  <div style="position: absolute; max-width: 90%">
    [some text with a wrap point at x=68]
  </div>
</div>

It results in the following layout being produced by Yoga:

<div layout="width: 80; height: 0; top: 0; left: 0;" style="width: 80px; " >
  <div layout="width: 61; height: 16; top: 0; left: 0;" style="max-width: 90%; position: absolute; " >
    <div layout="width: 62; height: 32; top: 0; left: 0;" style="" has-custom-measure="true"></div>
  </div>
</div>

Note that the text node (with has-custom-measure) has a greater height than its parent, which seems incorrect to me.

Link to Code

This test fails, but I think it ought to succeed:

static YGSize _simulate_wrapping_text(YGNodeRef node,
                                      float width,
                                      YGMeasureMode widthMode,
                                      float height,
                                      YGMeasureMode heightMode) {
  if (widthMode == YGMeasureModeUndefined || width >= 68) {
    return YGSize{.width = 68, .height = 16};
  }

  return YGSize{
      .width = 50, .height = 32,
  };
}

TEST(YogaTest, measure_wrap_in_percent) {
  const YGNodeRef root = YGNodeNew();
  YGNodeStyleSetWidth(root, 80);

  const YGNodeRef root_child0 = YGNodeNew();
  YGNodeStyleSetMaxWidthPercent(root_child0, 90);
  YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute);
  YGNodeInsertChild(root, root_child0, 0);

  const YGNodeRef root_child0_child0 = YGNodeNew();
  //  YGNodeSetMeasureFunc(root_child0, _simulate_wrapping_text);
  root_child0_child0->setMeasureFunc(_simulate_wrapping_text);
  YGNodeInsertChild(root_child0, root_child0_child0, 0);

  YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);

  ASSERT_FLOAT_EQ(32, YGNodeLayoutGetHeight(root_child0_child0));
  ASSERT_FLOAT_EQ(32, YGNodeLayoutGetHeight(root_child0));

  YGNodeFreeRecursive(root);
}

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the YogaTest measure_wrap_in_percent case and its _simulate_wrapping_text measure function, then trace the YGNodeCalculateLayout call for the absolute child with a 90% max width. Confirm the layout dimensions for the measured child and its parent, including the expected height of 32 for both.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
frontend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.