Skip to content

[Bug Report][4.2.1] VBtn clips a floating VBadge rendered inside it #23179

Description

@dschreij

Environment

Vuetify Version: 4.2.1
Vue Version: 3.5.42
OS: macOS 10.15.7 (current)

Steps to reproduce

  1. Open the reproduction on 4.2.1. Two icon buttons each wrap a v-icon in a v-badge; the preview is zoomed 4x so the edges are legible.
  2. Look at either badge: a clean arc is bitten out of its outer edge where it crosses the button boundary.

Expected Behavior

A floating v-badge placed inside a v-btn renders in full. The badge is anchored to the top-end corner of the content it wraps, so a few pixels of it necessarily fall outside the button box. This is what 4.1.13 and 3.13.4 both do.

Actual Behavior

The badge is clipped to its intersection with the button. On a round icon button the loss is large rather than marginal: for a 36x36 density="comfortable" icon button with a default 20x20 badge, 36% of the badge's area is cut away, and the diagonal cut across the badge's own circle is very visible.

.v-btn gained overflow: hidden in #22992, which also removed border-radius: inherit from .v-btn__overlay and from __underlay in _variant.sass, letting the button's own clip round them instead. That PR targets #22868, a VAvatar tonal radius bug, so the effect on badges nested in buttons looks like collateral rather than intent, and I could not find it noted in the upgrade guide.

Reproduction Link

https://play.vuetifyjs.com/#...

Other comments

Bisected against the published .v-btn CSS on jsdelivr:

version .v-btn { overflow: hidden } .v-btn__overlay { border-radius: inherit }
3.13.4 no yes
4.1.13 no yes
4.2.0-beta.0 yes no
4.2.0 yes no
4.2.1 yes no

So this is a 4.1 to 4.2 change rather than a v3 to v4 one, and 4.1.13 is the last release that renders the badge in full.

Restoring both halves for badge-bearing buttons is enough, and leaves the VAvatar fix alone:

.v-btn:has(.v-badge:not(.v-badge--inline)) {
  overflow: visible;

  .v-btn__overlay,
  .v-btn__underlay { border-radius: inherit; }
}

The second half is load-bearing. With overflow: visible alone the hover overlay renders as a square over the round button, since it no longer inherits the radius and no longer has a clip to round it. .v-ripple__container is unaffected, as it carries its own border-radius: inherit and overflow: hidden.

Worth saying plainly: badge-inside-button is not a composition the docs currently teach. The only example of it, v-badge/misc-tabs (a badge inside a v-tab, which is a VBtn), is still in the repo but is no longer referenced from badges.md or tabs.md, so this may well be judged working as intended. Filing it because it is a silent visual regression for anyone who did nest one, and the cause is not obvious from the symptom.

Inline badges (.v-badge--inline) are unaffected, as they are positioned relative and stay inside the button box.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions