Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Vue 3 debugging reference for reactivity issues, computed errors, watcher bugs, async failures, and SSR hydration problems.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
reference/teleport-scoped-styles-limitation.md
1---2title: Scoped Styles May Not Apply to Teleported Content3impact: MEDIUM4impactDescription: Scoped styles can fail to apply to teleported elements due to data attribute limitations5type: gotcha6tags: [vue3, teleport, scoped-styles, css]7---89# Scoped Styles May Not Apply to Teleported Content1011**Impact: MEDIUM** - When using scoped styles with Teleport, the styles may not apply correctly to teleported elements. This is a known limitation related to how Vue's scoped style attributes work with elements rendered outside the component's DOM tree.1213## Task Checklist1415- [ ] Test scoped styles on teleported content16- [ ] Use `:deep()` selector or non-scoped styles for teleported content17- [ ] Consider CSS modules as an alternative18- [ ] Keep teleported content styles in a separate non-scoped style block1920**Problem - Scoped Styles Not Applied:**21```vue22<template>23<Teleport to="body">24<div class="modal">25<p class="modal-text">This text may not be styled!</p>26</div>27</Teleport>28</template>2930<style scoped>31/* These styles may NOT apply to teleported content */32.modal {33background: white;34padding: 20px;35}3637.modal-text {38color: blue; /* May not work */39}40</style>41```4243**Solution 1 - Use Non-Scoped Styles for Teleported Content:**44```vue45<template>46<Teleport to="body">47<div class="my-modal">48<p class="my-modal-text">This text will be styled</p>49</div>50</Teleport>51</template>5253<style scoped>54/* Component-specific styles */55.button { color: blue; }56</style>5758<style>59/* Non-scoped styles for teleported content */60/* Use specific class names to avoid conflicts */61.my-modal {62background: white;63padding: 20px;64position: fixed;65top: 50%;66left: 50%;67transform: translate(-50%, -50%);68}6970.my-modal-text {71color: blue;72}73</style>74```7576**Solution 2 - Use :deep() Selector:**77```vue78<template>79<Teleport to="body">80<div class="modal">81<p class="modal-text">Styled with :deep()</p>82</div>83</Teleport>84</template>8586<style scoped>87:deep(.modal) {88background: white;89padding: 20px;90}9192:deep(.modal-text) {93color: blue;94}95</style>96```9798**Solution 3 - CSS Modules:**99```vue100<template>101<Teleport to="body">102<div :class="$style.modal">103<p :class="$style.modalText">Styled with CSS modules</p>104</div>105</Teleport>106</template>107108<style module>109.modal {110background: white;111padding: 20px;112}113114.modalText {115color: blue;116}117</style>118```119120## Multi-Root Components with Teleport121122Using Teleport as one of multiple root nodes causes additional issues:123124```vue125<template>126<!-- Multi-root component -->127<button @click="open = true">Open</button>128<Teleport to="body">129<div class="modal">Content</div>130</Teleport>131</template>132133<!-- Warning: class/style attributes may not be inherited -->134```135136Pass classes explicitly to avoid inheritance issues:137138```vue139<template>140<button @click="open = true">Open</button>141<Teleport to="body">142<div :class="['modal', $attrs.class]" :style="$attrs.style">143Content144</div>145</Teleport>146</template>147```148149## Best Practice: Dedicated Modal Styles150151Create a dedicated stylesheet for modal/overlay components:152153```css154/* modal-styles.css */155.modal-overlay {156position: fixed;157inset: 0;158background: rgba(0, 0, 0, 0.5);159display: flex;160align-items: center;161justify-content: center;162}163164.modal-content {165background: white;166border-radius: 8px;167padding: 24px;168max-width: 500px;169width: 90%;170}171```172173```vue174<script setup>175import './modal-styles.css'176</script>177178<template>179<Teleport to="body">180<div v-if="open" class="modal-overlay">181<div class="modal-content">182<slot />183</div>184</div>185</Teleport>186</template>187```188189## Reference190- [Vue.js SFC CSS Features - Scoped CSS](https://vuejs.org/api/sfc-css-features.html#scoped-css)191- [GitHub Issue #2047 - Scoped styles and teleport](https://github.com/vuejs/core/issues/2047)192