0
# Spectrum CSS Popover
1
2
Spectrum CSS Popover is a floating content container component that provides consistent positioning, animations, and visual styling for tooltips, dropdown menus, context menus, and modal-like interfaces. It supports comprehensive positioning options, optional pointer tips, theming variants, and full RTL/LTR internationalization support as part of Adobe's Spectrum Design System.
3
4
## Package Information
5
6
- **Package Name**: @spectrum-css/popover
7
- **Package Type**: npm
8
- **Language**: CSS
9
- **Installation**: `npm install @spectrum-css/popover`
10
11
## Core Imports
12
13
```css
14
/* Main popover styles (includes spectrum-two theme by default) */
15
@import "@spectrum-css/popover/index.css";
16
17
/* Alternative theme variants (optional) */
18
@import "@spectrum-css/popover/themes/spectrum.css"; /* Legacy Spectrum theme */
19
@import "@spectrum-css/popover/themes/express.css"; /* Express theme (borderless) */
20
```
21
22
CDN usage:
23
```html
24
<link rel="stylesheet" href="https://unpkg.com/@spectrum-css/popover@8.2.0/dist/index.css">
25
<!-- Optional: Override default theme with legacy or express -->
26
<link rel="stylesheet" href="https://unpkg.com/@spectrum-css/popover@8.2.0/dist/themes/express.css">
27
```
28
29
## Basic Usage
30
31
```html
32
<!-- Basic popover -->
33
<div class="spectrum-Popover is-open" role="presentation">
34
<p>Popover content goes here</p>
35
</div>
36
37
<!-- Popover with tip pointer -->
38
<div class="spectrum-Popover spectrum-Popover--withTip spectrum-Popover--bottom is-open" role="presentation">
39
<p>Content with tip pointing up</p>
40
<svg class="spectrum-Popover-tip" viewBox="0 -0.5 16 9" width="10">
41
<path class="spectrum-Popover-tip-triangle" d="M-1,-1 8,8 17,-1"></path>
42
</svg>
43
</div>
44
45
<!-- Positioned popover with alignment -->
46
<div class="spectrum-Popover spectrum-Popover--withTip spectrum-Popover--top-left is-open" role="presentation">
47
<p>Positioned above trigger, left-aligned</p>
48
<svg class="spectrum-Popover-tip" viewBox="0 -0.5 16 9" width="10">
49
<path class="spectrum-Popover-tip-triangle" d="M-1,-1 8,8 17,-1"></path>
50
</svg>
51
</div>
52
```
53
54
## Architecture
55
56
The Spectrum CSS Popover component consists of several key architectural layers:
57
58
- **Base Component**: `.spectrum-Popover` provides core styling, positioning, theming, and animation foundation
59
- **State Management**: `.is-open` class controls visibility and triggers directional animations
60
- **Positioning System**: Modifier classes control popover placement relative to trigger elements (top, bottom, left, right, start, end)
61
- **Tip System**: Optional triangular pointer with SVG-based rendering and intelligent positioning
62
- **Theme Variants**: Multiple design themes (Spectrum, Express) with different visual characteristics
63
- **Internationalization**: Full RTL/LTR support using logical positioning properties
64
- **Customization Layer**: CSS custom properties enabling extensive theming and behavioral customization
65
66
## Capabilities
67
68
### Base Popover Class
69
70
The foundational popover container with core styling and behavior.
71
72
```css { .api }
73
.spectrum-Popover {
74
/* Core popover styling with absolute positioning, flexbox layout, theming */
75
/* Includes border, background, shadow, corner radius, and content padding */
76
/* Provides CSS custom property integration for theming and customization */
77
}
78
```
79
80
### Open State
81
82
Controls popover visibility and animation states.
83
84
```css { .api }
85
.spectrum-Popover.is-open {
86
/* Makes popover visible and triggers directional animation */
87
/* Animation direction depends on position modifier class */
88
/* Uses CSS transforms for smooth animation transitions */
89
}
90
```
91
92
### Tip Variants
93
94
Enables triangular pointer tips that connect popovers to their trigger elements.
95
96
```css { .api }
97
.spectrum-Popover--withTip {
98
/* Enables overflow:visible for tip rendering */
99
/* Adds margin spacing to account for tip dimensions */
100
/* Provides tip positioning and styling foundation */
101
}
102
103
.spectrum-Popover-tip {
104
/* SVG container for triangular pointer */
105
/* Absolutely positioned based on popover placement */
106
/* Size controlled by --spectrum-popover-pointer-width/height */
107
}
108
109
.spectrum-Popover-tip-triangle {
110
/* SVG path element creating triangular shape */
111
/* Fill matches popover background color */
112
/* Stroke matches popover border color and width */
113
}
114
```
115
116
### Primary Positioning
117
118
Core directional positioning relative to trigger elements.
119
120
```css { .api }
121
.spectrum-Popover--top {
122
/* Positions popover above trigger element */
123
/* Animates upward when opened with is-open class */
124
/* Includes margin spacing for tip when combined with --withTip */
125
}
126
127
.spectrum-Popover--bottom {
128
/* Positions popover below trigger element */
129
/* Animates downward when opened with is-open class */
130
/* Includes margin spacing for tip when combined with --withTip */
131
}
132
133
.spectrum-Popover--left {
134
/* Positions popover to left of trigger element */
135
/* Animates leftward when opened with is-open class */
136
/* Fixed directional positioning, not affected by text direction */
137
}
138
139
.spectrum-Popover--right {
140
/* Positions popover to right of trigger element */
141
/* Animates rightward when opened with is-open class */
142
/* Fixed directional positioning, not affected by text direction */
143
}
144
```
145
146
### Logical Positioning
147
148
Internationalization-aware positioning that adapts to text direction.
149
150
```css { .api }
151
.spectrum-Popover--start {
152
/* Logical start positioning (left in LTR, right in RTL) */
153
/* Direction-aware animations for international layouts */
154
/* Animates toward logical start when opened */
155
}
156
157
.spectrum-Popover--end {
158
/* Logical end positioning (right in LTR, left in RTL) */
159
/* Direction-aware animations for international layouts */
160
/* Animates toward logical end when opened */
161
}
162
```
163
164
### Alignment Variants
165
166
Compound positioning classes for precise popover alignment relative to triggers.
167
168
```css { .api }
169
.spectrum-Popover--top-left {
170
/* Popover above trigger, left-aligned */
171
/* Tip positioned at left side when using --withTip */
172
}
173
174
.spectrum-Popover--top-right {
175
/* Popover above trigger, right-aligned */
176
/* Tip positioned at right side when using --withTip */
177
}
178
179
.spectrum-Popover--top-start {
180
/* Popover above trigger, logical start-aligned */
181
/* RTL/LTR aware tip positioning */
182
}
183
184
.spectrum-Popover--top-end {
185
/* Popover above trigger, logical end-aligned */
186
/* RTL/LTR aware tip positioning */
187
}
188
189
.spectrum-Popover--bottom-left {
190
/* Popover below trigger, left-aligned */
191
/* Tip positioned at left side when using --withTip */
192
}
193
194
.spectrum-Popover--bottom-right {
195
/* Popover below trigger, right-aligned */
196
/* Tip positioned at right side when using --withTip */
197
}
198
199
.spectrum-Popover--bottom-start {
200
/* Popover below trigger, logical start-aligned */
201
/* RTL/LTR aware tip positioning */
202
}
203
204
.spectrum-Popover--bottom-end {
205
/* Popover below trigger, logical end-aligned */
206
/* RTL/LTR aware tip positioning */
207
}
208
209
.spectrum-Popover--left-top {
210
/* Popover left of trigger, top-aligned */
211
/* Tip positioned at top when using --withTip */
212
}
213
214
.spectrum-Popover--left-bottom {
215
/* Popover left of trigger, bottom-aligned */
216
/* Tip positioned at bottom when using --withTip */
217
}
218
219
.spectrum-Popover--right-top {
220
/* Popover right of trigger, top-aligned */
221
/* Tip positioned at top when using --withTip */
222
}
223
224
.spectrum-Popover--right-bottom {
225
/* Popover right of trigger, bottom-aligned */
226
/* Tip positioned at bottom when using --withTip */
227
}
228
229
.spectrum-Popover--start-top {
230
/* Popover at logical start, top-aligned */
231
/* RTL/LTR aware positioning and tip placement */
232
}
233
234
.spectrum-Popover--start-bottom {
235
/* Popover at logical start, bottom-aligned */
236
/* RTL/LTR aware positioning and tip placement */
237
}
238
239
.spectrum-Popover--end-top {
240
/* Popover at logical end, top-aligned */
241
/* RTL/LTR aware positioning and tip placement */
242
}
243
244
.spectrum-Popover--end-bottom {
245
/* Popover at logical end, bottom-aligned */
246
/* RTL/LTR aware positioning and tip placement */
247
}
248
```
249
250
## CSS Custom Properties
251
252
### Animation Properties
253
254
Control popover animation behavior and timing.
255
256
```css { .api }
257
--spectrum-popover-animation-distance {
258
/* Distance popover moves during open/close animation */
259
/* Default: var(--spectrum-spacing-100) */
260
/* Affects both visual movement and spacing calculations */
261
}
262
```
263
264
### Overlay Animation Properties
265
266
Control overlay-based animation timing (inherited from commons/overlay.css).
267
268
```css { .api }
269
--spectrum-overlay-animation-duration {
270
/* Duration for opening animation */
271
/* Default: var(--spectrum-animation-duration-100) */
272
/* Inherited from %spectrum-overlay mixin */
273
}
274
275
--spectrum-overlay-animation-duration-opened {
276
/* Duration for closing animation */
277
/* Default: var(--spectrum-animation-duration-0) */
278
/* Inherited from %spectrum-overlay mixin */
279
}
280
```
281
282
### Visual Appearance Properties
283
284
Control popover visual styling and theming.
285
286
```css { .api }
287
--spectrum-popover-background-color {
288
/* Background color of popover content area */
289
/* Default: var(--spectrum-background-layer-2-color) */
290
/* Applied to main popover container and tip fill */
291
}
292
293
--spectrum-popover-border-color {
294
/* Border color around popover perimeter */
295
/* Default: var(--spectrum-gray-400) */
296
/* Applied to container border and tip stroke */
297
}
298
299
--spectrum-popover-border-width {
300
/* Width of popover border */
301
/* Default: var(--spectrum-border-width-100) (spectrum-two theme) */
302
/* Default: 0 (express theme for borderless appearance) */
303
/* Set via theme files, not directly in main CSS */
304
}
305
306
--spectrum-popover-corner-radius {
307
/* Border radius for rounded corners */
308
/* Default: var(--spectrum-corner-radius-100) */
309
/* Affects visual appearance and tip edge offset calculations */
310
}
311
```
312
313
### Spacing Properties
314
315
Control internal and external spacing.
316
317
```css { .api }
318
--spectrum-popover-content-area-spacing-vertical {
319
/* Vertical padding inside popover content area */
320
/* Default: var(--spectrum-popover-top-to-content-area) */
321
/* Provides consistent internal spacing for content */
322
}
323
```
324
325
### Shadow Properties
326
327
Control drop shadow appearance for depth and elevation.
328
329
```css { .api }
330
--spectrum-popover-shadow-horizontal {
331
/* Horizontal offset for drop shadow */
332
/* Default: var(--spectrum-drop-shadow-x) */
333
}
334
335
--spectrum-popover-shadow-vertical {
336
/* Vertical offset for drop shadow */
337
/* Default: var(--spectrum-drop-shadow-y) */
338
}
339
340
--spectrum-popover-shadow-blur {
341
/* Blur radius for drop shadow */
342
/* Default: var(--spectrum-drop-shadow-blur) */
343
}
344
345
--spectrum-popover-shadow-color {
346
/* Color of drop shadow */
347
/* Default: var(--spectrum-drop-shadow-color) */
348
}
349
```
350
351
### Tip Properties
352
353
Control triangular pointer tip dimensions and positioning.
354
355
```css { .api }
356
--spectrum-popover-pointer-width {
357
/* Width of triangular tip pointer */
358
/* Default: var(--spectrum-popover-tip-width) */
359
/* Used for tip sizing and margin calculations */
360
}
361
362
--spectrum-popover-pointer-height {
363
/* Height of triangular tip pointer */
364
/* Default: var(--spectrum-popover-tip-height) */
365
/* Used for tip sizing and margin calculations */
366
}
367
368
--spectrum-popover-pointer-edge-offset {
369
/* Default distance from popover edge to tip center */
370
/* Default: calc(var(--spectrum-corner-radius-100) + (var(--spectrum-popover-tip-width) / 2)) */
371
/* Calculated to account for corner radius and tip centering */
372
}
373
374
--spectrum-popover-pointer-edge-spacing {
375
/* Distance from edge when centering tip to source element */
376
/* Default: calc(var(--spectrum-popover-pointer-edge-offset) - (var(--spectrum-popover-tip-width) / 2)) */
377
/* Override to center tip on specific trigger element */
378
}
379
```
380
381
### Modifier Properties
382
383
Override any component property for customization.
384
385
```css { .api }
386
--mod-popover-animation-distance /* Override animation distance */
387
--mod-popover-background-color /* Override background color */
388
--mod-popover-border-color /* Override border color */
389
--mod-popover-border-width /* Override border width */
390
--mod-popover-content-area-spacing-vertical /* Override content padding */
391
--mod-popover-corner-radius /* Override corner radius */
392
--mod-popover-filter /* Override drop shadow filter */
393
--mod-popover-pointer-edge-spacing /* Override tip edge spacing */
394
--mod-popover-pointer-height /* Override tip height */
395
--mod-popover-pointer-width /* Override tip width */
396
--mod-popover-shadow-blur /* Override shadow blur */
397
--mod-popover-shadow-color /* Override shadow color */
398
--mod-popover-shadow-horizontal /* Override shadow horizontal offset */
399
--mod-popover-shadow-vertical /* Override shadow vertical offset */
400
--mod-overlay-animation-duration /* Override overlay opening animation duration */
401
--mod-overlay-animation-duration-opened /* Override overlay closing animation duration */
402
```
403
404
### High Contrast Properties
405
406
Accessibility enhancements for forced-colors mode.
407
408
```css { .api }
409
--highcontrast-popover-border-color {
410
/* Border color override for Windows high contrast mode */
411
/* Default: CanvasText */
412
/* Automatically applied when (forced-colors: active) */
413
}
414
```
415
416
## Usage Examples
417
418
### Basic Tooltip
419
420
```html
421
<!-- Simple tooltip above element -->
422
<div class="spectrum-Popover spectrum-Popover--withTip spectrum-Popover--top is-open">
423
<p>This is a tooltip message</p>
424
<svg class="spectrum-Popover-tip" viewBox="0 -0.5 16 9" width="10">
425
<path class="spectrum-Popover-tip-triangle" d="M-1,-1 8,8 17,-1"></path>
426
</svg>
427
</div>
428
```
429
430
### Dropdown Menu
431
432
```html
433
<!-- Dropdown menu below button -->
434
<div class="spectrum-Popover spectrum-Popover--bottom-start is-open">
435
<div class="spectrum-Menu">
436
<div class="spectrum-Menu-item">Option 1</div>
437
<div class="spectrum-Menu-item">Option 2</div>
438
<div class="spectrum-Menu-item">Option 3</div>
439
</div>
440
</div>
441
```
442
443
### Context Menu with Tip
444
445
```html
446
<!-- Context menu with pointer tip -->
447
<div class="spectrum-Popover spectrum-Popover--withTip spectrum-Popover--right-top is-open">
448
<div class="spectrum-Menu">
449
<div class="spectrum-Menu-item">Cut</div>
450
<div class="spectrum-Menu-item">Copy</div>
451
<div class="spectrum-Menu-item">Paste</div>
452
</div>
453
<!-- Note: Right/left positioning uses rotated viewBox dimensions (9x16) -->
454
<svg class="spectrum-Popover-tip" viewBox="0 -0.5 9 16" width="10">
455
<path class="spectrum-Popover-tip-triangle" d="M-1,-1 8,8 -1,17"></path>
456
</svg>
457
</div>
458
```
459
460
### Custom Styled Popover
461
462
```html
463
<div class="spectrum-Popover spectrum-Popover--withTip spectrum-Popover--bottom is-open"
464
style="--mod-popover-background-color: #1e1e1e; --mod-popover-border-color: #333; --mod-popover-shadow-color: rgba(0,0,0,0.5);">
465
<p style="color: white;">Dark themed popover</p>
466
<svg class="spectrum-Popover-tip" viewBox="0 -0.5 16 9" width="10">
467
<path class="spectrum-Popover-tip-triangle" d="M-1,-1 8,8 17,-1"></path>
468
</svg>
469
</div>
470
```
471
472
### Centered Tip on Small Trigger
473
474
```html
475
<!-- Custom tip positioning for precise alignment -->
476
<div class="spectrum-Popover spectrum-Popover--withTip spectrum-Popover--top is-open"
477
style="--mod-popover-pointer-edge-spacing: 20px;">
478
<p>Tip centered on 40px wide button</p>
479
<svg class="spectrum-Popover-tip" viewBox="0 -0.5 16 9" width="10">
480
<path class="spectrum-Popover-tip-triangle" d="M-1,-1 8,8 17,-1"></path>
481
</svg>
482
</div>
483
```
484
485
### RTL Layout Support
486
487
```html
488
<!-- Logical positioning for international layouts -->
489
<div dir="rtl">
490
<div class="spectrum-Popover spectrum-Popover--withTip spectrum-Popover--start is-open">
491
<p>هذا محتوى النافذة المنبثقة</p>
492
<svg class="spectrum-Popover-tip" viewBox="0 -0.5 9 16" width="10">
493
<path class="spectrum-Popover-tip-triangle" d="M-1,-1 8,8 -1,17"></path>
494
</svg>
495
</div>
496
</div>
497
```
498
499
## Theming Integration
500
501
### Default Theme (Spectrum-Two)
502
503
The main `index.css` imports `spectrum-two.css` by default, which sets:
504
505
```css
506
/* Included automatically in index.css */
507
--spectrum-popover-border-width: var(--spectrum-border-width-100);
508
```
509
510
### Express Theme (Borderless)
511
512
Override the default theme for borderless popovers:
513
514
```css
515
@import "@spectrum-css/popover/index.css";
516
@import "@spectrum-css/popover/themes/express.css";
517
518
/* Express theme automatically sets --spectrum-popover-border-width: 0 */
519
/* Results in borderless popovers with shadow-only elevation */
520
```
521
522
### Legacy Theme (Spectrum 1)
523
524
Use the legacy Spectrum 1 visual style:
525
526
```css
527
@import "@spectrum-css/popover/index.css";
528
@import "@spectrum-css/popover/themes/spectrum.css";
529
530
/* Legacy theme inherits spectrum-two settings but can be customized */
531
```
532
533
### Custom Theme Integration
534
535
```css
536
@import "@spectrum-css/popover/index.css";
537
538
/* Custom theme overrides */
539
.my-theme .spectrum-Popover {
540
--mod-popover-background-color: var(--my-popover-bg);
541
--mod-popover-border-color: var(--my-popover-border);
542
--mod-popover-shadow-color: var(--my-popover-shadow);
543
--mod-popover-corner-radius: var(--my-border-radius);
544
--mod-popover-border-width: var(--my-border-width);
545
}
546
```
547
548
## JavaScript Integration Patterns
549
550
While this is a CSS-only component, common JavaScript integration patterns include:
551
552
```javascript
553
// Show/hide popover
554
const popover = document.querySelector('.spectrum-Popover');
555
popover.classList.add('is-open');
556
557
// Position popover relative to trigger
558
function positionPopover(trigger, popover, placement = 'bottom') {
559
popover.className = `spectrum-Popover spectrum-Popover--${placement} is-open`;
560
// Additional positioning logic would be implemented here
561
}
562
563
// Toggle with animation
564
function togglePopover(popover) {
565
if (popover.classList.contains('is-open')) {
566
popover.classList.remove('is-open');
567
} else {
568
popover.classList.add('is-open');
569
}
570
}
571
```
572
573
## Accessibility Considerations
574
575
- Use `role="presentation"` on popover container as shown in examples
576
- Ensure proper focus management when opening/closing
577
- Consider `aria-describedby` or `aria-labelledby` relationships with trigger elements
578
- Provide keyboard navigation support (Escape to close, etc.)
579
- Test with screen readers and high contrast mode
580
- The component automatically adapts to Windows high contrast mode via `--highcontrast-popover-border-color`
581
582
## Browser Support
583
584
- Modern browsers supporting CSS custom properties (IE 11+ with polyfills)
585
- CSS Grid and Flexbox support required
586
- SVG support required for tip functionality
587
- Container queries supported where available (progressive enhancement)
588
589
## Peer Dependencies
590
591
The component integrates with related Spectrum CSS components:
592
593
- `@spectrum-css/tokens` - Design system tokens (>=16.0.0 <17.0.0, optional)
594
- `@spectrum-css/menu` - For dropdown menus within popovers (>=9.0.0 <10.0.0, optional)
595
- `@spectrum-css/dialog` - For dialog content within popovers (>=12.0.0 <13.0.0, optional)
596
- `@spectrum-css/alertdialog` - For alert dialogs within popovers (>=4.0.0 <5.0.0, optional)
597
- `@spectrum-css/divider` - For content separation within popovers (>=5.0.0 <6.0.0, optional)
598
599
All peer dependencies are optional and only needed when using specific content types within popovers.