Skip to content

[Bug Report][4.1.8] VChip renders divs inside its own span root, producing invalid HTML #23103

Description

@BatLeDev

Environment

Vuetify Version: 4.1.8
Vue Version: 3.5.38
Browsers: Chrome
OS: Linux

Steps to reproduce

Render any chip and run the page through the W3C validator:

<v-chip text="Territoires (7)" />

Expected Behavior

Valid HTML. VChip defaults its root tag to span (makeTagProps({ tag: 'span' })), so a chip is an inline box by design and everything it renders inside should be phrasing content.

Actual Behavior

The root is a span as expected, and the overlay and underlay wrappers are spans too — but four wrappers are hardcoded as div: v-chip__filter, v-chip__prepend, v-chip__content and v-chip__append.

<span class="v-chip v-chip--label v-chip--link ...">
  <span class="v-chip__overlay"></span>
  <span class="v-chip__underlay"></span>
  <div class="v-chip__content"></div>   <!-- invalid: div inside span -->
</span>

The validator reports, once per chip:

Element “div” not allowed as child of element “span” in this context.

Seven occurrences on a single page of our portal, all of them plain filter chips.

How this differs from #23093

#23093 (VBadge) only produces invalid HTML when the badge is placed inside phrasing content, e.g. inside VBtn's span.v-btn__content, and fixing it needs a discussion about the tag default because a badge legitimately wraps block content sometimes.

VChip has no such ambiguity: its root is already a span, so its subtree is already required to be phrasing content. The div wrappers are invalid unconditionally, with no particular nesting needed to trigger it.

Suggested fix

Render all four as span, matching the sibling v-chip__overlay and v-chip__underlay. No visual change: VChip.sass declares display: inline-flex explicitly on .v-chip__content and on the .v-chip__filter/.v-chip__prepend/.v-chip__append group, so the tag name carries no layout meaning. The close button is untouched — it is a button, already valid phrasing content.

None of these wrappers is reachable from userland (tag only controls the root), so there is no workaround short of patching the package.

I have a PR ready for this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    C: VChipS: triageaudit toolsa problem affecting auditing tools with no effect on the actual behavior

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions