Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SSR hydration errors when combining inline styles with v-bind() in CSS #12439

Open
adamdehaven opened this issue Nov 19, 2024 · 2 comments · May be fixed by #12442 or #12461
Open

SSR hydration errors when combining inline styles with v-bind() in CSS #12439

adamdehaven opened this issue Nov 19, 2024 · 2 comments · May be fixed by #12442 or #12461
Labels
🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. scope:hydration

Comments

@adamdehaven
Copy link

adamdehaven commented Nov 19, 2024

Vue version

3.5.13

Link to minimal reproduction

Reproduction playground

Steps to reproduce

PageBlock.vue

  1. Ensure SSR is enabled in the reproduction

  2. In PageBlock.vue we initialize two props, color and backgroundColor

  3. The color prop is bound to the element via inline :style

  4. Use v-bind in the style block to set the background-color property, set to the value of the backgroundColor prop

  5. Notice the hydration error in the console shown below.

    - rendered on server: style="color:#000;"
    - expected on client: style="color:#000;"
    ssr hydration error
  6. Also notice that the generated CSS Custom Property for the backgroundColor value is not exposed in the hydration error (meaning I would expect to see --a4f2eed6-backgroundColor: lightgray; in the hydration error as well)

What is expected?

No hydration errors should be present when utilizing both inline style bindings and v-bind in CSS.

The inline style properties should be resolved before render to prevent hydration errors to produce the final HTML, with both the inline color style as well as the generated CSS custom property binding:

<div class="block" style="color: rgb(0, 0, 0); --a4f2eed6-backgroundColor: lightgray;" data-v-7ba5bd90=""
  data-v-a4f2eed6="">
  <div data-v-7ba5bd90="">Block One</div>
  <div class="block" style="color:#000;" data-v-a4f2eed6="">
    <div data-v-7ba5bd90="">Block Two</div>
  </div>
</div>

What is actually happening?

The inline style binding that is produced in the HTML appears to differ between server and client when the inline styles are merged with the v-bind in CSS rules.

System Info

No response

Any additional comments?

The interesting piece is not only is the hydration error occurring, but comparing the output diff between server and client appears to show the actual rendered content is identical in this particular case.

- rendered on server: style="color:#000;"
- expected on client: style="color:#000;"

In addition, the CSS custom property binding is not shown here in the client render, meaning I would expect to see --a4f2eed6-backgroundColor: lightgray; on the client line above.

In more complex examples, the output appears to actually be different depending on how the inline styles are computed.

(This issue is similar to, but different, from #12434)

@th1m0
Copy link
Contributor

th1m0 commented Nov 20, 2024

I was able to reproduce this issue in just the App.vue with the following code:

<template>
  <p class="block" :style="{ color: '#000' }">
    test
  </p>
</template>

<script setup lang="ts">
import { ref } from 'vue'

const backGroundColor = ref(null)
</script>

<style scoped>
.block {
  background-color: v-bind('backgroundColor');
}
</style>

Removing the style block fixes the hydration mismatch or removing the inline :style fixes the hydration mismatch. Hope this helps for anyone that will be fixing this.

@edison1105 edison1105 added 🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. scope:hydration labels Nov 20, 2024
@adamdehaven
Copy link
Author

Thanks @th1m0 - here's a reproduction utilizing the simplified code:

Simplified reproduction

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. scope:hydration
Projects
None yet
3 participants