Photo by Bernd 📷 Dittrich on Unsplash
Tooltip Neo Brutalism Design Using HTML, CSS, and JavaScript
Create a modern, responsive tooltip design in the neo-brutalist style using HTML, CSS, and JavaScript, featuring bold colors, thick borders, and heavy shadows for a raw, unpolished aesthetic. This implementation focuses on striking visuals, accessible interactions, and maintainable code, ideal for providing contextual information in web interfaces.
Prerequisites
- Basic HTML, CSS, and JavaScript knowledge
- A code editor (e.g., VS Code)
Part 1: Tooltip Neo Brutalism Design
Step 1: HTML Structure (index.html)
Create a semantic HTML structure for the neo-brutalist tooltips with a container, trigger buttons, and tooltip elements.
<div class="tooltip-container" role="group" aria-label="Neo-brutalist tooltips">
<div class="tooltip-wrapper">
<button class="tooltip-trigger" aria-describedby="tooltip-primary" tabindex="0">Primary</button>
<span class="tooltip" id="tooltip-primary" role="tooltip">Primary Action Info</span>
</div>
<div class="tooltip-wrapper">
<button class="tooltip-trigger secondary" aria-describedby="tooltip-secondary" tabindex="0">Secondary</button>
<span class="tooltip" id="tooltip-secondary" role="tooltip">Secondary Action Info</span>
</div>
</div>
Step 2: Core CSS Implementation (styles.css)
Style the tooltips and triggers with neo-brutalist aesthetics: bold colors, thick borders, heavy shadows, and a monospace font.
:root {
--gray-900: #111827;
--gray-700: #374151;
--gray-200: #e5e7eb;
--gray-100: #f3f4f6;
--white: #ffffff;
--primary-600: #2563eb;
--primary-500: #3b82f6;
--accent-500: #f59e0b;
--spacing-xs: 4px;
--spacing-sm: 8px;
--spacing-md: 12px;
--spacing-lg: 16px;
--radius-sm: 4px;
--radius-md: 6px;
--transition: 0.2s ease;
--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
--shadow-neo: 4px 4px 0 var(--gray-900);
--font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
--font-mono: 'IBM Plex Mono', monospace;
}
.tooltip-container {
display: flex;
gap: var(--spacing-lg);
background: var(--white);
padding: var(--spacing-lg);
border-radius: var(--radius-md);
box-shadow: var(--shadow-md);
flex-wrap: wrap;
justify-content: center;
}
.tooltip-wrapper {
position: relative;
display: inline-flex;
align-items: center;
}
.tooltip-trigger {
padding: var(--spacing-sm) var(--spacing-md);
font-family: var(--font-mono);
font-size: 0.9375rem;
font-weight: 600;
text-transform: uppercase;
color: var(--gray-900);
background: var(--primary-500);
border: 3px solid var(--gray-900);
border-radius: var(--radius-sm);
box-shadow: var(--shadow-neo);
cursor: pointer;
transition: transform var(--transition), box-shadow var(--transition);
}
.tooltip-trigger:hover {
transform: translate(2px, 2px);
box-shadow: 2px 2px 0 var(--gray-900);
}
.tooltip-trigger:focus {
outline: none;
box-shadow: 2px 2px 0 var(--accent-500), 0 0 0 3px var(--primary-600);
}
.tooltip-trigger.secondary {
background: var(--accent-500);
}
.tooltip {
position: absolute;
top: calc(100% + var(--spacing-sm));
left: 50%;
transform: translateX(-50%) scale(0);
background: var(--gray-900);
color: var(--white);
font-family: var(--font-mono);
font-size: 0.875rem;
padding: var(--spacing-xs) var(--spacing-sm);
border: 2px solid var(--gray-900);
border-radius: var(--radius-sm);
box-shadow: var(--shadow-neo);
white-space: nowrap;
opacity: 0;
transition: transform var(--transition), opacity var(--transition);
z-index: 10;
}
.tooltip-wrapper:hover .tooltip,
.tooltip-trigger:focus + .tooltip {
transform: translateX(-50%) scale(1);
opacity: 1;
}
.tooltip::before {
content: '';
position: absolute;
bottom: 100%;
left: 50%;
transform: translateX(-50%);
border: 6px solid transparent;
border-bottom-color: var(--gray-900);
}
@media (max-width: 640px) {
.tooltip-container {
flex-direction: column;
padding: var(--spacing-md);
gap: var(--spacing-sm);
}
.tooltip-trigger {
padding: var(--spacing-xs) var(--spacing-sm);
font-size: 0.875rem;
}
.tooltip {
font-size: 0.75rem;
padding: var(--spacing-xs);
}
}
Step 3: JavaScript Implementation (script.js)
Add JavaScript to ensure tooltip visibility on focus for keyboard users, complementing CSS hover and focus states.
document.addEventListener('DOMContentLoaded', () => {
const tooltipTriggers = document.querySelectorAll('.tooltip-trigger');
tooltipTriggers.forEach(trigger => {
// Ensure tooltip remains visible on focus
trigger.addEventListener('focus', () => {
const tooltip = trigger.nextElementSibling;
tooltip.style.transform = 'translateX(-50%) scale(1)';
tooltip.style.opacity = '1';
});
trigger.addEventListener('blur', () => {
const tooltip = trigger.nextElementSibling;
tooltip.style.transform = 'translateX(-50%) scale(0)';
tooltip.style.opacity = '0';
});
// Keyboard support for Enter key to simulate click
trigger.addEventListener('keydown', (e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
trigger.click();
}
});
});
});
Explanation
- Layout: Tooltips are housed in a flexbox container with a white background, shadow, and rounded corners, mimicking a card. Each tooltip wrapper contains a trigger button and a tooltip, positioned relatively.
- Styling: Trigger buttons use a blue (
--primary-500) or orange (--accent-500) background, thick black borders (3px), and offset shadows (--shadow-neo) for a neo-brutalist look. Tooltips use a dark background (--gray-900) with white text, a monospace font, and a triangular arrow (::before). - Interactivity: CSS handles tooltip visibility on hover and focus with scale and opacity transitions. JavaScript ensures tooltips remain visible during focus for keyboard users, syncing with CSS states.
- Visual Feedback: Hovering a trigger shifts it slightly (
translate(2px, 2px)) with a reduced shadow; focus adds a dual shadow (accent and primary). Tooltips scale up (scale(1)) and fade in on trigger hover/focus. - Responsiveness: A media query (
@media (max-width: 640px)) switches the container to a column layout and reduces trigger and tooltip sizes for mobile usability. - Accessibility:
role="group"andaria-labelon the container, plusrole="tooltip"andaria-describedbyon triggers, ensure screen reader compatibility.tabindex="0"and keyboard support (Enter/Space) enable navigation. High contrast ratios enhance readability.
Accessibility Features
- Use
role="group",role="tooltip", andaria-describedbyfor semantic structure - Ensure high contrast ratios for text and backgrounds (4.5:1 minimum)
- Support keyboard navigation with
tabindex, Enter, and Space keys - Use bold, readable typography (monospace for neo-brutalism)
Golden Rules
- Use CSS variables for consistent theming
- Implement bold borders and heavy shadows for neo-brutalist style
- Ensure accessibility with ARIA and keyboard support
- Optimize for mobile with responsive design
Conclusion
A professional neo-brutalist tooltip should embrace raw, bold aesthetics, provide clear contextual information, remain responsive, and follow accessibility guidelines. This solution uses HTML, CSS, and JavaScript for striking tooltips with primary and secondary trigger variants, featuring heavy shadows and a monospace font. Experiment with colors, shadow offsets, or add dynamic positioning logic. Test across devices and browsers for usability. Feel free to leave comments with any questions or suggestions!
Comments
Post a Comment