I've noticed that when using Vue single-file components (.vue files) with ipyvue, the <style scoped> attribute appears to be ignored. CSS rules defined in one component can unintentionally affect other components, which makes styling complex applications challenging.
Expected Behavior
In standard Vue tooling (Vue CLI, Vite), <style scoped> transforms CSS selectors to include a unique data attribute, ensuring styles only apply to elements within that component:
/* Input */
.card-container { background: red; }
/* Output after Vue's PostCSS processing */
.card-container[data-v-f3f3eg9] { background: red; }
Actual Behavior
In ipyvue, the scoped attribute is parsed but not processed. CSS is injected into as-is, making all styles effectively global.
Reproduction Example
Component A (component_a.vue):
<template>
<div class="container">Component A</div>
</template>
<style scoped>
.container { background-color: red; }
</style>
Component B (component_b.vue):
<template>
<div class="container">Component B</div>
</template>
<style scoped>
.container { background-color: blue; }
</style>
Result: Both components end up with the same background color (whichever CSS loads last wins), even though both use <style scoped>.
Investigation
I looked into the ipyvue source and found:
- In VueTemplateRenderer.js, styles are extracted and injected into document.head, but the scoped attribute doesn't trigger any CSS transformation:
const css = model.get('css') || (vuefile.STYLE && vuefile.STYLE.content);
const cssId = (vuefile.STYLE && vuefile.STYLE.id);
if (css) {
if (cssId) {
// Uses ID for deduplication, but no scoping transformation
const prefixedCssId = `ipyvue-${cssId}`;
// ...
}
}
- Interestingly, httpVueLoader.js contains a scopeStyles function that modifies CSS selectors — this suggests there's partial infrastructure for scoping that could potentially be extended
Workaround
Currently, I'm manually prefixing all CSS class names with the component name (e.g., .sidepanel-card-container instead of .container), but this is error-prone and defeats the purpose of having scoped styles.
I've noticed that when using Vue single-file components (.vue files) with ipyvue, the <style scoped> attribute appears to be ignored. CSS rules defined in one component can unintentionally affect other components, which makes styling complex applications challenging.
Expected Behavior
In standard Vue tooling (Vue CLI, Vite), <style scoped> transforms CSS selectors to include a unique data attribute, ensuring styles only apply to elements within that component:
Actual Behavior
In ipyvue, the scoped attribute is parsed but not processed. CSS is injected into as-is, making all styles effectively global.
Reproduction Example
Component A (component_a.vue):
Component B (component_b.vue):
Result: Both components end up with the same background color (whichever CSS loads last wins), even though both use <style scoped>.
Investigation
I looked into the ipyvue source and found:
Workaround
Currently, I'm manually prefixing all CSS class names with the component name (e.g., .sidepanel-card-container instead of .container), but this is error-prone and defeats the purpose of having scoped styles.