A child pinned with bottom: 0 can end a pixel above its parent's bottom after pixel rounding

Đang mở
#2,067 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

@Pduhard đang làm issue này rồi.

Từ ngày 6/11/2026.

  • #2068 của @Pduhard — đang mở

Đánh giá

Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức phù hợp với người mới
25/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Đình trệ
Công nghệ
cpp, react-native
Lĩnh vực
frontend, testing

Hướng nghiên cứu

Start with PixelGrid.cpp and the roundLayoutResultsToPixelGrid logic described in the issue. Review draft PR #2068 and the gentest position rounding and generated expectations it identifies. Done means bottom-pinned children align with the parent after rounding, text positions avoid cumulative drift, and the reported gentest expectations are updated.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

Summary

  • roundLayoutResultsToPixelGrid: position rounded from relative offset (nodeTop), size from absolute edges (round(absoluteNodeBottom) - round(absoluteNodeTop)).
  • Parent on a fractional pixel → child pinned bottom: 0 ends 1 px above parent's bottom.

Repro

yoga-layout 3.2.1; PixelGrid.cpp on main rounds the same way.

import Yoga, { Edge, PositionType } from "yoga-layout";

const config = Yoga.Config.create();
config.setPointScaleFactor(1);

const root = Yoga.Node.create(config);
root.setWidth(100);

const parent = Yoga.Node.create(config);
parent.setPositionType(PositionType.Absolute);
parent.setPosition(Edge.Top, 0.25);
parent.setWidth(100);
parent.setHeight(10.5);

const child = Yoga.Node.create(config);
child.setPositionType(PositionType.Absolute);
child.setPosition(Edge.Bottom, 0);
child.setWidth(100);
child.setHeight(10.25);

parent.insertChild(child, 0);
root.insertChild(parent, 0);
root.calculateLayout(undefined, undefined);

parent.getComputedLayout(); // { top: 0, height: 11 }
child.getComputedLayout();  // { top: 0, height: 10 } -> bottom 10, parent bottom 11
  • Expected: child top: 1, height: 10, flush with parent bottom.
  • Actual: 1 px gap.

Why

  • Child absolute edges 0.5 / 10.75 → rounded 1 / 11 → height 10.
  • Position: round(0.25) = 0, not round(0.5) - round(0.25) = 1.

Scale

  • Scale 2.25 (Pixel 8 Pro), parent 506 tall at offset 0–4, bottom: 0 child 150–260 tall: 2003 / 9176 layouts 1 px short.
  • top: 0; bottom: 0 child: 0 / 9176.
  • Seen in React Native 0.88, Android: card shade bottom: 0 stops 1 px above the card edge, image line shows.

Related

  • #1574: rounding is meant to avoid gaps between touching edges. This is one.

Possible fix

  • Non-text position: round(absoluteNodeTop) - round(absoluteTop) (same for left), reusing the rounded leading edge of the size.
  • Text nodes keep floored relative position: absolute flooring drifts text 1 px per relayout.
  • gentest reads positions with the same relative rounding (Math.round(rect.top - parentTop)); change it too. 2 generated expectations move.
  • Draft PR: #2068.

Written with help from Claude (AI); reviewed and tested by me.

Ngôn ngữ chính
C++
Star
18.9k
Fork
1.6k
Merge trung bình
1 ngày 31 phút
Pull request đã merge (30 ngày)
14

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của react/yoga

Tất cả issue của react/yoga

Issue tương tự

Thêm issue về C++

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.