Skip to content

Conversation

alex-snezhko
Copy link
Contributor

fix #13025 for class

Match behavior of style overriding present in normalizeStyle for normalizeClass.

Example: <div class="foo" :class="{ foo: false }"></div> -> <div class=""></div>

I have assumed that the discrepancy between class and style is a bug hence listing this as a fix.

Copy link

Size Report

Bundles

File Size Gzip Brotli
runtime-dom.global.prod.js 101 kB (+289 B) 38.6 kB (+108 B) 34.7 kB (+81 B)
vue.global.prod.js 159 kB (+289 B) 58.7 kB (+119 B) 52.2 kB (+54 B)

Usages

Name Size Gzip Brotli
createApp (CAPI only) 46.9 kB (+290 B) 18.3 kB (+98 B) 16.8 kB (+82 B)
createApp 54.9 kB (+290 B) 21.4 kB (+95 B) 19.5 kB (+89 B)
createSSRApp 59.2 kB (+290 B) 23.1 kB (+103 B) 21.1 kB (+81 B)
defineCustomElement 59.9 kB (+290 B) 23 kB (+113 B) 20.9 kB (+80 B)
overall 69 kB (+290 B) 26.6 kB (+111 B) 24.2 kB (+48 B)

Copy link

pkg-pr-new bot commented Sep 21, 2025

Open in StackBlitz

@vue/compiler-core

npm i https://pkg.pr.new/@vue/compiler-core@13911

@vue/compiler-dom

npm i https://pkg.pr.new/@vue/compiler-dom@13911

@vue/compiler-sfc

npm i https://pkg.pr.new/@vue/compiler-sfc@13911

@vue/compiler-ssr

npm i https://pkg.pr.new/@vue/compiler-ssr@13911

@vue/reactivity

npm i https://pkg.pr.new/@vue/reactivity@13911

@vue/runtime-core

npm i https://pkg.pr.new/@vue/runtime-core@13911

@vue/runtime-dom

npm i https://pkg.pr.new/@vue/runtime-dom@13911

@vue/server-renderer

npm i https://pkg.pr.new/@vue/server-renderer@13911

@vue/shared

npm i https://pkg.pr.new/@vue/shared@13911

vue

npm i https://pkg.pr.new/vue@13911

@vue/compat

npm i https://pkg.pr.new/@vue/compat@13911

commit: fe15e02

@edison1105 edison1105 added the 🍰 p2-nice-to-have Priority 2: this is not breaking anything but nice to have it addressed. label Sep 23, 2025
@skirtles-code
Copy link
Contributor

This change adds quite a few bytes to the build. Not necessarily a problem, but it's something I think we need to take into account when deciding whether this fix is worth it.

The underlying problem described in #13025 is interesting, but I don't think changing how we merge classes is the correct way to address that use case.

I think changing how normalizeClass behaves will break a lot of existing applications. It's common for elements to accrue classes from a variety of sources, including attribute inheritance.

This change would alter the semantics of falsey values from 'do nothing' to 'remove this class'. Currently, :class="{ a: b }" is equivalent to :class="b ? 'a' : ''". It's purely an additive process, adding the class a if required. It doesn't block that same class from being added by an earlier source.

class and style are fundamentally different and their handling reflects that. I don't see this as an inconsistency, they're just different.

I think the correct mental model for style is a map, with key/value pairs. Merging those maps needs a way to handle clashing keys. Browsers already need to handle this for HTML, e.g. style="color: red; color: blue" will use blue as the value for color. Our handling reflects that and gives priority to the last value. We allow an object to be used with :style as its a natural fit for specifying a map.

The mental model for class is different, that behaves more like a set. When we merge those sets we essentially just take the union of those sets. (I'm glossing over duplicate classes, but I don't think they matter from the perspective of the mental model). When we use an object with :class it should be seen as a convenient way to specify one of those sets. Allowing the truthiness of the value to determine inclusion is useful for conditionals, but a falsey value is only intended to indicate that the key should not be added to current set. That information isn't supposed to be retained beyond the creation of the current set and shouldn't be taken into account when taking the union of the sets.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🍰 p2-nice-to-have Priority 2: this is not breaking anything but nice to have it addressed.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Overriding existing HTML for the sake hydration isn't consistent
3 participants