💬 Tooltips & Popovers Design Guide
Tooltips та popovers provide contextual help without cluttering interface. Tooltips (small, text-only) appear on hover for brief labels або explanations. Popovers (larger, може contain titles/paragraphs/images) appear on click для detailed information. For mushroom education site, tooltips clarify: technical terms ("What is mycelium?"), dosage units ("mg psilocybin"), safety icons. Popovers present: detailed species warnings, cultivation tip expansions, reference citations. Effective tooltip/popover design balances discoverability (clear triggers), positioning (not obscuring content), brevity (concise text), та accessibility (keyboard invocation, screen reader support). Цей guide охоплює CSS-only та JavaScript implementations, arrow positioning, mobile behavior (tap-to-show), та ARIA patterns.
🎨 Tooltips Demo
Hover over highlighted terms to see tooltips:
Mycelium colonizes substrate during cultivation. Proper sterile technique prevents contamination.
Dosage calculator helps determine appropriate dose based на body weight та desired intensity.
📋 Popovers Demo
Click button to trigger popover:
• Start з low dose (1-2g dried)
• Ensure safe, comfortable environment
• Have trusted trip sitter present
• Never mix з alcohol або other drugs
• Avoid if personal/family history of psychosis
💻 CSS Implementation
CSS-Only Tooltip:
/* HTML */
<span data-tooltip="Tooltip text">Hover me</span>
/* CSS */
[data-tooltip] {
position: relative;
cursor: help;
border-bottom: 1px dotted currentColor; /* Indicate clickability */
}
/* Tooltip box */
[data-tooltip]::after {
content: attr(data-tooltip); /* Use data attribute */
position: absolute;
bottom: 100%;
left: 50%;
transform: translateX(-50%) translateY(-8px);
background: #2c3e50;
color: white;
padding: 8px 12px;
border-radius: 6px;
font-size: 0.875em;
white-space: nowrap;
/* Hidden by default */
opacity: 0;
pointer-events: none;
transition: opacity 0.3s, transform 0.3s;
z-index: 1000;
}
/* Arrow */
[data-tooltip]::before {
content: '';
position: absolute;
bottom: 100%;
left: 50%;
transform: translateX(-50%);
border: 6px solid transparent;
border-top-color: #2c3e50; /* Arrow pointing down */
opacity: 0;
pointer-events: none;
transition: opacity 0.3s;
}
/* Show on hover */
[data-tooltip]:hover::after,
[data-tooltip]:hover::before {
opacity: 1;
}
Tooltip Positioning Variants:
/* Top tooltip (default above) */
[data-tooltip-top]::after {
bottom: 100%;
left: 50%;
transform: translateX(-50%) translateY(-8px);
}
/* Bottom tooltip */
[data-tooltip-bottom]::after {
top: 100%;
left: 50%;
transform: translateX(-50%) translateY(8px);
}
/* Left tooltip */
[data-tooltip-left]::after {
right: 100%;
top: 50%;
transform: translateX(-8px) translateY(-50%);
}
/* Right tooltip */
[data-tooltip-right]::after {
left: 100%;
top: 50%;
transform: translateX(8px) translateY(-50%);
}
JavaScript Popover:
/* HTML */
<button onclick="togglePopover('myPopover')">Open Popover</button>
<div class="popover" id="myPopover">
<div class="popover-title">Title</div>
<div class="popover-content">Content...</div>
</div>
/* CSS */
.popover {
position: absolute;
background: white;
border: 2px solid #e9ecef;
border-radius: 12px;
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.15);
padding: 20px;
width: 300px;
/* Hidden by default */
display: none;
z-index: 1000;
}
.popover.active {
display: block;
animation: popoverFadeIn 0.3s;
}
@keyframes popoverFadeIn {
від { opacity: 0; transform: translateY(-10px); }
до { opacity: 1; transform: translateY(0); }
}
/* JavaScript */
function togglePopover(id) {
const popover = document.getElementById(id);
popover.classList.toggle('active');
}
// Close on outside click
document.addEventListener('click', (e) => {
if (!e.target.closest('.popover') && !e.target.closest('.popover-trigger')) {
document.querySelectorAll('.popover').forEach(p => p.classList.remove('active'));
}
});
Positioning Library (Popper.js):
/* For advanced positioning, use Popper.js */
<script src="https://unpkg.com/@popperjs/core@2"></script>
const button = document.querySelector('.popover-trigger');
const tooltip = document.querySelector('.popover');
const popperInstance = Popper.createPopper(button, tooltip, {
placement: 'top', // або 'bottom', 'left', 'right'
modifiers: [
{
name: 'offset',
options: {
offset: [0, 8], /* X, Y offset */
},
},
],
});
♿ Accessibility
ARIA для Tooltips:
<!-- Tooltip з aria-describedby -->
<button aria-describedby="tooltip1">
Hover me
</button>
<div id="tooltip1" role="tooltip" hidden>
Tooltip text
</div>
/* Show/hide з JavaScript */
button.addEventListener('mouseenter', () => {
tooltip.removeAttribute('hidden');
});
button.addEventListener('mouseleave', () => {
tooltip.setAttribute('hidden', '');
});
Keyboard Accessibility:
/* Show tooltip на focus (keyboard users) */
[data-tooltip]:focus::after,
[data-tooltip]:focus::before {
opacity: 1;
}
/* Ensure focusable */
[data-tooltip] {
tabindex: 0; /* Make focusable */
outline: none; /* Remove default outline */
}
[data-tooltip]:focus {
outline: 2px solid #a8edea; /* Custom focus indicator */
outline-offset: 2px;
}
Mobile Considerations:
/* Mobile: Tap to show (no hover) */
@media (max-width: 768px) {
[data-tooltip]::after,
[data-tooltip]::before {
/* Show on active (tap) */
opacity: 0;
}
[data-tooltip]:active::after,
[data-tooltip]:active::before {
opacity: 1;
}
}
/* Alternative: JavaScript click handler для mobile */
if ('ontouchstart' in window) {
document.querySelectorAll('[data-tooltip]').forEach(el => {
el.addEventListener('click', function(e) {
e.preventDefault();
this.classList.toggle('tooltip-active');
});
});
}
✅ Tooltips та Popovers Checklist
Tooltips Checklist:
- ☐ Brief text (1-2 sentences maximum)
- ☐ Appears on hover + focus
- ☐ Arrow points до trigger element
- ☐ Positioned не obscure content
- ☐ Smooth fadeвід/fadeOut (0.3s)
- ☐ High z-index (1000+)
- ☐ Mobile: Tap-to-show або avoid
Popovers Checklist:
- ☐ Triggered by click (not hover)
- ☐ Close button visible
- ☐ Close на outside click
- ☐ Close на ESC key
- ☐ Может contain rich content (title, paragraphs, buttons)
- ☐ Positioned dynamically (Popper.js recommended)
- ☐ Max-width set (250-400px)
- ☐ ARIA: role="dialog" або role="tooltip"