penpot/penpot

Show selection size badge below bounding box in the workspace

Open

#9,205 opened on 2026年4月28日

GitHub で見る
 (7 comments) (0 reactions) (0 assignees)Clojure (47,547 stars) (2,944 forks)batch import
community contributionenhancementgood first issuemanaged on taiga

説明

Is your feature request related to a problem? Please describe.

When a designer selects an element in the Penpot workspace, the only way to check its dimensions is to look at the Design panel on the right sidebar. There is no visual feedback directly on the canvas.

This forces an eye movement away from the canvas even for the simplest sanity check — "is this box 240 px wide?" — adding friction that compounds during dense layout work or when reviewing someone else's design.

Additionally, when resizing an element, the current tooltip only appears near the handle being dragged, far from the element's center. The size badge provides a stable, centered reference point that updates live during the entire resize interaction.

Describe the solution you'd like

Show a small read-only badge directly below the bounding box of the selected element (or combined bounding box for multi-selection), displaying width × height. The badge is always visible while an element is selected, and updates live as the element is resized — replacing the existing resize tooltip.


Badge content and format

  • Format: {width} x {height} (lowercase x, single space each side) e.g. 235.47 x 113.72
  • Precision: 2 decimal places, matching the Design panel (not 235 x 113 nor 235.470 x 113.720)
  • Units: respect the document unit setting (px by default)

Visual variants

The badge background must reuse the same color token already used by the bounding box stroke. No new color values are introduced.

Theme Element type Token Approx. hex Badge text
Dark Non-component d.color.accent.tertiary #00d1b8 Dark
Dark Component d.color.accent.secondary #bb97d8 Dark
Light Non-component l.color.accent.tertiary #8c33eb White
Light Component l.color.accent.secondary #1345aa White

Badge anatomy

  • Font: Work Sans, Body S (12px), same as the existing resize/rotate tooltip
  • Padding: 2px top/bottom, 2px left/right
  • Border radius: 2px
  • Border: none — background fill only

Positioning

  • Centered horizontally on the bounding box midpoint
  • 8px vertical gap between the bottom edge of the bounding box and the top edge of the badge
  • Rendered in canvas/overlay space (not DOM flow)
  • Fixed screen size: the badge does not scale with canvas zoom — it always renders at the same physical size on screen, consistent with how the existing resize/rotate tooltip behaves
  • During resize, the badge follows the bounding box bottom edge as it moves, always staying centered and 8px below it

Flip behavior (viewport clipping)

If the badge would render outside the visible viewport bottom edge, flip it above the bounding box top edge with the same 8px gap.

This flip must also work correctly during live resize.


Live resize behavior

The badge replaces the existing resize tooltip. When the user drags a resize handle:

  • The badge remains visible and in position throughout the entire drag
  • Width, height, or both values update on every frame as the element is resized (depending on which handle is being dragged)
  • The badge position follows the bounding box in real time
  • The existing resize tooltip must be removed or disabled to avoid showing duplicate dimension feedback

Which value updates per handle:

  • Corner handles (tl, tr, bl, br) → both W and H update
  • Left/right handles (ml, mr) → only W updates
  • Top/bottom handles (mt, mb) → only H updates

Visibility rules

Condition Badge shown?
Single element selected Yes
Single element selected, rotated Yes — shows unrotated W × H (matches Design panel)
Single element being resized Yes — updates live, replaces existing resize tooltip
Multi-selection (2+ elements) Yes — shows combined axis-aligned bounding box W × H
Multi-selection with rotated elements Yes — shows axis-aligned W × H of the combined box
Multi-selection, mix of components/non-components Yes — uses non-component token (neutral)
No selection No
Actively rotating No — existing rotate tooltip takes over
Actively moving (drag element) No — existing move tooltip takes over
Text element in edit mode (double-clicked) No
Element very small at current zoom — badge overlaps handles Hide badge
Element partially outside viewport Show, as long as bounding box is visible
Element fully outside viewport No

Rotation note (single selection)

When a single element is rotated, the bounding box expands to be axis-aligned. The badge must show the unrotated W and H of the element — the same values shown in the Design panel — not the dimensions of the expanded axis-aligned box.

Rotation note (multi-selection)

When multiple elements are selected and any of them is rotated, the combined bounding box is axis-aligned. The badge shows the dimensions of that axis-aligned box, not the unrotated dimensions of any individual element. This matches the Design panel behavior for multi-selection.


What is explicitly out of scope

  • Making the badge interactive or editable (clicking to edit dimensions is a separate, larger feature)
  • Any changes to the Design panel
  • Updating the badge live during rotate or move interactions (those already have their own tooltips)

How to test

Single selection

  1. Open any file in the workspace (dark theme).
  2. Click a regular shape → teal badge appears below, showing correct W × H.
  3. Click a component instance → muted purple badge appears.
  4. Switch to light theme (Profile > Theme > Light).
  5. Click a regular shape → vivid purple badge, white text.
  6. Click a component instance → dark navy badge, white text.
  7. Deselect (click empty canvas) → badge disappears.
  8. Double-click a text element to enter edit mode → badge disappears.
  9. Zoom in and out → badge stays the same physical size on screen.
  10. Rotate an element → badge shows unrotated W × H (matches Design panel).

Resize (live update) 11. Drag a corner handle → both W and H update on every frame, badge follows the bounding box bottom edge in real time. 12. Drag a left or right handle → only W updates. 13. Drag a top or bottom handle → only H updates. 14. Confirm the old resize tooltip no longer appears.

Multi-selection 15. Select 2+ regular shapes → badge shows combined W × H. 16. Select 2+ rotated shapes → badge shows axis-aligned combined W × H (matches Design panel). 17. Select a mix of components and non-components → badge uses non-component color token.

Edge cases 18. Move an element near the bottom of the visible viewport → badge flips above the bounding box. 19. Resize an element toward the bottom of the viewport → flip also works correctly during live resize. 20. Zoom out until element is very small → confirm badge does not overlap the resize handles (hide if it would).

Describe alternatives you've considered.

No response

Additional context

コントリビューターガイド