You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
"By default, CSS in ipyvue templates is **global** — it affects all elements on the page with matching selectors. Scoped CSS limits styles to the component that defines them.\n",
10
+
"\n",
11
+
"**How it works:** ipyvue adds a unique `data-v-*` attribute to your component's elements and rewrites your CSS selectors to include it (e.g., `.my-class` → `.my-class[data-v-abc123]`)."
12
+
]
13
+
},
14
+
{
15
+
"cell_type": "code",
16
+
"execution_count": null,
17
+
"metadata": {},
18
+
"outputs": [],
19
+
"source": [
20
+
"import ipyvue as vue\n",
21
+
"import ipywidgets as widgets\n",
22
+
"from traitlets import default"
23
+
]
24
+
},
25
+
{
26
+
"cell_type": "markdown",
27
+
"metadata": {},
28
+
"source": [
29
+
"## Without scoped CSS (the problem)"
30
+
]
31
+
},
32
+
{
33
+
"cell_type": "code",
34
+
"execution_count": null,
35
+
"metadata": {},
36
+
"outputs": [],
37
+
"source": [
38
+
"class GlobalStyle(vue.VueTemplate):\n",
39
+
" @default(\"template\")\n",
40
+
" def _default_template(self):\n",
41
+
" return \"\"\"\n",
42
+
" <template>\n",
43
+
" <span class=\"demo-text\">Widget A</span>\n",
44
+
" </template>\n",
45
+
" <style>\n",
46
+
" .demo-text { color: red; }\n",
47
+
" </style>\n",
48
+
"\"\"\"\n",
49
+
"\n",
50
+
"widget_b = vue.Html(tag=\"span\", children=[\"Widget B (innocent bystander)\"], class_=\"demo-text\")\n",
51
+
"\n",
52
+
"widgets.VBox([GlobalStyle(), widget_b]) # Both turn red!"
53
+
]
54
+
},
55
+
{
56
+
"cell_type": "markdown",
57
+
"metadata": {},
58
+
"source": [
59
+
"## With `<style scoped>`"
60
+
]
61
+
},
62
+
{
63
+
"cell_type": "code",
64
+
"execution_count": null,
65
+
"metadata": {},
66
+
"outputs": [],
67
+
"source": [
68
+
"class ScopedStyle(vue.VueTemplate):\n",
69
+
" @default(\"template\")\n",
70
+
" def _default_template(self):\n",
71
+
" return \"\"\"\n",
72
+
" <template>\n",
73
+
" <span class=\"demo-text-2\">Widget A (scoped)</span>\n",
74
+
" </template>\n",
75
+
" <style scoped>\n",
76
+
" .demo-text-2 { color: green; }\n",
77
+
" </style>\n",
78
+
"\"\"\"\n",
79
+
"\n",
80
+
"widget_b = vue.Html(tag=\"span\", children=[\"Widget B (unaffected)\"], class_=\"demo-text-2\")\n",
81
+
"\n",
82
+
"widgets.VBox([ScopedStyle(), widget_b]) # Only Widget A is green"
83
+
]
84
+
},
85
+
{
86
+
"cell_type": "markdown",
87
+
"metadata": {},
88
+
"source": [
89
+
"## Using the `css` trait with `scoped=True`\n",
90
+
"\n",
91
+
"Alternative syntax when defining CSS outside the template:"
92
+
]
93
+
},
94
+
{
95
+
"cell_type": "code",
96
+
"execution_count": null,
97
+
"metadata": {},
98
+
"outputs": [],
99
+
"source": [
100
+
"class CssTrait(vue.VueTemplate):\n",
101
+
" @default(\"template\")\n",
102
+
" def _default_template(self):\n",
103
+
" return \"<template><span class='trait-demo'>Widget C (scoped via trait)</span></template>\"\n",
0 commit comments