Subscribe on changes!

Support other data types on top of strings in CSS `v-bind`

avatar
Nov 4th 2022

Vue version

3.2.41

Link to minimal reproduction

https://stackblitz.com/edit/nuxt-starter-phmbfs?file=components/TestBinding1.vue

HTML rendered on SSR is missing the binding for values used in calc(...) or repeat(...) expressions. For anything else - the inlined style contains appropriate properties. This may lead to content jumping around or changing after hydration. For example in case of repeat - if we have a CSS grid which has a number of columns based on a prop.

Steps to reproduce

Try to refresh the preview window (also see the plain HTML response returned by the server); in this case the hydration is also visible because the flex/grid properties get applied after hydration making the content jump:

  • TestBinding1.vue - flex container missing the gap on initial load, and applying that after hydration.
  • TestBinding2.vue - CSS grid missing proper columns definition and changing that after hydration.

What is expected?

All inlined styles present for all of the v-bind bindings in the HTML returned by server during SSR.

What is actually happening?

Missing inline styles for some v-bind bindings in the HTML (those used within calc or repeat` expressions within CSS); they get added during hydration.

System Info

No response

Any additional comments?

HTML rendered on SSR is missing the binding for values used in calc(...) or repeat(...) expressions. For anything else - the inlined style contains appropriate properties.

This may lead to content jumping around or changing after hydration. For example in case of repeat - if we have a CSS grid which has a number of columns based on a prop.

Previously reported here at Nuxt's repository but turns out it's not strictly Nuxt related after further checking.

Also checked without Nuxt on a plain Vite & SSR setup - same issue present: https://stackblitz.com/edit/github-ne553q?file=README.md

avatar
Nov 4th 2022

FYI, after some digging - it's actually not depending on the expressions, but the type of the property we bind in CSS - in essence anything other than a string... gets skipped when generating the inline styles in HTML 🤔

Reproduction example for this (hydration is disabled to easier see the results; just inspect the element):

https://stackblitz.com/edit/github-ne553q-cxzcsw?file=src/components/TestBinding.vue

avatar
Nov 6th 2022

duplicate of nuxt/nuxt.js#14586