@ghostly-ui/core 0.2.2 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ghostly.css +76 -52
- package/package.json +1 -1
package/dist/ghostly.css
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
/* ============================================================
|
|
2
2
|
GHOSTLY — Zero-config skeleton loaders
|
|
3
3
|
|
|
4
|
-
Philosophy:
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
Philosophy:
|
|
5
|
+
1. NEVER override layout properties blindly
|
|
6
|
+
2. Only hide content + add skeleton background
|
|
7
|
+
3. Use :has() to surgically fix collapsing flex children
|
|
8
|
+
4. Component's own CSS defines sizing, spacing, and radius
|
|
7
9
|
============================================================ */
|
|
8
10
|
|
|
9
|
-
/* --- Custom properties
|
|
11
|
+
/* --- Custom properties --- */
|
|
10
12
|
|
|
11
13
|
:root {
|
|
12
14
|
--ghostly-color: hsl(220 13% 87%);
|
|
@@ -43,7 +45,6 @@
|
|
|
43
45
|
|
|
44
46
|
/* ============================================================
|
|
45
47
|
2. TEXT ELEMENTS — Hide text, show skeleton background
|
|
46
|
-
Only override visual properties. NEVER touch layout.
|
|
47
48
|
============================================================ */
|
|
48
49
|
|
|
49
50
|
[data-ghostly] :where(
|
|
@@ -63,53 +64,81 @@
|
|
|
63
64
|
text-decoration: none !important;
|
|
64
65
|
text-shadow: none !important;
|
|
65
66
|
outline: none !important;
|
|
66
|
-
/* Prevent empty elements from collapsing vertically */
|
|
67
67
|
min-height: 1em;
|
|
68
|
-
/* Inline elements need display block/inline-block to respect min-height */
|
|
69
|
-
display: var(--_ghostly-display, revert);
|
|
70
68
|
}
|
|
71
69
|
|
|
72
|
-
/*
|
|
70
|
+
/* Inline elements need inline-block to respect min-height */
|
|
73
71
|
[data-ghostly] :where(
|
|
74
72
|
span, a, em, strong, small, mark, code, abbr,
|
|
75
73
|
cite, q, sub, sup, del, ins, time, label
|
|
76
74
|
) {
|
|
77
|
-
|
|
75
|
+
display: inline-block;
|
|
78
76
|
}
|
|
79
77
|
|
|
80
|
-
/*
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
We
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
[data-ghostly] :where(
|
|
89
|
-
[data-ghostly] :where(
|
|
90
|
-
[data-ghostly] :where(
|
|
91
|
-
[data-ghostly] :where(
|
|
78
|
+
/* ============================================================
|
|
79
|
+
3. PREVENT TEXT COLLAPSE — Invisible pseudo-content
|
|
80
|
+
When text is empty (''), elements collapse to 0 width.
|
|
81
|
+
We inject invisible non-breaking spaces via ::before so the
|
|
82
|
+
element has natural width. Works with ANY layout system.
|
|
83
|
+
============================================================ */
|
|
84
|
+
|
|
85
|
+
/* Block text: inject wide invisible content */
|
|
86
|
+
[data-ghostly] :where(h1)::before { content: '\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0'; }
|
|
87
|
+
[data-ghostly] :where(h2)::before { content: '\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0'; }
|
|
88
|
+
[data-ghostly] :where(h3)::before { content: '\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0'; }
|
|
89
|
+
[data-ghostly] :where(h4, h5, h6)::before { content: '\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0'; }
|
|
90
|
+
[data-ghostly] :where(p)::before { content: '\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0'; }
|
|
91
|
+
|
|
92
|
+
/* Inline text: shorter content */
|
|
93
|
+
[data-ghostly] :where(span, a, em, strong, small, label, time, code)::before { content: '\00a0\00a0\00a0\00a0\00a0\00a0'; }
|
|
94
|
+
|
|
95
|
+
/* Interactive: reasonable widths */
|
|
96
|
+
[data-ghostly] :where(button)::before { content: '\00a0\00a0\00a0\00a0\00a0\00a0\00a0\00a0'; }
|
|
92
97
|
[data-ghostly] :where(input, textarea, select) { min-width: 6rem; }
|
|
93
98
|
|
|
99
|
+
/* All pseudo-content inherits transparent color so it's invisible */
|
|
100
|
+
[data-ghostly] :where(h1, h2, h3, h4, h5, h6, p, span, a, li,
|
|
101
|
+
em, strong, small, mark, code, label, time, button)::before {
|
|
102
|
+
color: transparent !important;
|
|
103
|
+
visibility: hidden;
|
|
104
|
+
display: inline;
|
|
105
|
+
height: 0;
|
|
106
|
+
}
|
|
107
|
+
|
|
94
108
|
/* Headings: proportional min-height */
|
|
95
109
|
[data-ghostly] :where(h1) { min-height: 1.75em; }
|
|
96
110
|
[data-ghostly] :where(h2) { min-height: 1.5em; }
|
|
97
111
|
[data-ghostly] :where(h3) { min-height: 1.3em; }
|
|
98
112
|
[data-ghostly] :where(h4, h5, h6) { min-height: 1.15em; }
|
|
99
|
-
|
|
100
|
-
/* Paragraphs: taller to simulate multi-line text */
|
|
101
|
-
[data-ghostly] :where(p) { min-height: 3em; }
|
|
102
|
-
|
|
103
|
-
/* Code blocks: taller */
|
|
113
|
+
[data-ghostly] :where(p) { min-height: 1em; }
|
|
104
114
|
[data-ghostly] :where(pre) { min-height: 5em; }
|
|
105
|
-
|
|
106
|
-
/* Interactive elements: reasonable minimums */
|
|
107
115
|
[data-ghostly] :where(input, textarea, select) { min-height: 2.5rem; }
|
|
108
116
|
[data-ghostly] :where(button) { min-height: 2.25rem; }
|
|
109
117
|
|
|
110
118
|
/* ============================================================
|
|
111
|
-
|
|
112
|
-
|
|
119
|
+
4. FLEX/GRID LAYOUT FIX — Surgical, using :has()
|
|
120
|
+
Only expand containers that CONTAIN text elements.
|
|
121
|
+
Empty divs (avatars, icons) are left alone.
|
|
122
|
+
This is safe for sidebars, fixed columns, etc.
|
|
123
|
+
============================================================ */
|
|
124
|
+
|
|
125
|
+
/* Containers holding text elements should grow in flex layouts.
|
|
126
|
+
:has() ensures we ONLY target divs that wrap text, not fixed-size ones. */
|
|
127
|
+
[data-ghostly] :where(
|
|
128
|
+
div, section, article, aside, header, footer, nav, main
|
|
129
|
+
):has(> :where(h1, h2, h3, h4, h5, h6, p, span, a, button, input, label)) {
|
|
130
|
+
flex-grow: 1;
|
|
131
|
+
min-width: 0;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/* Empty containers (avatar placeholders etc): NEVER grow */
|
|
135
|
+
[data-ghostly] :where(div:empty, span:empty) {
|
|
136
|
+
flex-grow: 0 !important;
|
|
137
|
+
flex-shrink: 0 !important;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/* ============================================================
|
|
141
|
+
5. MEDIA ELEMENTS — Hide content, preserve dimensions
|
|
113
142
|
============================================================ */
|
|
114
143
|
|
|
115
144
|
[data-ghostly] :where(img, svg, video, canvas, picture, iframe) {
|
|
@@ -118,7 +147,6 @@
|
|
|
118
147
|
box-shadow: none !important;
|
|
119
148
|
}
|
|
120
149
|
|
|
121
|
-
/* Hide image content without changing dimensions */
|
|
122
150
|
[data-ghostly] :where(img) {
|
|
123
151
|
color: transparent !important;
|
|
124
152
|
object-position: -9999px !important;
|
|
@@ -128,23 +156,19 @@
|
|
|
128
156
|
opacity: 0;
|
|
129
157
|
}
|
|
130
158
|
|
|
131
|
-
/* SVG: hide strokes/fills but keep size */
|
|
132
159
|
[data-ghostly] :where(svg) {
|
|
133
160
|
color: transparent !important;
|
|
134
161
|
fill: transparent !important;
|
|
135
162
|
stroke: transparent !important;
|
|
136
163
|
}
|
|
137
164
|
|
|
138
|
-
/* Only add min-size for SVG icons that might be empty */
|
|
139
165
|
[data-ghostly] :where(svg:empty) {
|
|
140
166
|
min-height: 1.5rem;
|
|
141
167
|
min-width: 1.5rem;
|
|
142
168
|
}
|
|
143
169
|
|
|
144
170
|
/* ============================================================
|
|
145
|
-
|
|
146
|
-
When a component renders an empty div instead of an img
|
|
147
|
-
(e.g. avatar placeholder), it should still show skeleton.
|
|
171
|
+
6. EMPTY CONTAINERS — Skeleton background on placeholders
|
|
148
172
|
============================================================ */
|
|
149
173
|
|
|
150
174
|
[data-ghostly] :where(div:empty) {
|
|
@@ -152,12 +176,9 @@
|
|
|
152
176
|
}
|
|
153
177
|
|
|
154
178
|
/* ============================================================
|
|
155
|
-
|
|
156
|
-
Never override existing border-radius from the component.
|
|
179
|
+
7. BORDER RADIUS — Lowest specificity, component CSS wins
|
|
157
180
|
============================================================ */
|
|
158
181
|
|
|
159
|
-
/* Apply default radius ONLY to elements that don't have one set.
|
|
160
|
-
We use a very low specificity so any component CSS wins. */
|
|
161
182
|
@layer ghostly-defaults {
|
|
162
183
|
[data-ghostly] h1, [data-ghostly] h2, [data-ghostly] h3,
|
|
163
184
|
[data-ghostly] h4, [data-ghostly] h5, [data-ghostly] h6,
|
|
@@ -173,7 +194,7 @@
|
|
|
173
194
|
}
|
|
174
195
|
|
|
175
196
|
/* ============================================================
|
|
176
|
-
|
|
197
|
+
8. CUSTOM LINE COUNT — data-ghostly-lines="N"
|
|
177
198
|
============================================================ */
|
|
178
199
|
|
|
179
200
|
[data-ghostly] :where([data-ghostly-lines="1"]) { min-height: 1em; }
|
|
@@ -186,7 +207,7 @@
|
|
|
186
207
|
[data-ghostly] :where([data-ghostly-lines="8"]) { min-height: 8em; }
|
|
187
208
|
|
|
188
209
|
/* ============================================================
|
|
189
|
-
|
|
210
|
+
9. CUSTOM ASPECT RATIO — data-ghostly-ratio
|
|
190
211
|
============================================================ */
|
|
191
212
|
|
|
192
213
|
[data-ghostly] :where([data-ghostly-ratio="1/1"]) { aspect-ratio: 1/1 !important; }
|
|
@@ -197,7 +218,7 @@
|
|
|
197
218
|
[data-ghostly] :where([data-ghostly-ratio="9/16"]) { aspect-ratio: 9/16 !important; }
|
|
198
219
|
|
|
199
220
|
/* ============================================================
|
|
200
|
-
|
|
221
|
+
10. DECORATIVE — Strip visual noise
|
|
201
222
|
============================================================ */
|
|
202
223
|
|
|
203
224
|
[data-ghostly] :where(hr) {
|
|
@@ -205,7 +226,7 @@
|
|
|
205
226
|
}
|
|
206
227
|
|
|
207
228
|
/* ============================================================
|
|
208
|
-
|
|
229
|
+
11. EXCLUSIONS — data-ghostly-ignore
|
|
209
230
|
============================================================ */
|
|
210
231
|
|
|
211
232
|
[data-ghostly] [data-ghostly-ignore],
|
|
@@ -222,11 +243,15 @@
|
|
|
222
243
|
animation: none !important;
|
|
223
244
|
}
|
|
224
245
|
|
|
246
|
+
[data-ghostly] [data-ghostly-ignore]::before {
|
|
247
|
+
content: none !important;
|
|
248
|
+
}
|
|
249
|
+
|
|
225
250
|
/* ============================================================
|
|
226
|
-
|
|
251
|
+
12. ANIMATIONS
|
|
227
252
|
============================================================ */
|
|
228
253
|
|
|
229
|
-
/* --- Shimmer
|
|
254
|
+
/* --- Shimmer --- */
|
|
230
255
|
|
|
231
256
|
[data-ghostly='shimmer'] :where(
|
|
232
257
|
h1, h2, h3, h4, h5, h6,
|
|
@@ -256,7 +281,7 @@
|
|
|
256
281
|
100% { background-position: -100% 0; }
|
|
257
282
|
}
|
|
258
283
|
|
|
259
|
-
/* --- Pulse
|
|
284
|
+
/* --- Pulse --- */
|
|
260
285
|
|
|
261
286
|
[data-ghostly='pulse'] :where(
|
|
262
287
|
h1, h2, h3, h4, h5, h6,
|
|
@@ -277,7 +302,7 @@
|
|
|
277
302
|
50% { opacity: 0.4; }
|
|
278
303
|
}
|
|
279
304
|
|
|
280
|
-
/* --- Wave
|
|
305
|
+
/* --- Wave --- */
|
|
281
306
|
|
|
282
307
|
[data-ghostly='wave'] :where(
|
|
283
308
|
h1, h2, h3, h4, h5, h6,
|
|
@@ -301,7 +326,6 @@
|
|
|
301
326
|
100% { opacity: 1; }
|
|
302
327
|
}
|
|
303
328
|
|
|
304
|
-
/* Stagger direct children for cascading effect */
|
|
305
329
|
[data-ghostly='wave'] > :nth-child(1) { animation-delay: 0ms !important; }
|
|
306
330
|
[data-ghostly='wave'] > :nth-child(2) { animation-delay: 80ms !important; }
|
|
307
331
|
[data-ghostly='wave'] > :nth-child(3) { animation-delay: 160ms !important; }
|
|
@@ -317,7 +341,7 @@
|
|
|
317
341
|
[data-ghostly='wave'] > :nth-child(n+13) { animation-delay: 960ms !important; }
|
|
318
342
|
|
|
319
343
|
/* ============================================================
|
|
320
|
-
|
|
344
|
+
13. SMOOTH TRANSITION
|
|
321
345
|
============================================================ */
|
|
322
346
|
|
|
323
347
|
[data-ghostly-smooth] :where(
|
|
@@ -338,7 +362,7 @@
|
|
|
338
362
|
}
|
|
339
363
|
|
|
340
364
|
/* ============================================================
|
|
341
|
-
|
|
365
|
+
14. ACCESSIBILITY
|
|
342
366
|
============================================================ */
|
|
343
367
|
|
|
344
368
|
@media (prefers-reduced-motion: reduce) {
|