14 Material Design CSS Components 10 / 14
Material Design Tooltip CSS
Plain and rich tooltips in four directions, linear progress (determinate and indeterminate), circular progress, notification badges, and page dot navigation — all pure CSS.
This is a full-page demo — interact inside the frame above, or open it in the playground for the full-screen experience.
The code
<div class="md-10">
<div class="md-10__wrap">
<div class="md-10__page-title">Material Design Tooltips & Indicators</div>
<div class="md-10__page-sub">Tooltips (all 4 positions + rich), progress bars, circular indicators and badge components — pure CSS</div>
<!-- Tooltips -->
<div class="md-10__section">
<div class="md-10__section-title">Tooltips — Hover to See</div>
<div style="display:flex;flex-wrap:wrap;gap:24px;align-items:center;justify-content:center;padding:24px 0">
<div class="md-10__tooltip-wrap">
<button class="md-10__icon-btn">✏</button>
<div class="md-10__tooltip md-10__tooltip--top">Edit item</div>
</div>
<div class="md-10__tooltip-wrap">
<button class="md-10__icon-btn" style="background:#c62828">🗑</button>
<div class="md-10__tooltip md-10__tooltip--bottom">Delete permanently</div>
</div>
<div class="md-10__tooltip-wrap">
<button class="md-10__icon-btn" style="background:#7b1fa2">↗</button>
<div class="md-10__tooltip md-10__tooltip--right">Share with team</div>
</div>
<div class="md-10__tooltip-wrap">
<button class="md-10__icon-btn" style="background:#1565c0">⚙</button>
<div class="md-10__tooltip md-10__tooltip--left">Open settings</div>
</div>
<div class="md-10__tooltip-wrap">
<button class="md-10__text-btn">Format options</button>
<div class="md-10__tooltip md-10__tooltip--top">Bold, italic, underline, strikethrough</div>
</div>
<div class="md-10__tooltip-wrap">
<button class="md-10__badge-btn">Keyboard shortcuts</button>
<div class="md-10__tooltip md-10__tooltip--top" style="max-width:220px;white-space:normal">Press ⌘K to open the command palette, ⌘S to save, ⌘Z to undo.</div>
</div>
</div>
</div>
<!-- Rich Tooltip -->
<div class="md-10__section">
<div class="md-10__section-title">Rich Tooltip (Hover)</div>
<div style="display:flex;gap:24px;flex-wrap:wrap;align-items:center;justify-content:center;padding:24px 0">
<div class="md-10__tooltip-wrap">
<button class="md-10__icon-btn" style="background:#ff8f00">★</button>
<div class="md-10__tooltip md-10__tooltip--top md-10__tooltip--rich" style="bottom:calc(100% + 12px);min-width:240px">
<div class="md-10__tt-title">Add to favourites</div>
<div class="md-10__tt-body">Save this item to your favourites list to access it quickly from the sidebar.</div>
<div class="md-10__tt-actions">
<button class="md-10__tt-btn">Learn more</button>
<button class="md-10__tt-btn" style="margin-left:auto">Got it</button>
</div>
</div>
</div>
<div class="md-10__tooltip-wrap">
<button class="md-10__text-btn">Privacy settings ℹ</button>
<div class="md-10__tooltip md-10__tooltip--right md-10__tooltip--rich" style="left:calc(100% + 12px)">
<div class="md-10__tt-title">Privacy controls</div>
<div class="md-10__tt-body">Control who can see your profile and how your data is shared. Settings apply immediately.</div>
<div class="md-10__tt-actions">
<button class="md-10__tt-btn">Open settings</button>
</div>
</div>
</div>
</div>
</div>
<!-- Linear Progress -->
<div class="md-10__section">
<div class="md-10__section-title">Linear Progress Indicators</div>
<div class="md-10__progress-row">
<div>
<div class="md-10__progress-label"><span>Storage used</span><span>72%</span></div>
<div class="md-10__progress-track"><div class="md-10__progress-fill" style="width:72%"></div></div>
</div>
<div>
<div class="md-10__progress-label"><span>Upload complete</span><span>45%</span></div>
<div class="md-10__progress-track" style="height:8px;border-radius:4px"><div class="md-10__progress-fill" style="width:45%;background:#1565c0"></div></div>
</div>
<div>
<div class="md-10__progress-label"><span>Confidence score</span><span>94%</span></div>
<div class="md-10__progress-track" style="height:6px;background:#c8e6c9"><div class="md-10__progress-fill" style="width:94%;background:#2e7d32"></div></div>
</div>
<div>
<div class="md-10__progress-label"><span>Loading data…</span><span>Indeterminate</span></div>
<div class="md-10__progress-track" style="overflow:hidden;position:relative"><div class="md-10__progress-fill md-10__progress-fill--indeterminate" style="position:absolute"></div></div>
</div>
</div>
</div>
<!-- Circular Progress -->
<div class="md-10__section">
<div class="md-10__section-title">Circular Progress Indicators</div>
<div class="md-10__circular-row">
<div style="text-align:center">
<div class="md-10__circular">
<svg viewBox="0 0 64 64"><circle class="md-10__circular-track" cx="32" cy="32" r="28"/><circle class="md-10__circular-fill" cx="32" cy="32" r="28" stroke-dasharray="131" stroke-dashoffset="33" style="stroke:var(--primary)"/></svg>
<div class="md-10__circular-val">75%</div>
</div>
<div style="font-size:.75rem;color:var(--ink2);margin-top:6px">Progress</div>
</div>
<div style="text-align:center">
<div class="md-10__circular">
<svg viewBox="0 0 64 64"><circle class="md-10__circular-track" cx="32" cy="32" r="28"/><circle class="md-10__circular-fill" cx="32" cy="32" r="28" stroke-dasharray="131" stroke-dashoffset="72" style="stroke:#2e7d32"/></svg>
<div class="md-10__circular-val" style="color:#2e7d32">45%</div>
</div>
<div style="font-size:.75rem;color:var(--ink2);margin-top:6px">Budget</div>
</div>
<div style="text-align:center">
<div class="md-10__circular">
<svg viewBox="0 0 64 64"><circle class="md-10__circular-track" cx="32" cy="32" r="28"/><circle class="md-10__circular-fill" cx="32" cy="32" r="28" stroke-dasharray="131" stroke-dashoffset="13" style="stroke:#e65100"/></svg>
<div class="md-10__circular-val" style="color:#e65100">90%</div>
</div>
<div style="font-size:.75rem;color:var(--ink2);margin-top:6px">Capacity</div>
</div>
<div style="text-align:center">
<div class="md-10__circular md-10__circular--spin">
<svg viewBox="0 0 64 64"><circle class="md-10__circular-track" cx="32" cy="32" r="28"/><circle class="md-10__circular-fill" cx="32" cy="32" r="28" style="stroke:var(--primary)"/></svg>
</div>
<div style="font-size:.75rem;color:var(--ink2);margin-top:6px">Loading…</div>
</div>
<div style="text-align:center">
<div class="md-10__circular md-10__circular--spin">
<svg viewBox="0 0 64 64"><circle class="md-10__circular-track" cx="32" cy="32" r="28" style="stroke:#fce4ec"/><circle class="md-10__circular-fill" cx="32" cy="32" r="28" style="stroke:#e91e63"/></svg>
</div>
<div style="font-size:.75rem;color:var(--ink2);margin-top:6px">Syncing</div>
</div>
</div>
</div>
<!-- Badges -->
<div class="md-10__section">
<div class="md-10__section-title">Badges</div>
<div class="md-10__badge-demo-row">
<div class="md-10__badge-wrap">
<button class="md-10__icon-btn" style="background:#455a64">🔔</button>
<div class="md-10__badge">3</div>
</div>
<div class="md-10__badge-wrap">
<button class="md-10__icon-btn" style="background:#455a64">📧</button>
<div class="md-10__badge">99+</div>
</div>
<div class="md-10__badge-wrap">
<button class="md-10__icon-btn" style="background:#455a64">⚙</button>
<div class="md-10__badge md-10__badge--dot"></div>
</div>
<div class="md-10__badge-wrap">
<button class="md-10__text-btn">Inbox</button>
<div class="md-10__badge md-10__badge--large" style="top:-8px;right:-8px">New</div>
</div>
<div class="md-10__badge-wrap">
<button class="md-10__text-btn">Messages</button>
<div class="md-10__badge" style="top:-6px;right:-6px;background:#2e7d32">12</div>
</div>
</div>
<!-- Page indicator dots -->
<div style="margin-top:28px">
<div style="font-size:.78rem;color:var(--ink2);margin-bottom:12px">Page Indicator Dots</div>
<div class="md-10__dots-row">
<div class="md-10__dot"></div>
<div class="md-10__dot md-10__dot--active"></div>
<div class="md-10__dot"></div>
<div class="md-10__dot"></div>
<div class="md-10__dot"></div>
</div>
</div>
</div>
</div>
</div> <div class="md-10">
<div class="md-10__wrap">
<div class="md-10__page-title">Material Design Tooltips & Indicators</div>
<div class="md-10__page-sub">Tooltips (all 4 positions + rich), progress bars, circular indicators and badge components — pure CSS</div>
<!-- Tooltips -->
<div class="md-10__section">
<div class="md-10__section-title">Tooltips — Hover to See</div>
<div style="display:flex;flex-wrap:wrap;gap:24px;align-items:center;justify-content:center;padding:24px 0">
<div class="md-10__tooltip-wrap">
<button class="md-10__icon-btn">✏</button>
<div class="md-10__tooltip md-10__tooltip--top">Edit item</div>
</div>
<div class="md-10__tooltip-wrap">
<button class="md-10__icon-btn" style="background:#c62828">🗑</button>
<div class="md-10__tooltip md-10__tooltip--bottom">Delete permanently</div>
</div>
<div class="md-10__tooltip-wrap">
<button class="md-10__icon-btn" style="background:#7b1fa2">↗</button>
<div class="md-10__tooltip md-10__tooltip--right">Share with team</div>
</div>
<div class="md-10__tooltip-wrap">
<button class="md-10__icon-btn" style="background:#1565c0">⚙</button>
<div class="md-10__tooltip md-10__tooltip--left">Open settings</div>
</div>
<div class="md-10__tooltip-wrap">
<button class="md-10__text-btn">Format options</button>
<div class="md-10__tooltip md-10__tooltip--top">Bold, italic, underline, strikethrough</div>
</div>
<div class="md-10__tooltip-wrap">
<button class="md-10__badge-btn">Keyboard shortcuts</button>
<div class="md-10__tooltip md-10__tooltip--top" style="max-width:220px;white-space:normal">Press ⌘K to open the command palette, ⌘S to save, ⌘Z to undo.</div>
</div>
</div>
</div>
<!-- Rich Tooltip -->
<div class="md-10__section">
<div class="md-10__section-title">Rich Tooltip (Hover)</div>
<div style="display:flex;gap:24px;flex-wrap:wrap;align-items:center;justify-content:center;padding:24px 0">
<div class="md-10__tooltip-wrap">
<button class="md-10__icon-btn" style="background:#ff8f00">★</button>
<div class="md-10__tooltip md-10__tooltip--top md-10__tooltip--rich" style="bottom:calc(100% + 12px);min-width:240px">
<div class="md-10__tt-title">Add to favourites</div>
<div class="md-10__tt-body">Save this item to your favourites list to access it quickly from the sidebar.</div>
<div class="md-10__tt-actions">
<button class="md-10__tt-btn">Learn more</button>
<button class="md-10__tt-btn" style="margin-left:auto">Got it</button>
</div>
</div>
</div>
<div class="md-10__tooltip-wrap">
<button class="md-10__text-btn">Privacy settings ℹ</button>
<div class="md-10__tooltip md-10__tooltip--right md-10__tooltip--rich" style="left:calc(100% + 12px)">
<div class="md-10__tt-title">Privacy controls</div>
<div class="md-10__tt-body">Control who can see your profile and how your data is shared. Settings apply immediately.</div>
<div class="md-10__tt-actions">
<button class="md-10__tt-btn">Open settings</button>
</div>
</div>
</div>
</div>
</div>
<!-- Linear Progress -->
<div class="md-10__section">
<div class="md-10__section-title">Linear Progress Indicators</div>
<div class="md-10__progress-row">
<div>
<div class="md-10__progress-label"><span>Storage used</span><span>72%</span></div>
<div class="md-10__progress-track"><div class="md-10__progress-fill" style="width:72%"></div></div>
</div>
<div>
<div class="md-10__progress-label"><span>Upload complete</span><span>45%</span></div>
<div class="md-10__progress-track" style="height:8px;border-radius:4px"><div class="md-10__progress-fill" style="width:45%;background:#1565c0"></div></div>
</div>
<div>
<div class="md-10__progress-label"><span>Confidence score</span><span>94%</span></div>
<div class="md-10__progress-track" style="height:6px;background:#c8e6c9"><div class="md-10__progress-fill" style="width:94%;background:#2e7d32"></div></div>
</div>
<div>
<div class="md-10__progress-label"><span>Loading data…</span><span>Indeterminate</span></div>
<div class="md-10__progress-track" style="overflow:hidden;position:relative"><div class="md-10__progress-fill md-10__progress-fill--indeterminate" style="position:absolute"></div></div>
</div>
</div>
</div>
<!-- Circular Progress -->
<div class="md-10__section">
<div class="md-10__section-title">Circular Progress Indicators</div>
<div class="md-10__circular-row">
<div style="text-align:center">
<div class="md-10__circular">
<svg viewBox="0 0 64 64"><circle class="md-10__circular-track" cx="32" cy="32" r="28"/><circle class="md-10__circular-fill" cx="32" cy="32" r="28" stroke-dasharray="131" stroke-dashoffset="33" style="stroke:var(--primary)"/></svg>
<div class="md-10__circular-val">75%</div>
</div>
<div style="font-size:.75rem;color:var(--ink2);margin-top:6px">Progress</div>
</div>
<div style="text-align:center">
<div class="md-10__circular">
<svg viewBox="0 0 64 64"><circle class="md-10__circular-track" cx="32" cy="32" r="28"/><circle class="md-10__circular-fill" cx="32" cy="32" r="28" stroke-dasharray="131" stroke-dashoffset="72" style="stroke:#2e7d32"/></svg>
<div class="md-10__circular-val" style="color:#2e7d32">45%</div>
</div>
<div style="font-size:.75rem;color:var(--ink2);margin-top:6px">Budget</div>
</div>
<div style="text-align:center">
<div class="md-10__circular">
<svg viewBox="0 0 64 64"><circle class="md-10__circular-track" cx="32" cy="32" r="28"/><circle class="md-10__circular-fill" cx="32" cy="32" r="28" stroke-dasharray="131" stroke-dashoffset="13" style="stroke:#e65100"/></svg>
<div class="md-10__circular-val" style="color:#e65100">90%</div>
</div>
<div style="font-size:.75rem;color:var(--ink2);margin-top:6px">Capacity</div>
</div>
<div style="text-align:center">
<div class="md-10__circular md-10__circular--spin">
<svg viewBox="0 0 64 64"><circle class="md-10__circular-track" cx="32" cy="32" r="28"/><circle class="md-10__circular-fill" cx="32" cy="32" r="28" style="stroke:var(--primary)"/></svg>
</div>
<div style="font-size:.75rem;color:var(--ink2);margin-top:6px">Loading…</div>
</div>
<div style="text-align:center">
<div class="md-10__circular md-10__circular--spin">
<svg viewBox="0 0 64 64"><circle class="md-10__circular-track" cx="32" cy="32" r="28" style="stroke:#fce4ec"/><circle class="md-10__circular-fill" cx="32" cy="32" r="28" style="stroke:#e91e63"/></svg>
</div>
<div style="font-size:.75rem;color:var(--ink2);margin-top:6px">Syncing</div>
</div>
</div>
</div>
<!-- Badges -->
<div class="md-10__section">
<div class="md-10__section-title">Badges</div>
<div class="md-10__badge-demo-row">
<div class="md-10__badge-wrap">
<button class="md-10__icon-btn" style="background:#455a64">🔔</button>
<div class="md-10__badge">3</div>
</div>
<div class="md-10__badge-wrap">
<button class="md-10__icon-btn" style="background:#455a64">📧</button>
<div class="md-10__badge">99+</div>
</div>
<div class="md-10__badge-wrap">
<button class="md-10__icon-btn" style="background:#455a64">⚙</button>
<div class="md-10__badge md-10__badge--dot"></div>
</div>
<div class="md-10__badge-wrap">
<button class="md-10__text-btn">Inbox</button>
<div class="md-10__badge md-10__badge--large" style="top:-8px;right:-8px">New</div>
</div>
<div class="md-10__badge-wrap">
<button class="md-10__text-btn">Messages</button>
<div class="md-10__badge" style="top:-6px;right:-6px;background:#2e7d32">12</div>
</div>
</div>
<!-- Page indicator dots -->
<div style="margin-top:28px">
<div style="font-size:.78rem;color:var(--ink2);margin-bottom:12px">Page Indicator Dots</div>
<div class="md-10__dots-row">
<div class="md-10__dot"></div>
<div class="md-10__dot md-10__dot--active"></div>
<div class="md-10__dot"></div>
<div class="md-10__dot"></div>
<div class="md-10__dot"></div>
</div>
</div>
</div>
</div>
</div>.md-10,.md-10 *,.md-10 *::before,.md-10 *::after{box-sizing:border-box;margin:0;padding:0}
.md-10 ::selection{background:#00695c;color:#fff}
.md-10{
--primary:#00695c;
--primary-l:#4db6ac;
--secondary:#f57c00;
--surface:#fff;
--bg:#e0f2f1;
--ink:#212121;
--ink2:#546e7a;
--ink3:#90a4ae;
--divider:#b2dfdb;
font-family:'Roboto',sans-serif;
background:var(--bg);
min-height:100vh;
padding:48px 24px 80px;
color:var(--ink);
}
.md-10__wrap{max-width:900px;margin:0 auto}
.md-10__page-title{font-size:clamp(1.4rem,4vw,2rem);font-weight:700;margin-bottom:4px}
.md-10__page-sub{font-size:.9rem;color:var(--ink2);margin-bottom:40px}
.md-10__section{background:var(--surface);border-radius:12px;padding:32px;margin-bottom:24px;box-shadow:0 1px 4px rgba(0,0,0,.1)}
.md-10__section-title{font-size:.7rem;font-weight:700;letter-spacing:.18em;text-transform:uppercase;color:var(--ink2);margin-bottom:24px;display:flex;align-items:center;gap:10px}
.md-10__section-title::after{content:'';flex:1;height:1px;background:var(--divider)}
/* ── TOOLTIP ── */
.md-10__tooltip-wrap{position:relative;display:inline-flex}
.md-10__tooltip{
position:absolute;z-index:10;
background:#212121;color:#fff;
font-size:.75rem;font-weight:400;line-height:1.4;
padding:6px 10px;border-radius:4px;
white-space:nowrap;max-width:240px;white-space:normal;
pointer-events:none;
opacity:0;transition:opacity .15s .1s,transform .15s .1s;
}
/* Arrow */
.md-10__tooltip::before{content:'';position:absolute;width:0;height:0}
/* Top tooltip */
.md-10__tooltip--top{bottom:calc(100% + 8px);left:50%;transform:translateX(-50%) translateY(4px)}
.md-10__tooltip--top::before{top:100%;left:50%;transform:translateX(-50%);border:5px solid transparent;border-top-color:#212121}
.md-10__tooltip-wrap:hover .md-10__tooltip--top{opacity:1;transform:translateX(-50%) translateY(0)}
/* Bottom tooltip */
.md-10__tooltip--bottom{top:calc(100% + 8px);left:50%;transform:translateX(-50%) translateY(-4px)}
.md-10__tooltip--bottom::before{bottom:100%;left:50%;transform:translateX(-50%);border:5px solid transparent;border-bottom-color:#212121}
.md-10__tooltip-wrap:hover .md-10__tooltip--bottom{opacity:1;transform:translateX(-50%) translateY(0)}
/* Left tooltip */
.md-10__tooltip--left{right:calc(100% + 8px);top:50%;transform:translateY(-50%) translateX(4px)}
.md-10__tooltip--left::before{left:100%;top:50%;transform:translateY(-50%);border:5px solid transparent;border-left-color:#212121}
.md-10__tooltip-wrap:hover .md-10__tooltip--left{opacity:1;transform:translateY(-50%) translateX(0)}
/* Right tooltip */
.md-10__tooltip--right{left:calc(100% + 8px);top:50%;transform:translateY(-50%) translateX(-4px)}
.md-10__tooltip--right::before{right:100%;top:50%;transform:translateY(-50%);border:5px solid transparent;border-right-color:#212121}
.md-10__tooltip-wrap:hover .md-10__tooltip--right{opacity:1;transform:translateY(-50%) translateX(0)}
/* Rich tooltip */
.md-10__tooltip--rich{
background:var(--surface);color:var(--ink);
max-width:280px;padding:12px 16px;
box-shadow:0 2px 12px rgba(0,0,0,.2);
border-radius:8px;white-space:normal;
}
.md-10__tooltip--rich::before{display:none}
.md-10__tooltip--rich .md-10__tt-title{font-size:.875rem;font-weight:700;margin-bottom:4px;color:var(--ink)}
.md-10__tooltip--rich .md-10__tt-body{font-size:.8rem;line-height:1.5;color:var(--ink2)}
.md-10__tooltip--rich .md-10__tt-actions{display:flex;gap:8px;margin-top:8px;padding-top:8px;border-top:1px solid var(--divider)}
.md-10__tooltip--rich .md-10__tt-btn{background:none;border:none;color:var(--primary);font-family:'Roboto';font-size:.78rem;font-weight:500;cursor:pointer;text-transform:uppercase;letter-spacing:.05em;padding:0}
/* ── TRIGGER BUTTONS ── */
.md-10__icon-btn{
width:44px;height:44px;border-radius:50%;border:none;cursor:pointer;
background:var(--primary);color:#fff;font-size:1.2rem;
display:flex;align-items:center;justify-content:center;
box-shadow:0 2px 6px rgba(0,0,0,.2);transition:box-shadow .2s;
}
.md-10__icon-btn:hover{box-shadow:0 4px 12px rgba(0,0,0,.25)}
.md-10__text-btn{
height:36px;padding:0 16px;border:1px solid var(--divider);border-radius:4px;
background:var(--surface);font-family:'Roboto';font-size:.875rem;cursor:pointer;color:var(--ink);
}
.md-10__badge-btn{
background:var(--primary);color:#fff;border:none;border-radius:4px;padding:10px 16px;
font-family:'Roboto';font-size:.875rem;font-weight:500;cursor:pointer;
}
/* ── PROGRESS INDICATORS ── */
.md-10__progress-row{display:flex;flex-direction:column;gap:20px}
.md-10__progress-label{font-size:.8rem;color:var(--ink2);margin-bottom:6px;display:flex;justify-content:space-between}
.md-10__progress-track{height:4px;background:#b2dfdb;border-radius:2px;overflow:hidden;position:relative}
.md-10__progress-fill{height:100%;background:var(--primary);border-radius:2px;position:relative}
/* Indeterminate bar */
.md-10__progress-fill--indeterminate{
width:30%;
animation:md10-indeterminate 2s linear infinite;
}
@keyframes md10-indeterminate{
0%{left:-30%;width:30%}
60%{left:60%;width:50%}
100%{left:110%;width:30%}
}
/* Circular progress */
.md-10__circular-row{display:flex;gap:28px;flex-wrap:wrap;align-items:center;justify-content:center}
.md-10__circular{position:relative;width:64px;height:64px;flex-shrink:0}
.md-10__circular svg{transform:rotate(-90deg);width:64px;height:64px}
.md-10__circular-track{fill:none;stroke:#b2dfdb;stroke-width:4}
.md-10__circular-fill{fill:none;stroke:var(--primary);stroke-width:4;stroke-linecap:round;transition:stroke-dashoffset .5s ease}
.md-10__circular-val{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font-size:.8rem;font-weight:700;color:var(--primary)}
/* Indeterminate circle */
.md-10__circular--spin .md-10__circular-fill{
stroke-dasharray:160 200;
animation:md10-cspin 1.4s linear infinite;
}
@keyframes md10-cspin{0%{stroke-dashoffset:0;transform:none}100%{stroke-dashoffset:-320;transform:none}}
.md-10__circular--spin svg{animation:md10-svg-spin 1.4s linear infinite}
@keyframes md10-svg-spin{0%{transform:rotate(-90deg)}100%{transform:rotate(270deg)}}
/* ── BADGE ── */
.md-10__badge-wrap{position:relative;display:inline-flex}
.md-10__badge{
position:absolute;top:-4px;right:-4px;
background:var(--secondary);color:#fff;
font-size:.65rem;font-weight:700;
padding:2px 6px;border-radius:10px;
border:2px solid var(--surface);
line-height:1.4;white-space:nowrap;
min-width:20px;text-align:center;
}
.md-10__badge--dot{width:10px;height:10px;min-width:0;padding:0;top:-2px;right:-2px}
.md-10__badge--large{font-size:.75rem;padding:3px 8px;border-radius:12px}
.md-10__badge-demo-row{display:flex;gap:24px;flex-wrap:wrap;align-items:center}
/* ── PROGRESS OVERFLOW DOTS ── */
.md-10__dots-row{display:flex;gap:4px;align-items:center;justify-content:center;padding:8px 0}
.md-10__dot{width:8px;height:8px;border-radius:50%;background:var(--divider);transition:all .2s}
.md-10__dot--active{background:var(--primary);width:24px;border-radius:4px}
@media(prefers-reduced-motion:reduce){.md-10 *{animation:none!important;transition:none!important}} .md-10,.md-10 *,.md-10 *::before,.md-10 *::after{box-sizing:border-box;margin:0;padding:0}
.md-10 ::selection{background:#00695c;color:#fff}
.md-10{
--primary:#00695c;
--primary-l:#4db6ac;
--secondary:#f57c00;
--surface:#fff;
--bg:#e0f2f1;
--ink:#212121;
--ink2:#546e7a;
--ink3:#90a4ae;
--divider:#b2dfdb;
font-family:'Roboto',sans-serif;
background:var(--bg);
min-height:100vh;
padding:48px 24px 80px;
color:var(--ink);
}
.md-10__wrap{max-width:900px;margin:0 auto}
.md-10__page-title{font-size:clamp(1.4rem,4vw,2rem);font-weight:700;margin-bottom:4px}
.md-10__page-sub{font-size:.9rem;color:var(--ink2);margin-bottom:40px}
.md-10__section{background:var(--surface);border-radius:12px;padding:32px;margin-bottom:24px;box-shadow:0 1px 4px rgba(0,0,0,.1)}
.md-10__section-title{font-size:.7rem;font-weight:700;letter-spacing:.18em;text-transform:uppercase;color:var(--ink2);margin-bottom:24px;display:flex;align-items:center;gap:10px}
.md-10__section-title::after{content:'';flex:1;height:1px;background:var(--divider)}
/* ── TOOLTIP ── */
.md-10__tooltip-wrap{position:relative;display:inline-flex}
.md-10__tooltip{
position:absolute;z-index:10;
background:#212121;color:#fff;
font-size:.75rem;font-weight:400;line-height:1.4;
padding:6px 10px;border-radius:4px;
white-space:nowrap;max-width:240px;white-space:normal;
pointer-events:none;
opacity:0;transition:opacity .15s .1s,transform .15s .1s;
}
/* Arrow */
.md-10__tooltip::before{content:'';position:absolute;width:0;height:0}
/* Top tooltip */
.md-10__tooltip--top{bottom:calc(100% + 8px);left:50%;transform:translateX(-50%) translateY(4px)}
.md-10__tooltip--top::before{top:100%;left:50%;transform:translateX(-50%);border:5px solid transparent;border-top-color:#212121}
.md-10__tooltip-wrap:hover .md-10__tooltip--top{opacity:1;transform:translateX(-50%) translateY(0)}
/* Bottom tooltip */
.md-10__tooltip--bottom{top:calc(100% + 8px);left:50%;transform:translateX(-50%) translateY(-4px)}
.md-10__tooltip--bottom::before{bottom:100%;left:50%;transform:translateX(-50%);border:5px solid transparent;border-bottom-color:#212121}
.md-10__tooltip-wrap:hover .md-10__tooltip--bottom{opacity:1;transform:translateX(-50%) translateY(0)}
/* Left tooltip */
.md-10__tooltip--left{right:calc(100% + 8px);top:50%;transform:translateY(-50%) translateX(4px)}
.md-10__tooltip--left::before{left:100%;top:50%;transform:translateY(-50%);border:5px solid transparent;border-left-color:#212121}
.md-10__tooltip-wrap:hover .md-10__tooltip--left{opacity:1;transform:translateY(-50%) translateX(0)}
/* Right tooltip */
.md-10__tooltip--right{left:calc(100% + 8px);top:50%;transform:translateY(-50%) translateX(-4px)}
.md-10__tooltip--right::before{right:100%;top:50%;transform:translateY(-50%);border:5px solid transparent;border-right-color:#212121}
.md-10__tooltip-wrap:hover .md-10__tooltip--right{opacity:1;transform:translateY(-50%) translateX(0)}
/* Rich tooltip */
.md-10__tooltip--rich{
background:var(--surface);color:var(--ink);
max-width:280px;padding:12px 16px;
box-shadow:0 2px 12px rgba(0,0,0,.2);
border-radius:8px;white-space:normal;
}
.md-10__tooltip--rich::before{display:none}
.md-10__tooltip--rich .md-10__tt-title{font-size:.875rem;font-weight:700;margin-bottom:4px;color:var(--ink)}
.md-10__tooltip--rich .md-10__tt-body{font-size:.8rem;line-height:1.5;color:var(--ink2)}
.md-10__tooltip--rich .md-10__tt-actions{display:flex;gap:8px;margin-top:8px;padding-top:8px;border-top:1px solid var(--divider)}
.md-10__tooltip--rich .md-10__tt-btn{background:none;border:none;color:var(--primary);font-family:'Roboto';font-size:.78rem;font-weight:500;cursor:pointer;text-transform:uppercase;letter-spacing:.05em;padding:0}
/* ── TRIGGER BUTTONS ── */
.md-10__icon-btn{
width:44px;height:44px;border-radius:50%;border:none;cursor:pointer;
background:var(--primary);color:#fff;font-size:1.2rem;
display:flex;align-items:center;justify-content:center;
box-shadow:0 2px 6px rgba(0,0,0,.2);transition:box-shadow .2s;
}
.md-10__icon-btn:hover{box-shadow:0 4px 12px rgba(0,0,0,.25)}
.md-10__text-btn{
height:36px;padding:0 16px;border:1px solid var(--divider);border-radius:4px;
background:var(--surface);font-family:'Roboto';font-size:.875rem;cursor:pointer;color:var(--ink);
}
.md-10__badge-btn{
background:var(--primary);color:#fff;border:none;border-radius:4px;padding:10px 16px;
font-family:'Roboto';font-size:.875rem;font-weight:500;cursor:pointer;
}
/* ── PROGRESS INDICATORS ── */
.md-10__progress-row{display:flex;flex-direction:column;gap:20px}
.md-10__progress-label{font-size:.8rem;color:var(--ink2);margin-bottom:6px;display:flex;justify-content:space-between}
.md-10__progress-track{height:4px;background:#b2dfdb;border-radius:2px;overflow:hidden;position:relative}
.md-10__progress-fill{height:100%;background:var(--primary);border-radius:2px;position:relative}
/* Indeterminate bar */
.md-10__progress-fill--indeterminate{
width:30%;
animation:md10-indeterminate 2s linear infinite;
}
@keyframes md10-indeterminate{
0%{left:-30%;width:30%}
60%{left:60%;width:50%}
100%{left:110%;width:30%}
}
/* Circular progress */
.md-10__circular-row{display:flex;gap:28px;flex-wrap:wrap;align-items:center;justify-content:center}
.md-10__circular{position:relative;width:64px;height:64px;flex-shrink:0}
.md-10__circular svg{transform:rotate(-90deg);width:64px;height:64px}
.md-10__circular-track{fill:none;stroke:#b2dfdb;stroke-width:4}
.md-10__circular-fill{fill:none;stroke:var(--primary);stroke-width:4;stroke-linecap:round;transition:stroke-dashoffset .5s ease}
.md-10__circular-val{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font-size:.8rem;font-weight:700;color:var(--primary)}
/* Indeterminate circle */
.md-10__circular--spin .md-10__circular-fill{
stroke-dasharray:160 200;
animation:md10-cspin 1.4s linear infinite;
}
@keyframes md10-cspin{0%{stroke-dashoffset:0;transform:none}100%{stroke-dashoffset:-320;transform:none}}
.md-10__circular--spin svg{animation:md10-svg-spin 1.4s linear infinite}
@keyframes md10-svg-spin{0%{transform:rotate(-90deg)}100%{transform:rotate(270deg)}}
/* ── BADGE ── */
.md-10__badge-wrap{position:relative;display:inline-flex}
.md-10__badge{
position:absolute;top:-4px;right:-4px;
background:var(--secondary);color:#fff;
font-size:.65rem;font-weight:700;
padding:2px 6px;border-radius:10px;
border:2px solid var(--surface);
line-height:1.4;white-space:nowrap;
min-width:20px;text-align:center;
}
.md-10__badge--dot{width:10px;height:10px;min-width:0;padding:0;top:-2px;right:-2px}
.md-10__badge--large{font-size:.75rem;padding:3px 8px;border-radius:12px}
.md-10__badge-demo-row{display:flex;gap:24px;flex-wrap:wrap;align-items:center}
/* ── PROGRESS OVERFLOW DOTS ── */
.md-10__dots-row{display:flex;gap:4px;align-items:center;justify-content:center;padding:8px 0}
.md-10__dot{width:8px;height:8px;border-radius:50%;background:var(--divider);transition:all .2s}
.md-10__dot--active{background:var(--primary);width:24px;border-radius:4px}
@media(prefers-reduced-motion:reduce){.md-10 *{animation:none!important;transition:none!important}}How this works
Plain tooltips are ::after pseudo-elements on a .tooltip wrapper set to opacity: 0; pointer-events: none by default. On :hover and :focus-within, opacity transitions to 1 and a small translateY closes the gap, giving the Material enter animation. Direction variants (--top, --right, --bottom, --left) use absolute positioning offset from the anchor.
Linear progress tracks are height: 4px containers with a child fill element. Determinate fill uses an inline width percentage; indeterminate runs a @keyframes that slides the fill from -35% to 110% and a second keyframe that scales it from 0.35 to 0.65 — matching the exact Material indeterminate behaviour. Circular progress uses stroke-dasharray/stroke-dashoffset on an SVG circle.
Customize
- Change tooltip max-width by editing the
max-widthon.tooltip::afterfrom200pxto a wider value for rich content. - Delay tooltip appearance by adding
transition-delay: 400msto theopacitytransition so it only shows on sustained hover. - Make progress bars animated on page load by adding a
@keyframesthat growswidthfrom 0 to the target percentage over 600ms. - Change circular progress stroke colour by editing
strokeon the foreground circle element. - Adjust badge position by modifying the
top/rightoffset on the.badgeabsolute positioning.
Watch out for
- Tooltip pseudo-elements on
<button>work in Chrome and Firefox but Safari requires a non-replaced element as the anchor — wrap the button in a<span>if needed. - The indeterminate linear progress animation runs indefinitely — pause it with
animation-play-state: pausedwhen the loading state resolves. - SVG
stroke-dashoffsetfor circular progress requires knowing the circle circumference (2πr) — changing the SVGrattribute means recalculating the dasharray value.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 88+ | 14+ | 89+ | 88+ |
SVG stroke-dasharray animation is supported in all modern browsers; the indeterminate linear animation uses standard keyframes with no vendor prefixes needed.