21 CSS Tooltips15 / 21
Orion Constellation Chart
A starfield rendering of the Orion constellation with six labeled star hotspots — Rigel, Betelgeuse, Bellatrix, Alnilam, Saiph, Meissa. Each star pops a card with real astronomical data: Bayer designation, distance, magnitude, luminosity, and a five-star brightness gauge.
Published
The code
<div class="tp-15">
<div class="tp-15__chart">
<svg viewBox="0 0 400 400" xmlns="http://www.w3.org/2000/svg">
<circle cx="22" cy="18" r="0.6" fill="rgba(200,220,255,0.35)"/>
<circle cx="80" cy="10" r="0.7" fill="rgba(200,220,255,0.45)"/>
<circle cx="140" cy="22" r="0.4" fill="rgba(200,220,255,0.25)"/>
<circle cx="170" cy="38" r="0.6" fill="rgba(200,220,255,0.35)"/>
<circle cx="265" cy="18" r="0.7" fill="rgba(200,220,255,0.4)"/>
<circle cx="330" cy="22" r="0.4" fill="rgba(200,220,255,0.22)"/>
<circle cx="360" cy="55" r="0.6" fill="rgba(200,220,255,0.38)"/>
<circle cx="30" cy="80" r="0.4" fill="rgba(200,220,255,0.2)"/>
<circle cx="320" cy="75" r="0.6" fill="rgba(200,220,255,0.32)"/>
<circle cx="55" cy="145" r="0.5" fill="rgba(200,220,255,0.28)"/>
<circle cx="360" cy="150" r="0.5" fill="rgba(200,220,255,0.28)"/>
<circle cx="35" cy="260" r="0.5" fill="rgba(200,220,255,0.3)"/>
<circle cx="380" cy="260" r="0.5" fill="rgba(200,220,255,0.28)"/>
<circle cx="58" cy="360" r="0.4" fill="rgba(200,220,255,0.2)"/>
<circle cx="90" cy="380" r="0.5" fill="rgba(200,220,255,0.28)"/>
<circle cx="340" cy="355" r="0.5" fill="rgba(200,220,255,0.3)"/>
<circle cx="392" cy="360" r="0.6" fill="rgba(200,220,255,0.35)"/>
<line x1="200" y1="48" x2="148" y2="155" stroke="rgba(140,160,255,0.18)" stroke-width="0.8"/>
<line x1="200" y1="48" x2="262" y2="142" stroke="rgba(140,160,255,0.18)" stroke-width="0.8"/>
<line x1="148" y1="155" x2="168" y2="228" stroke="rgba(140,160,255,0.18)" stroke-width="0.8"/>
<line x1="262" y1="142" x2="232" y2="224" stroke="rgba(140,160,255,0.18)" stroke-width="0.8"/>
<line x1="168" y1="228" x2="200" y2="230" stroke="rgba(140,160,255,0.22)" stroke-width="0.8"/>
<line x1="200" y1="230" x2="232" y2="224" stroke="rgba(140,160,255,0.22)" stroke-width="0.8"/>
<line x1="168" y1="228" x2="136" y2="342" stroke="rgba(140,160,255,0.18)" stroke-width="0.8"/>
<line x1="232" y1="224" x2="278" y2="330" stroke="rgba(140,160,255,0.18)" stroke-width="0.8"/>
<circle cx="200" cy="48" r="6" fill="rgba(160,180,255,0.08)"/>
<circle cx="200" cy="48" r="2.5" fill="#d0daff" opacity="0.85"/>
<circle cx="148" cy="155" r="10" fill="rgba(255,120,60,0.06)"/>
<circle cx="148" cy="155" r="5" fill="#ffb890" opacity="0.9"/>
<circle cx="262" cy="142" r="6" fill="rgba(160,200,255,0.06)"/>
<circle cx="262" cy="142" r="3" fill="#c0d8ff" opacity="0.85"/>
<circle cx="168" cy="228" r="5" fill="rgba(160,180,255,0.06)"/>
<circle cx="168" cy="228" r="2.8" fill="#d0daff" opacity="0.85"/>
<circle cx="200" cy="230" r="5" fill="rgba(160,180,255,0.06)"/>
<circle cx="200" cy="230" r="3" fill="#d0daff" opacity="0.85"/>
<circle cx="232" cy="224" r="5" fill="rgba(160,200,255,0.06)"/>
<circle cx="232" cy="224" r="2.5" fill="#c8d8ff" opacity="0.85"/>
<circle cx="136" cy="342" r="5" fill="rgba(160,200,255,0.06)"/>
<circle cx="136" cy="342" r="2.5" fill="#c0d4ff" opacity="0.8"/>
<circle cx="278" cy="330" r="14" fill="rgba(160,200,255,0.05)"/>
<circle cx="278" cy="330" r="6" fill="#dce8ff" opacity="0.95"/>
</svg>
<div class="tp-15__spot" style="left:37%;top:38.75%"><div class="tp-15__hit"></div>
<div class="tp-15__card">
<div class="tp-15__top"><div class="tp-15__bayer">α Orionis</div><div class="tp-15__name">Betelgeuse</div><div class="tp-15__const">Orion · Upper left shoulder</div><span class="tp-15__pill">M1–2 Iaab · Red Supergiant</span></div>
<div class="tp-15__data">
<div class="tp-15__row"><span class="tp-15__key">Distance</span><span class="tp-15__val">700 ly</span></div>
<div class="tp-15__row"><span class="tp-15__key">App. mag</span><span class="tp-15__val">0.42 (variable)</span></div>
<div class="tp-15__row"><span class="tp-15__key">Luminosity</span><span class="tp-15__val">~126,000 L☉</span></div>
<div class="tp-15__row"><span class="tp-15__key">Radius</span><span class="tp-15__val">~700 R☉</span></div>
<div class="tp-15__mag"><span class="tp-15__mag-label">Brightness</span><span class="tp-15__mag-stars"><span class="tp-15__mag-star">★</span><span class="tp-15__mag-star">★</span><span class="tp-15__mag-star">★</span><span class="tp-15__mag-star">★</span><span class="tp-15__mag-star tp-15__mag-dim">★</span></span></div>
</div>
</div>
</div>
<div class="tp-15__spot" style="left:69.5%;top:82.5%"><div class="tp-15__hit"></div>
<div class="tp-15__card tp-15__card-left">
<div class="tp-15__top"><div class="tp-15__bayer">β Orionis</div><div class="tp-15__name">Rigel</div><div class="tp-15__const">Orion · Lower right</div><span class="tp-15__pill">B8 Ia · Blue Supergiant</span></div>
<div class="tp-15__data">
<div class="tp-15__row"><span class="tp-15__key">Distance</span><span class="tp-15__val">860 ly</span></div>
<div class="tp-15__row"><span class="tp-15__key">App. mag</span><span class="tp-15__val">0.13 (brightest)</span></div>
<div class="tp-15__row"><span class="tp-15__key">Luminosity</span><span class="tp-15__val">~120,000 L☉</span></div>
<div class="tp-15__row"><span class="tp-15__key">Temp</span><span class="tp-15__val">12,100 K</span></div>
<div class="tp-15__mag"><span class="tp-15__mag-label">Brightness</span><span class="tp-15__mag-stars"><span class="tp-15__mag-star">★</span><span class="tp-15__mag-star">★</span><span class="tp-15__mag-star">★</span><span class="tp-15__mag-star">★</span><span class="tp-15__mag-star">★</span></span></div>
</div>
</div>
</div>
<div class="tp-15__spot" style="left:65.5%;top:35.5%"><div class="tp-15__hit"></div>
<div class="tp-15__card tp-15__card-left">
<div class="tp-15__top"><div class="tp-15__bayer">γ Orionis</div><div class="tp-15__name">Bellatrix</div><div class="tp-15__const">Orion · Upper right shoulder</div><span class="tp-15__pill">B2 III · Blue Giant</span></div>
<div class="tp-15__data">
<div class="tp-15__row"><span class="tp-15__key">Distance</span><span class="tp-15__val">250 ly</span></div>
<div class="tp-15__row"><span class="tp-15__key">App. mag</span><span class="tp-15__val">1.64</span></div>
<div class="tp-15__row"><span class="tp-15__key">Luminosity</span><span class="tp-15__val">~6,400 L☉</span></div>
<div class="tp-15__row"><span class="tp-15__key">Temp</span><span class="tp-15__val">22,000 K</span></div>
<div class="tp-15__mag"><span class="tp-15__mag-label">Brightness</span><span class="tp-15__mag-stars"><span class="tp-15__mag-star">★</span><span class="tp-15__mag-star">★</span><span class="tp-15__mag-star">★</span><span class="tp-15__mag-star tp-15__mag-dim">★</span><span class="tp-15__mag-star tp-15__mag-dim">★</span></span></div>
</div>
</div>
</div>
<div class="tp-15__spot" style="left:50%;top:57.5%"><div class="tp-15__hit"></div>
<div class="tp-15__card">
<div class="tp-15__top"><div class="tp-15__bayer">ε Orionis</div><div class="tp-15__name">Alnilam</div><div class="tp-15__const">Orion · Belt, central star</div><span class="tp-15__pill">B0 Ia · Blue Supergiant</span></div>
<div class="tp-15__data">
<div class="tp-15__row"><span class="tp-15__key">Distance</span><span class="tp-15__val">2,000 ly</span></div>
<div class="tp-15__row"><span class="tp-15__key">App. mag</span><span class="tp-15__val">1.69</span></div>
<div class="tp-15__row"><span class="tp-15__key">Luminosity</span><span class="tp-15__val">~375,000 L☉</span></div>
<div class="tp-15__row"><span class="tp-15__key">Temp</span><span class="tp-15__val">27,500 K</span></div>
</div>
</div>
</div>
<div class="tp-15__spot" style="left:50%;top:12%"><div class="tp-15__hit"></div>
<div class="tp-15__card">
<div class="tp-15__top"><div class="tp-15__bayer">λ Orionis</div><div class="tp-15__name">Meissa</div><div class="tp-15__const">Orion · Head</div><span class="tp-15__pill">O8 III · Blue-White Giant</span></div>
<div class="tp-15__data">
<div class="tp-15__row"><span class="tp-15__key">Distance</span><span class="tp-15__val">1,100 ly</span></div>
<div class="tp-15__row"><span class="tp-15__key">App. mag</span><span class="tp-15__val">3.39</span></div>
<div class="tp-15__row"><span class="tp-15__key">Luminosity</span><span class="tp-15__val">~28,000 L☉</span></div>
<div class="tp-15__row"><span class="tp-15__key">Temp</span><span class="tp-15__val">35,000 K</span></div>
</div>
</div>
</div>
<div class="tp-15__spot" style="left:34%;top:85.5%"><div class="tp-15__hit"></div>
<div class="tp-15__card">
<div class="tp-15__top"><div class="tp-15__bayer">κ Orionis</div><div class="tp-15__name">Saiph</div><div class="tp-15__const">Orion · Lower left</div><span class="tp-15__pill">B0.5 Ia · Blue Supergiant</span></div>
<div class="tp-15__data">
<div class="tp-15__row"><span class="tp-15__key">Distance</span><span class="tp-15__val">720 ly</span></div>
<div class="tp-15__row"><span class="tp-15__key">App. mag</span><span class="tp-15__val">2.07</span></div>
<div class="tp-15__row"><span class="tp-15__key">Luminosity</span><span class="tp-15__val">~57,500 L☉</span></div>
<div class="tp-15__row"><span class="tp-15__key">Temp</span><span class="tp-15__val">26,500 K</span></div>
</div>
</div>
</div>
</div>
</div><div class="tp-15">
<div class="tp-15__chart">
<svg viewBox="0 0 400 400" xmlns="http://www.w3.org/2000/svg">
<circle cx="22" cy="18" r="0.6" fill="rgba(200,220,255,0.35)"/>
<circle cx="80" cy="10" r="0.7" fill="rgba(200,220,255,0.45)"/>
<circle cx="140" cy="22" r="0.4" fill="rgba(200,220,255,0.25)"/>
<circle cx="170" cy="38" r="0.6" fill="rgba(200,220,255,0.35)"/>
<circle cx="265" cy="18" r="0.7" fill="rgba(200,220,255,0.4)"/>
<circle cx="330" cy="22" r="0.4" fill="rgba(200,220,255,0.22)"/>
<circle cx="360" cy="55" r="0.6" fill="rgba(200,220,255,0.38)"/>
<circle cx="30" cy="80" r="0.4" fill="rgba(200,220,255,0.2)"/>
<circle cx="320" cy="75" r="0.6" fill="rgba(200,220,255,0.32)"/>
<circle cx="55" cy="145" r="0.5" fill="rgba(200,220,255,0.28)"/>
<circle cx="360" cy="150" r="0.5" fill="rgba(200,220,255,0.28)"/>
<circle cx="35" cy="260" r="0.5" fill="rgba(200,220,255,0.3)"/>
<circle cx="380" cy="260" r="0.5" fill="rgba(200,220,255,0.28)"/>
<circle cx="58" cy="360" r="0.4" fill="rgba(200,220,255,0.2)"/>
<circle cx="90" cy="380" r="0.5" fill="rgba(200,220,255,0.28)"/>
<circle cx="340" cy="355" r="0.5" fill="rgba(200,220,255,0.3)"/>
<circle cx="392" cy="360" r="0.6" fill="rgba(200,220,255,0.35)"/>
<line x1="200" y1="48" x2="148" y2="155" stroke="rgba(140,160,255,0.18)" stroke-width="0.8"/>
<line x1="200" y1="48" x2="262" y2="142" stroke="rgba(140,160,255,0.18)" stroke-width="0.8"/>
<line x1="148" y1="155" x2="168" y2="228" stroke="rgba(140,160,255,0.18)" stroke-width="0.8"/>
<line x1="262" y1="142" x2="232" y2="224" stroke="rgba(140,160,255,0.18)" stroke-width="0.8"/>
<line x1="168" y1="228" x2="200" y2="230" stroke="rgba(140,160,255,0.22)" stroke-width="0.8"/>
<line x1="200" y1="230" x2="232" y2="224" stroke="rgba(140,160,255,0.22)" stroke-width="0.8"/>
<line x1="168" y1="228" x2="136" y2="342" stroke="rgba(140,160,255,0.18)" stroke-width="0.8"/>
<line x1="232" y1="224" x2="278" y2="330" stroke="rgba(140,160,255,0.18)" stroke-width="0.8"/>
<circle cx="200" cy="48" r="6" fill="rgba(160,180,255,0.08)"/>
<circle cx="200" cy="48" r="2.5" fill="#d0daff" opacity="0.85"/>
<circle cx="148" cy="155" r="10" fill="rgba(255,120,60,0.06)"/>
<circle cx="148" cy="155" r="5" fill="#ffb890" opacity="0.9"/>
<circle cx="262" cy="142" r="6" fill="rgba(160,200,255,0.06)"/>
<circle cx="262" cy="142" r="3" fill="#c0d8ff" opacity="0.85"/>
<circle cx="168" cy="228" r="5" fill="rgba(160,180,255,0.06)"/>
<circle cx="168" cy="228" r="2.8" fill="#d0daff" opacity="0.85"/>
<circle cx="200" cy="230" r="5" fill="rgba(160,180,255,0.06)"/>
<circle cx="200" cy="230" r="3" fill="#d0daff" opacity="0.85"/>
<circle cx="232" cy="224" r="5" fill="rgba(160,200,255,0.06)"/>
<circle cx="232" cy="224" r="2.5" fill="#c8d8ff" opacity="0.85"/>
<circle cx="136" cy="342" r="5" fill="rgba(160,200,255,0.06)"/>
<circle cx="136" cy="342" r="2.5" fill="#c0d4ff" opacity="0.8"/>
<circle cx="278" cy="330" r="14" fill="rgba(160,200,255,0.05)"/>
<circle cx="278" cy="330" r="6" fill="#dce8ff" opacity="0.95"/>
</svg>
<div class="tp-15__spot" style="left:37%;top:38.75%"><div class="tp-15__hit"></div>
<div class="tp-15__card">
<div class="tp-15__top"><div class="tp-15__bayer">α Orionis</div><div class="tp-15__name">Betelgeuse</div><div class="tp-15__const">Orion · Upper left shoulder</div><span class="tp-15__pill">M1–2 Iaab · Red Supergiant</span></div>
<div class="tp-15__data">
<div class="tp-15__row"><span class="tp-15__key">Distance</span><span class="tp-15__val">700 ly</span></div>
<div class="tp-15__row"><span class="tp-15__key">App. mag</span><span class="tp-15__val">0.42 (variable)</span></div>
<div class="tp-15__row"><span class="tp-15__key">Luminosity</span><span class="tp-15__val">~126,000 L☉</span></div>
<div class="tp-15__row"><span class="tp-15__key">Radius</span><span class="tp-15__val">~700 R☉</span></div>
<div class="tp-15__mag"><span class="tp-15__mag-label">Brightness</span><span class="tp-15__mag-stars"><span class="tp-15__mag-star">★</span><span class="tp-15__mag-star">★</span><span class="tp-15__mag-star">★</span><span class="tp-15__mag-star">★</span><span class="tp-15__mag-star tp-15__mag-dim">★</span></span></div>
</div>
</div>
</div>
<div class="tp-15__spot" style="left:69.5%;top:82.5%"><div class="tp-15__hit"></div>
<div class="tp-15__card tp-15__card-left">
<div class="tp-15__top"><div class="tp-15__bayer">β Orionis</div><div class="tp-15__name">Rigel</div><div class="tp-15__const">Orion · Lower right</div><span class="tp-15__pill">B8 Ia · Blue Supergiant</span></div>
<div class="tp-15__data">
<div class="tp-15__row"><span class="tp-15__key">Distance</span><span class="tp-15__val">860 ly</span></div>
<div class="tp-15__row"><span class="tp-15__key">App. mag</span><span class="tp-15__val">0.13 (brightest)</span></div>
<div class="tp-15__row"><span class="tp-15__key">Luminosity</span><span class="tp-15__val">~120,000 L☉</span></div>
<div class="tp-15__row"><span class="tp-15__key">Temp</span><span class="tp-15__val">12,100 K</span></div>
<div class="tp-15__mag"><span class="tp-15__mag-label">Brightness</span><span class="tp-15__mag-stars"><span class="tp-15__mag-star">★</span><span class="tp-15__mag-star">★</span><span class="tp-15__mag-star">★</span><span class="tp-15__mag-star">★</span><span class="tp-15__mag-star">★</span></span></div>
</div>
</div>
</div>
<div class="tp-15__spot" style="left:65.5%;top:35.5%"><div class="tp-15__hit"></div>
<div class="tp-15__card tp-15__card-left">
<div class="tp-15__top"><div class="tp-15__bayer">γ Orionis</div><div class="tp-15__name">Bellatrix</div><div class="tp-15__const">Orion · Upper right shoulder</div><span class="tp-15__pill">B2 III · Blue Giant</span></div>
<div class="tp-15__data">
<div class="tp-15__row"><span class="tp-15__key">Distance</span><span class="tp-15__val">250 ly</span></div>
<div class="tp-15__row"><span class="tp-15__key">App. mag</span><span class="tp-15__val">1.64</span></div>
<div class="tp-15__row"><span class="tp-15__key">Luminosity</span><span class="tp-15__val">~6,400 L☉</span></div>
<div class="tp-15__row"><span class="tp-15__key">Temp</span><span class="tp-15__val">22,000 K</span></div>
<div class="tp-15__mag"><span class="tp-15__mag-label">Brightness</span><span class="tp-15__mag-stars"><span class="tp-15__mag-star">★</span><span class="tp-15__mag-star">★</span><span class="tp-15__mag-star">★</span><span class="tp-15__mag-star tp-15__mag-dim">★</span><span class="tp-15__mag-star tp-15__mag-dim">★</span></span></div>
</div>
</div>
</div>
<div class="tp-15__spot" style="left:50%;top:57.5%"><div class="tp-15__hit"></div>
<div class="tp-15__card">
<div class="tp-15__top"><div class="tp-15__bayer">ε Orionis</div><div class="tp-15__name">Alnilam</div><div class="tp-15__const">Orion · Belt, central star</div><span class="tp-15__pill">B0 Ia · Blue Supergiant</span></div>
<div class="tp-15__data">
<div class="tp-15__row"><span class="tp-15__key">Distance</span><span class="tp-15__val">2,000 ly</span></div>
<div class="tp-15__row"><span class="tp-15__key">App. mag</span><span class="tp-15__val">1.69</span></div>
<div class="tp-15__row"><span class="tp-15__key">Luminosity</span><span class="tp-15__val">~375,000 L☉</span></div>
<div class="tp-15__row"><span class="tp-15__key">Temp</span><span class="tp-15__val">27,500 K</span></div>
</div>
</div>
</div>
<div class="tp-15__spot" style="left:50%;top:12%"><div class="tp-15__hit"></div>
<div class="tp-15__card">
<div class="tp-15__top"><div class="tp-15__bayer">λ Orionis</div><div class="tp-15__name">Meissa</div><div class="tp-15__const">Orion · Head</div><span class="tp-15__pill">O8 III · Blue-White Giant</span></div>
<div class="tp-15__data">
<div class="tp-15__row"><span class="tp-15__key">Distance</span><span class="tp-15__val">1,100 ly</span></div>
<div class="tp-15__row"><span class="tp-15__key">App. mag</span><span class="tp-15__val">3.39</span></div>
<div class="tp-15__row"><span class="tp-15__key">Luminosity</span><span class="tp-15__val">~28,000 L☉</span></div>
<div class="tp-15__row"><span class="tp-15__key">Temp</span><span class="tp-15__val">35,000 K</span></div>
</div>
</div>
</div>
<div class="tp-15__spot" style="left:34%;top:85.5%"><div class="tp-15__hit"></div>
<div class="tp-15__card">
<div class="tp-15__top"><div class="tp-15__bayer">κ Orionis</div><div class="tp-15__name">Saiph</div><div class="tp-15__const">Orion · Lower left</div><span class="tp-15__pill">B0.5 Ia · Blue Supergiant</span></div>
<div class="tp-15__data">
<div class="tp-15__row"><span class="tp-15__key">Distance</span><span class="tp-15__val">720 ly</span></div>
<div class="tp-15__row"><span class="tp-15__key">App. mag</span><span class="tp-15__val">2.07</span></div>
<div class="tp-15__row"><span class="tp-15__key">Luminosity</span><span class="tp-15__val">~57,500 L☉</span></div>
<div class="tp-15__row"><span class="tp-15__key">Temp</span><span class="tp-15__val">26,500 K</span></div>
</div>
</div>
</div>
</div>
</div>.tp-15 {
width: 100%;
min-height: 100vh;
background: #04060e;
/* Side room — star cards pop to the right (Betelgeuse, Alnilam,
Meissa, Saiph) or left (Rigel, Bellatrix). 260px each side. */
padding: 40px 280px;
font-family: 'JetBrains Mono', ui-monospace, monospace;
display: flex;
align-items: center;
justify-content: center;
}
.tp-15__chart {
position: relative;
width: 400px;
height: 400px;
flex-shrink: 0;
}
.tp-15__chart svg {
width: 100%;
height: 100%;
display: block;
}
.tp-15__spot {
position: absolute;
transform: translate(-50%, -50%);
cursor: help;
z-index: 10;
}
.tp-15__hit {
width: 22px;
height: 22px;
border-radius: 50%;
position: relative;
}
.tp-15__hit::after {
content: '';
position: absolute;
inset: 0;
border-radius: 50%;
background: rgba(180, 200, 255, 0);
transition: background .2s;
}
.tp-15__spot:hover .tp-15__hit::after {
background: rgba(180, 200, 255, 0.08);
box-shadow: 0 0 18px 6px rgba(160, 180, 255, 0.12);
}
.tp-15__card {
position: absolute;
left: calc(100% + 14px);
top: 50%;
transform: translateY(-50%) translateX(6px);
z-index: 200;
width: 230px;
background: rgba(8, 12, 28, 0.96);
border: 1px solid rgba(100, 120, 200, 0.2);
border-radius: 8px;
opacity: 0;
visibility: hidden;
pointer-events: none;
transition: opacity .2s, transform .2s cubic-bezier(0.22, 1, 0.36, 1), visibility 0s linear .2s;
box-shadow: 0 12px 38px rgba(0, 0, 0, 0.9), 0 0 0 1px rgba(100, 120, 200, 0.06);
overflow: hidden;
text-align: left;
}
.tp-15__spot:hover .tp-15__card {
opacity: 1;
visibility: visible;
transform: translateY(-50%) translateX(0);
transition-delay: 0s;
}
.tp-15__card-left {
left: auto;
right: calc(100% + 14px);
transform: translateY(-50%) translateX(-6px);
}
.tp-15__spot:hover .tp-15__card-left {
transform: translateY(-50%) translateX(0);
}
.tp-15__top {
padding: 12px 13px 10px;
border-bottom: 1px solid rgba(100, 120, 200, 0.1);
}
.tp-15__bayer {
font-size: 9px;
color: rgba(140, 160, 255, 0.4);
letter-spacing: 0.1em;
margin-bottom: 3px;
}
.tp-15__name {
font-size: 15px;
font-weight: 500;
color: rgba(220, 230, 255, 0.92);
margin-bottom: 1px;
}
.tp-15__const {
font-size: 9.5px;
color: rgba(100, 120, 180, 0.6);
}
.tp-15__pill {
display: inline-block;
font-size: 8.5px;
padding: 2px 7px;
border-radius: 3px;
margin-top: 6px;
letter-spacing: 0.06em;
border: 1px solid rgba(100, 120, 200, 0.2);
color: rgba(140, 160, 220, 0.7);
}
.tp-15__data {
padding: 10px 13px;
}
.tp-15__row {
display: flex;
justify-content: space-between;
margin-bottom: 5px;
}
.tp-15__key {
font-size: 8.5px;
color: rgba(60, 80, 140, 0.7);
letter-spacing: 0.08em;
}
.tp-15__val {
font-size: 9.5px;
color: rgba(160, 180, 240, 0.75);
}
.tp-15__mag {
display: flex;
align-items: center;
gap: 8px;
margin-top: 8px;
padding-top: 8px;
border-top: 1px solid rgba(100, 120, 200, 0.06);
}
.tp-15__mag-label {
font-size: 7.5px;
color: rgba(60, 80, 140, 0.5);
letter-spacing: 0.08em;
}
.tp-15__mag-stars {
display: flex;
gap: 2px;
}
.tp-15__mag-star {
font-size: 9.5px;
color: rgba(255, 220, 80, 0.7);
}
.tp-15__mag-dim {
color: rgba(60, 80, 140, 0.3);
}.tp-15 {
width: 100%;
min-height: 100vh;
background: #04060e;
/* Side room — star cards pop to the right (Betelgeuse, Alnilam,
Meissa, Saiph) or left (Rigel, Bellatrix). 260px each side. */
padding: 40px 280px;
font-family: 'JetBrains Mono', ui-monospace, monospace;
display: flex;
align-items: center;
justify-content: center;
}
.tp-15__chart {
position: relative;
width: 400px;
height: 400px;
flex-shrink: 0;
}
.tp-15__chart svg {
width: 100%;
height: 100%;
display: block;
}
.tp-15__spot {
position: absolute;
transform: translate(-50%, -50%);
cursor: help;
z-index: 10;
}
.tp-15__hit {
width: 22px;
height: 22px;
border-radius: 50%;
position: relative;
}
.tp-15__hit::after {
content: '';
position: absolute;
inset: 0;
border-radius: 50%;
background: rgba(180, 200, 255, 0);
transition: background .2s;
}
.tp-15__spot:hover .tp-15__hit::after {
background: rgba(180, 200, 255, 0.08);
box-shadow: 0 0 18px 6px rgba(160, 180, 255, 0.12);
}
.tp-15__card {
position: absolute;
left: calc(100% + 14px);
top: 50%;
transform: translateY(-50%) translateX(6px);
z-index: 200;
width: 230px;
background: rgba(8, 12, 28, 0.96);
border: 1px solid rgba(100, 120, 200, 0.2);
border-radius: 8px;
opacity: 0;
visibility: hidden;
pointer-events: none;
transition: opacity .2s, transform .2s cubic-bezier(0.22, 1, 0.36, 1), visibility 0s linear .2s;
box-shadow: 0 12px 38px rgba(0, 0, 0, 0.9), 0 0 0 1px rgba(100, 120, 200, 0.06);
overflow: hidden;
text-align: left;
}
.tp-15__spot:hover .tp-15__card {
opacity: 1;
visibility: visible;
transform: translateY(-50%) translateX(0);
transition-delay: 0s;
}
.tp-15__card-left {
left: auto;
right: calc(100% + 14px);
transform: translateY(-50%) translateX(-6px);
}
.tp-15__spot:hover .tp-15__card-left {
transform: translateY(-50%) translateX(0);
}
.tp-15__top {
padding: 12px 13px 10px;
border-bottom: 1px solid rgba(100, 120, 200, 0.1);
}
.tp-15__bayer {
font-size: 9px;
color: rgba(140, 160, 255, 0.4);
letter-spacing: 0.1em;
margin-bottom: 3px;
}
.tp-15__name {
font-size: 15px;
font-weight: 500;
color: rgba(220, 230, 255, 0.92);
margin-bottom: 1px;
}
.tp-15__const {
font-size: 9.5px;
color: rgba(100, 120, 180, 0.6);
}
.tp-15__pill {
display: inline-block;
font-size: 8.5px;
padding: 2px 7px;
border-radius: 3px;
margin-top: 6px;
letter-spacing: 0.06em;
border: 1px solid rgba(100, 120, 200, 0.2);
color: rgba(140, 160, 220, 0.7);
}
.tp-15__data {
padding: 10px 13px;
}
.tp-15__row {
display: flex;
justify-content: space-between;
margin-bottom: 5px;
}
.tp-15__key {
font-size: 8.5px;
color: rgba(60, 80, 140, 0.7);
letter-spacing: 0.08em;
}
.tp-15__val {
font-size: 9.5px;
color: rgba(160, 180, 240, 0.75);
}
.tp-15__mag {
display: flex;
align-items: center;
gap: 8px;
margin-top: 8px;
padding-top: 8px;
border-top: 1px solid rgba(100, 120, 200, 0.06);
}
.tp-15__mag-label {
font-size: 7.5px;
color: rgba(60, 80, 140, 0.5);
letter-spacing: 0.08em;
}
.tp-15__mag-stars {
display: flex;
gap: 2px;
}
.tp-15__mag-star {
font-size: 9.5px;
color: rgba(255, 220, 80, 0.7);
}
.tp-15__mag-dim {
color: rgba(60, 80, 140, 0.3);
}Here's a working CSS Tooltip from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Orion Constellation Chart
Source: https://codefronts.com/snippets/css-tooltips/orion-constellation-chart/
A starfield rendering of the Orion constellation with six labeled star hotspots — Rigel, Betelgeuse, Bellatrix, Alnilam, Saiph, Meissa. Each star pops a card with real astronomical data: Bayer designation, distance, magnitude, luminosity, and a five-star brightness gauge.
## HTML
```html
<div class="tp-15">
<div class="tp-15__chart">
<svg viewBox="0 0 400 400" xmlns="http://www.w3.org/2000/svg">
<circle cx="22" cy="18" r="0.6" fill="rgba(200,220,255,0.35)"/>
<circle cx="80" cy="10" r="0.7" fill="rgba(200,220,255,0.45)"/>
<circle cx="140" cy="22" r="0.4" fill="rgba(200,220,255,0.25)"/>
<circle cx="170" cy="38" r="0.6" fill="rgba(200,220,255,0.35)"/>
<circle cx="265" cy="18" r="0.7" fill="rgba(200,220,255,0.4)"/>
<circle cx="330" cy="22" r="0.4" fill="rgba(200,220,255,0.22)"/>
<circle cx="360" cy="55" r="0.6" fill="rgba(200,220,255,0.38)"/>
<circle cx="30" cy="80" r="0.4" fill="rgba(200,220,255,0.2)"/>
<circle cx="320" cy="75" r="0.6" fill="rgba(200,220,255,0.32)"/>
<circle cx="55" cy="145" r="0.5" fill="rgba(200,220,255,0.28)"/>
<circle cx="360" cy="150" r="0.5" fill="rgba(200,220,255,0.28)"/>
<circle cx="35" cy="260" r="0.5" fill="rgba(200,220,255,0.3)"/>
<circle cx="380" cy="260" r="0.5" fill="rgba(200,220,255,0.28)"/>
<circle cx="58" cy="360" r="0.4" fill="rgba(200,220,255,0.2)"/>
<circle cx="90" cy="380" r="0.5" fill="rgba(200,220,255,0.28)"/>
<circle cx="340" cy="355" r="0.5" fill="rgba(200,220,255,0.3)"/>
<circle cx="392" cy="360" r="0.6" fill="rgba(200,220,255,0.35)"/>
<line x1="200" y1="48" x2="148" y2="155" stroke="rgba(140,160,255,0.18)" stroke-width="0.8"/>
<line x1="200" y1="48" x2="262" y2="142" stroke="rgba(140,160,255,0.18)" stroke-width="0.8"/>
<line x1="148" y1="155" x2="168" y2="228" stroke="rgba(140,160,255,0.18)" stroke-width="0.8"/>
<line x1="262" y1="142" x2="232" y2="224" stroke="rgba(140,160,255,0.18)" stroke-width="0.8"/>
<line x1="168" y1="228" x2="200" y2="230" stroke="rgba(140,160,255,0.22)" stroke-width="0.8"/>
<line x1="200" y1="230" x2="232" y2="224" stroke="rgba(140,160,255,0.22)" stroke-width="0.8"/>
<line x1="168" y1="228" x2="136" y2="342" stroke="rgba(140,160,255,0.18)" stroke-width="0.8"/>
<line x1="232" y1="224" x2="278" y2="330" stroke="rgba(140,160,255,0.18)" stroke-width="0.8"/>
<circle cx="200" cy="48" r="6" fill="rgba(160,180,255,0.08)"/>
<circle cx="200" cy="48" r="2.5" fill="#d0daff" opacity="0.85"/>
<circle cx="148" cy="155" r="10" fill="rgba(255,120,60,0.06)"/>
<circle cx="148" cy="155" r="5" fill="#ffb890" opacity="0.9"/>
<circle cx="262" cy="142" r="6" fill="rgba(160,200,255,0.06)"/>
<circle cx="262" cy="142" r="3" fill="#c0d8ff" opacity="0.85"/>
<circle cx="168" cy="228" r="5" fill="rgba(160,180,255,0.06)"/>
<circle cx="168" cy="228" r="2.8" fill="#d0daff" opacity="0.85"/>
<circle cx="200" cy="230" r="5" fill="rgba(160,180,255,0.06)"/>
<circle cx="200" cy="230" r="3" fill="#d0daff" opacity="0.85"/>
<circle cx="232" cy="224" r="5" fill="rgba(160,200,255,0.06)"/>
<circle cx="232" cy="224" r="2.5" fill="#c8d8ff" opacity="0.85"/>
<circle cx="136" cy="342" r="5" fill="rgba(160,200,255,0.06)"/>
<circle cx="136" cy="342" r="2.5" fill="#c0d4ff" opacity="0.8"/>
<circle cx="278" cy="330" r="14" fill="rgba(160,200,255,0.05)"/>
<circle cx="278" cy="330" r="6" fill="#dce8ff" opacity="0.95"/>
</svg>
<div class="tp-15__spot" style="left:37%;top:38.75%"><div class="tp-15__hit"></div>
<div class="tp-15__card">
<div class="tp-15__top"><div class="tp-15__bayer">α Orionis</div><div class="tp-15__name">Betelgeuse</div><div class="tp-15__const">Orion · Upper left shoulder</div><span class="tp-15__pill">M1–2 Iaab · Red Supergiant</span></div>
<div class="tp-15__data">
<div class="tp-15__row"><span class="tp-15__key">Distance</span><span class="tp-15__val">700 ly</span></div>
<div class="tp-15__row"><span class="tp-15__key">App. mag</span><span class="tp-15__val">0.42 (variable)</span></div>
<div class="tp-15__row"><span class="tp-15__key">Luminosity</span><span class="tp-15__val">~126,000 L☉</span></div>
<div class="tp-15__row"><span class="tp-15__key">Radius</span><span class="tp-15__val">~700 R☉</span></div>
<div class="tp-15__mag"><span class="tp-15__mag-label">Brightness</span><span class="tp-15__mag-stars"><span class="tp-15__mag-star">★</span><span class="tp-15__mag-star">★</span><span class="tp-15__mag-star">★</span><span class="tp-15__mag-star">★</span><span class="tp-15__mag-star tp-15__mag-dim">★</span></span></div>
</div>
</div>
</div>
<div class="tp-15__spot" style="left:69.5%;top:82.5%"><div class="tp-15__hit"></div>
<div class="tp-15__card tp-15__card-left">
<div class="tp-15__top"><div class="tp-15__bayer">β Orionis</div><div class="tp-15__name">Rigel</div><div class="tp-15__const">Orion · Lower right</div><span class="tp-15__pill">B8 Ia · Blue Supergiant</span></div>
<div class="tp-15__data">
<div class="tp-15__row"><span class="tp-15__key">Distance</span><span class="tp-15__val">860 ly</span></div>
<div class="tp-15__row"><span class="tp-15__key">App. mag</span><span class="tp-15__val">0.13 (brightest)</span></div>
<div class="tp-15__row"><span class="tp-15__key">Luminosity</span><span class="tp-15__val">~120,000 L☉</span></div>
<div class="tp-15__row"><span class="tp-15__key">Temp</span><span class="tp-15__val">12,100 K</span></div>
<div class="tp-15__mag"><span class="tp-15__mag-label">Brightness</span><span class="tp-15__mag-stars"><span class="tp-15__mag-star">★</span><span class="tp-15__mag-star">★</span><span class="tp-15__mag-star">★</span><span class="tp-15__mag-star">★</span><span class="tp-15__mag-star">★</span></span></div>
</div>
</div>
</div>
<div class="tp-15__spot" style="left:65.5%;top:35.5%"><div class="tp-15__hit"></div>
<div class="tp-15__card tp-15__card-left">
<div class="tp-15__top"><div class="tp-15__bayer">γ Orionis</div><div class="tp-15__name">Bellatrix</div><div class="tp-15__const">Orion · Upper right shoulder</div><span class="tp-15__pill">B2 III · Blue Giant</span></div>
<div class="tp-15__data">
<div class="tp-15__row"><span class="tp-15__key">Distance</span><span class="tp-15__val">250 ly</span></div>
<div class="tp-15__row"><span class="tp-15__key">App. mag</span><span class="tp-15__val">1.64</span></div>
<div class="tp-15__row"><span class="tp-15__key">Luminosity</span><span class="tp-15__val">~6,400 L☉</span></div>
<div class="tp-15__row"><span class="tp-15__key">Temp</span><span class="tp-15__val">22,000 K</span></div>
<div class="tp-15__mag"><span class="tp-15__mag-label">Brightness</span><span class="tp-15__mag-stars"><span class="tp-15__mag-star">★</span><span class="tp-15__mag-star">★</span><span class="tp-15__mag-star">★</span><span class="tp-15__mag-star tp-15__mag-dim">★</span><span class="tp-15__mag-star tp-15__mag-dim">★</span></span></div>
</div>
</div>
</div>
<div class="tp-15__spot" style="left:50%;top:57.5%"><div class="tp-15__hit"></div>
<div class="tp-15__card">
<div class="tp-15__top"><div class="tp-15__bayer">ε Orionis</div><div class="tp-15__name">Alnilam</div><div class="tp-15__const">Orion · Belt, central star</div><span class="tp-15__pill">B0 Ia · Blue Supergiant</span></div>
<div class="tp-15__data">
<div class="tp-15__row"><span class="tp-15__key">Distance</span><span class="tp-15__val">2,000 ly</span></div>
<div class="tp-15__row"><span class="tp-15__key">App. mag</span><span class="tp-15__val">1.69</span></div>
<div class="tp-15__row"><span class="tp-15__key">Luminosity</span><span class="tp-15__val">~375,000 L☉</span></div>
<div class="tp-15__row"><span class="tp-15__key">Temp</span><span class="tp-15__val">27,500 K</span></div>
</div>
</div>
</div>
<div class="tp-15__spot" style="left:50%;top:12%"><div class="tp-15__hit"></div>
<div class="tp-15__card">
<div class="tp-15__top"><div class="tp-15__bayer">λ Orionis</div><div class="tp-15__name">Meissa</div><div class="tp-15__const">Orion · Head</div><span class="tp-15__pill">O8 III · Blue-White Giant</span></div>
<div class="tp-15__data">
<div class="tp-15__row"><span class="tp-15__key">Distance</span><span class="tp-15__val">1,100 ly</span></div>
<div class="tp-15__row"><span class="tp-15__key">App. mag</span><span class="tp-15__val">3.39</span></div>
<div class="tp-15__row"><span class="tp-15__key">Luminosity</span><span class="tp-15__val">~28,000 L☉</span></div>
<div class="tp-15__row"><span class="tp-15__key">Temp</span><span class="tp-15__val">35,000 K</span></div>
</div>
</div>
</div>
<div class="tp-15__spot" style="left:34%;top:85.5%"><div class="tp-15__hit"></div>
<div class="tp-15__card">
<div class="tp-15__top"><div class="tp-15__bayer">κ Orionis</div><div class="tp-15__name">Saiph</div><div class="tp-15__const">Orion · Lower left</div><span class="tp-15__pill">B0.5 Ia · Blue Supergiant</span></div>
<div class="tp-15__data">
<div class="tp-15__row"><span class="tp-15__key">Distance</span><span class="tp-15__val">720 ly</span></div>
<div class="tp-15__row"><span class="tp-15__key">App. mag</span><span class="tp-15__val">2.07</span></div>
<div class="tp-15__row"><span class="tp-15__key">Luminosity</span><span class="tp-15__val">~57,500 L☉</span></div>
<div class="tp-15__row"><span class="tp-15__key">Temp</span><span class="tp-15__val">26,500 K</span></div>
</div>
</div>
</div>
</div>
</div>
```
## CSS
```css
.tp-15 {
width: 100%;
min-height: 100vh;
background: #04060e;
/* Side room — star cards pop to the right (Betelgeuse, Alnilam,
Meissa, Saiph) or left (Rigel, Bellatrix). 260px each side. */
padding: 40px 280px;
font-family: 'JetBrains Mono', ui-monospace, monospace;
display: flex;
align-items: center;
justify-content: center;
}
.tp-15__chart {
position: relative;
width: 400px;
height: 400px;
flex-shrink: 0;
}
.tp-15__chart svg {
width: 100%;
height: 100%;
display: block;
}
.tp-15__spot {
position: absolute;
transform: translate(-50%, -50%);
cursor: help;
z-index: 10;
}
.tp-15__hit {
width: 22px;
height: 22px;
border-radius: 50%;
position: relative;
}
.tp-15__hit::after {
content: '';
position: absolute;
inset: 0;
border-radius: 50%;
background: rgba(180, 200, 255, 0);
transition: background .2s;
}
.tp-15__spot:hover .tp-15__hit::after {
background: rgba(180, 200, 255, 0.08);
box-shadow: 0 0 18px 6px rgba(160, 180, 255, 0.12);
}
.tp-15__card {
position: absolute;
left: calc(100% + 14px);
top: 50%;
transform: translateY(-50%) translateX(6px);
z-index: 200;
width: 230px;
background: rgba(8, 12, 28, 0.96);
border: 1px solid rgba(100, 120, 200, 0.2);
border-radius: 8px;
opacity: 0;
visibility: hidden;
pointer-events: none;
transition: opacity .2s, transform .2s cubic-bezier(0.22, 1, 0.36, 1), visibility 0s linear .2s;
box-shadow: 0 12px 38px rgba(0, 0, 0, 0.9), 0 0 0 1px rgba(100, 120, 200, 0.06);
overflow: hidden;
text-align: left;
}
.tp-15__spot:hover .tp-15__card {
opacity: 1;
visibility: visible;
transform: translateY(-50%) translateX(0);
transition-delay: 0s;
}
.tp-15__card-left {
left: auto;
right: calc(100% + 14px);
transform: translateY(-50%) translateX(-6px);
}
.tp-15__spot:hover .tp-15__card-left {
transform: translateY(-50%) translateX(0);
}
.tp-15__top {
padding: 12px 13px 10px;
border-bottom: 1px solid rgba(100, 120, 200, 0.1);
}
.tp-15__bayer {
font-size: 9px;
color: rgba(140, 160, 255, 0.4);
letter-spacing: 0.1em;
margin-bottom: 3px;
}
.tp-15__name {
font-size: 15px;
font-weight: 500;
color: rgba(220, 230, 255, 0.92);
margin-bottom: 1px;
}
.tp-15__const {
font-size: 9.5px;
color: rgba(100, 120, 180, 0.6);
}
.tp-15__pill {
display: inline-block;
font-size: 8.5px;
padding: 2px 7px;
border-radius: 3px;
margin-top: 6px;
letter-spacing: 0.06em;
border: 1px solid rgba(100, 120, 200, 0.2);
color: rgba(140, 160, 220, 0.7);
}
.tp-15__data {
padding: 10px 13px;
}
.tp-15__row {
display: flex;
justify-content: space-between;
margin-bottom: 5px;
}
.tp-15__key {
font-size: 8.5px;
color: rgba(60, 80, 140, 0.7);
letter-spacing: 0.08em;
}
.tp-15__val {
font-size: 9.5px;
color: rgba(160, 180, 240, 0.75);
}
.tp-15__mag {
display: flex;
align-items: center;
gap: 8px;
margin-top: 8px;
padding-top: 8px;
border-top: 1px solid rgba(100, 120, 200, 0.06);
}
.tp-15__mag-label {
font-size: 7.5px;
color: rgba(60, 80, 140, 0.5);
letter-spacing: 0.08em;
}
.tp-15__mag-stars {
display: flex;
gap: 2px;
}
.tp-15__mag-star {
font-size: 9.5px;
color: rgba(255, 220, 80, 0.7);
}
.tp-15__mag-dim {
color: rgba(60, 80, 140, 0.3);
}
```Here's a working CSS Tooltip from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Orion Constellation Chart
Source: https://codefronts.com/snippets/css-tooltips/orion-constellation-chart/
A starfield rendering of the Orion constellation with six labeled star hotspots — Rigel, Betelgeuse, Bellatrix, Alnilam, Saiph, Meissa. Each star pops a card with real astronomical data: Bayer designation, distance, magnitude, luminosity, and a five-star brightness gauge.
## HTML
```html
<div class="tp-15">
<div class="tp-15__chart">
<svg viewBox="0 0 400 400" xmlns="http://www.w3.org/2000/svg">
<circle cx="22" cy="18" r="0.6" fill="rgba(200,220,255,0.35)"/>
<circle cx="80" cy="10" r="0.7" fill="rgba(200,220,255,0.45)"/>
<circle cx="140" cy="22" r="0.4" fill="rgba(200,220,255,0.25)"/>
<circle cx="170" cy="38" r="0.6" fill="rgba(200,220,255,0.35)"/>
<circle cx="265" cy="18" r="0.7" fill="rgba(200,220,255,0.4)"/>
<circle cx="330" cy="22" r="0.4" fill="rgba(200,220,255,0.22)"/>
<circle cx="360" cy="55" r="0.6" fill="rgba(200,220,255,0.38)"/>
<circle cx="30" cy="80" r="0.4" fill="rgba(200,220,255,0.2)"/>
<circle cx="320" cy="75" r="0.6" fill="rgba(200,220,255,0.32)"/>
<circle cx="55" cy="145" r="0.5" fill="rgba(200,220,255,0.28)"/>
<circle cx="360" cy="150" r="0.5" fill="rgba(200,220,255,0.28)"/>
<circle cx="35" cy="260" r="0.5" fill="rgba(200,220,255,0.3)"/>
<circle cx="380" cy="260" r="0.5" fill="rgba(200,220,255,0.28)"/>
<circle cx="58" cy="360" r="0.4" fill="rgba(200,220,255,0.2)"/>
<circle cx="90" cy="380" r="0.5" fill="rgba(200,220,255,0.28)"/>
<circle cx="340" cy="355" r="0.5" fill="rgba(200,220,255,0.3)"/>
<circle cx="392" cy="360" r="0.6" fill="rgba(200,220,255,0.35)"/>
<line x1="200" y1="48" x2="148" y2="155" stroke="rgba(140,160,255,0.18)" stroke-width="0.8"/>
<line x1="200" y1="48" x2="262" y2="142" stroke="rgba(140,160,255,0.18)" stroke-width="0.8"/>
<line x1="148" y1="155" x2="168" y2="228" stroke="rgba(140,160,255,0.18)" stroke-width="0.8"/>
<line x1="262" y1="142" x2="232" y2="224" stroke="rgba(140,160,255,0.18)" stroke-width="0.8"/>
<line x1="168" y1="228" x2="200" y2="230" stroke="rgba(140,160,255,0.22)" stroke-width="0.8"/>
<line x1="200" y1="230" x2="232" y2="224" stroke="rgba(140,160,255,0.22)" stroke-width="0.8"/>
<line x1="168" y1="228" x2="136" y2="342" stroke="rgba(140,160,255,0.18)" stroke-width="0.8"/>
<line x1="232" y1="224" x2="278" y2="330" stroke="rgba(140,160,255,0.18)" stroke-width="0.8"/>
<circle cx="200" cy="48" r="6" fill="rgba(160,180,255,0.08)"/>
<circle cx="200" cy="48" r="2.5" fill="#d0daff" opacity="0.85"/>
<circle cx="148" cy="155" r="10" fill="rgba(255,120,60,0.06)"/>
<circle cx="148" cy="155" r="5" fill="#ffb890" opacity="0.9"/>
<circle cx="262" cy="142" r="6" fill="rgba(160,200,255,0.06)"/>
<circle cx="262" cy="142" r="3" fill="#c0d8ff" opacity="0.85"/>
<circle cx="168" cy="228" r="5" fill="rgba(160,180,255,0.06)"/>
<circle cx="168" cy="228" r="2.8" fill="#d0daff" opacity="0.85"/>
<circle cx="200" cy="230" r="5" fill="rgba(160,180,255,0.06)"/>
<circle cx="200" cy="230" r="3" fill="#d0daff" opacity="0.85"/>
<circle cx="232" cy="224" r="5" fill="rgba(160,200,255,0.06)"/>
<circle cx="232" cy="224" r="2.5" fill="#c8d8ff" opacity="0.85"/>
<circle cx="136" cy="342" r="5" fill="rgba(160,200,255,0.06)"/>
<circle cx="136" cy="342" r="2.5" fill="#c0d4ff" opacity="0.8"/>
<circle cx="278" cy="330" r="14" fill="rgba(160,200,255,0.05)"/>
<circle cx="278" cy="330" r="6" fill="#dce8ff" opacity="0.95"/>
</svg>
<div class="tp-15__spot" style="left:37%;top:38.75%"><div class="tp-15__hit"></div>
<div class="tp-15__card">
<div class="tp-15__top"><div class="tp-15__bayer">α Orionis</div><div class="tp-15__name">Betelgeuse</div><div class="tp-15__const">Orion · Upper left shoulder</div><span class="tp-15__pill">M1–2 Iaab · Red Supergiant</span></div>
<div class="tp-15__data">
<div class="tp-15__row"><span class="tp-15__key">Distance</span><span class="tp-15__val">700 ly</span></div>
<div class="tp-15__row"><span class="tp-15__key">App. mag</span><span class="tp-15__val">0.42 (variable)</span></div>
<div class="tp-15__row"><span class="tp-15__key">Luminosity</span><span class="tp-15__val">~126,000 L☉</span></div>
<div class="tp-15__row"><span class="tp-15__key">Radius</span><span class="tp-15__val">~700 R☉</span></div>
<div class="tp-15__mag"><span class="tp-15__mag-label">Brightness</span><span class="tp-15__mag-stars"><span class="tp-15__mag-star">★</span><span class="tp-15__mag-star">★</span><span class="tp-15__mag-star">★</span><span class="tp-15__mag-star">★</span><span class="tp-15__mag-star tp-15__mag-dim">★</span></span></div>
</div>
</div>
</div>
<div class="tp-15__spot" style="left:69.5%;top:82.5%"><div class="tp-15__hit"></div>
<div class="tp-15__card tp-15__card-left">
<div class="tp-15__top"><div class="tp-15__bayer">β Orionis</div><div class="tp-15__name">Rigel</div><div class="tp-15__const">Orion · Lower right</div><span class="tp-15__pill">B8 Ia · Blue Supergiant</span></div>
<div class="tp-15__data">
<div class="tp-15__row"><span class="tp-15__key">Distance</span><span class="tp-15__val">860 ly</span></div>
<div class="tp-15__row"><span class="tp-15__key">App. mag</span><span class="tp-15__val">0.13 (brightest)</span></div>
<div class="tp-15__row"><span class="tp-15__key">Luminosity</span><span class="tp-15__val">~120,000 L☉</span></div>
<div class="tp-15__row"><span class="tp-15__key">Temp</span><span class="tp-15__val">12,100 K</span></div>
<div class="tp-15__mag"><span class="tp-15__mag-label">Brightness</span><span class="tp-15__mag-stars"><span class="tp-15__mag-star">★</span><span class="tp-15__mag-star">★</span><span class="tp-15__mag-star">★</span><span class="tp-15__mag-star">★</span><span class="tp-15__mag-star">★</span></span></div>
</div>
</div>
</div>
<div class="tp-15__spot" style="left:65.5%;top:35.5%"><div class="tp-15__hit"></div>
<div class="tp-15__card tp-15__card-left">
<div class="tp-15__top"><div class="tp-15__bayer">γ Orionis</div><div class="tp-15__name">Bellatrix</div><div class="tp-15__const">Orion · Upper right shoulder</div><span class="tp-15__pill">B2 III · Blue Giant</span></div>
<div class="tp-15__data">
<div class="tp-15__row"><span class="tp-15__key">Distance</span><span class="tp-15__val">250 ly</span></div>
<div class="tp-15__row"><span class="tp-15__key">App. mag</span><span class="tp-15__val">1.64</span></div>
<div class="tp-15__row"><span class="tp-15__key">Luminosity</span><span class="tp-15__val">~6,400 L☉</span></div>
<div class="tp-15__row"><span class="tp-15__key">Temp</span><span class="tp-15__val">22,000 K</span></div>
<div class="tp-15__mag"><span class="tp-15__mag-label">Brightness</span><span class="tp-15__mag-stars"><span class="tp-15__mag-star">★</span><span class="tp-15__mag-star">★</span><span class="tp-15__mag-star">★</span><span class="tp-15__mag-star tp-15__mag-dim">★</span><span class="tp-15__mag-star tp-15__mag-dim">★</span></span></div>
</div>
</div>
</div>
<div class="tp-15__spot" style="left:50%;top:57.5%"><div class="tp-15__hit"></div>
<div class="tp-15__card">
<div class="tp-15__top"><div class="tp-15__bayer">ε Orionis</div><div class="tp-15__name">Alnilam</div><div class="tp-15__const">Orion · Belt, central star</div><span class="tp-15__pill">B0 Ia · Blue Supergiant</span></div>
<div class="tp-15__data">
<div class="tp-15__row"><span class="tp-15__key">Distance</span><span class="tp-15__val">2,000 ly</span></div>
<div class="tp-15__row"><span class="tp-15__key">App. mag</span><span class="tp-15__val">1.69</span></div>
<div class="tp-15__row"><span class="tp-15__key">Luminosity</span><span class="tp-15__val">~375,000 L☉</span></div>
<div class="tp-15__row"><span class="tp-15__key">Temp</span><span class="tp-15__val">27,500 K</span></div>
</div>
</div>
</div>
<div class="tp-15__spot" style="left:50%;top:12%"><div class="tp-15__hit"></div>
<div class="tp-15__card">
<div class="tp-15__top"><div class="tp-15__bayer">λ Orionis</div><div class="tp-15__name">Meissa</div><div class="tp-15__const">Orion · Head</div><span class="tp-15__pill">O8 III · Blue-White Giant</span></div>
<div class="tp-15__data">
<div class="tp-15__row"><span class="tp-15__key">Distance</span><span class="tp-15__val">1,100 ly</span></div>
<div class="tp-15__row"><span class="tp-15__key">App. mag</span><span class="tp-15__val">3.39</span></div>
<div class="tp-15__row"><span class="tp-15__key">Luminosity</span><span class="tp-15__val">~28,000 L☉</span></div>
<div class="tp-15__row"><span class="tp-15__key">Temp</span><span class="tp-15__val">35,000 K</span></div>
</div>
</div>
</div>
<div class="tp-15__spot" style="left:34%;top:85.5%"><div class="tp-15__hit"></div>
<div class="tp-15__card">
<div class="tp-15__top"><div class="tp-15__bayer">κ Orionis</div><div class="tp-15__name">Saiph</div><div class="tp-15__const">Orion · Lower left</div><span class="tp-15__pill">B0.5 Ia · Blue Supergiant</span></div>
<div class="tp-15__data">
<div class="tp-15__row"><span class="tp-15__key">Distance</span><span class="tp-15__val">720 ly</span></div>
<div class="tp-15__row"><span class="tp-15__key">App. mag</span><span class="tp-15__val">2.07</span></div>
<div class="tp-15__row"><span class="tp-15__key">Luminosity</span><span class="tp-15__val">~57,500 L☉</span></div>
<div class="tp-15__row"><span class="tp-15__key">Temp</span><span class="tp-15__val">26,500 K</span></div>
</div>
</div>
</div>
</div>
</div>
```
## CSS
```css
.tp-15 {
width: 100%;
min-height: 100vh;
background: #04060e;
/* Side room — star cards pop to the right (Betelgeuse, Alnilam,
Meissa, Saiph) or left (Rigel, Bellatrix). 260px each side. */
padding: 40px 280px;
font-family: 'JetBrains Mono', ui-monospace, monospace;
display: flex;
align-items: center;
justify-content: center;
}
.tp-15__chart {
position: relative;
width: 400px;
height: 400px;
flex-shrink: 0;
}
.tp-15__chart svg {
width: 100%;
height: 100%;
display: block;
}
.tp-15__spot {
position: absolute;
transform: translate(-50%, -50%);
cursor: help;
z-index: 10;
}
.tp-15__hit {
width: 22px;
height: 22px;
border-radius: 50%;
position: relative;
}
.tp-15__hit::after {
content: '';
position: absolute;
inset: 0;
border-radius: 50%;
background: rgba(180, 200, 255, 0);
transition: background .2s;
}
.tp-15__spot:hover .tp-15__hit::after {
background: rgba(180, 200, 255, 0.08);
box-shadow: 0 0 18px 6px rgba(160, 180, 255, 0.12);
}
.tp-15__card {
position: absolute;
left: calc(100% + 14px);
top: 50%;
transform: translateY(-50%) translateX(6px);
z-index: 200;
width: 230px;
background: rgba(8, 12, 28, 0.96);
border: 1px solid rgba(100, 120, 200, 0.2);
border-radius: 8px;
opacity: 0;
visibility: hidden;
pointer-events: none;
transition: opacity .2s, transform .2s cubic-bezier(0.22, 1, 0.36, 1), visibility 0s linear .2s;
box-shadow: 0 12px 38px rgba(0, 0, 0, 0.9), 0 0 0 1px rgba(100, 120, 200, 0.06);
overflow: hidden;
text-align: left;
}
.tp-15__spot:hover .tp-15__card {
opacity: 1;
visibility: visible;
transform: translateY(-50%) translateX(0);
transition-delay: 0s;
}
.tp-15__card-left {
left: auto;
right: calc(100% + 14px);
transform: translateY(-50%) translateX(-6px);
}
.tp-15__spot:hover .tp-15__card-left {
transform: translateY(-50%) translateX(0);
}
.tp-15__top {
padding: 12px 13px 10px;
border-bottom: 1px solid rgba(100, 120, 200, 0.1);
}
.tp-15__bayer {
font-size: 9px;
color: rgba(140, 160, 255, 0.4);
letter-spacing: 0.1em;
margin-bottom: 3px;
}
.tp-15__name {
font-size: 15px;
font-weight: 500;
color: rgba(220, 230, 255, 0.92);
margin-bottom: 1px;
}
.tp-15__const {
font-size: 9.5px;
color: rgba(100, 120, 180, 0.6);
}
.tp-15__pill {
display: inline-block;
font-size: 8.5px;
padding: 2px 7px;
border-radius: 3px;
margin-top: 6px;
letter-spacing: 0.06em;
border: 1px solid rgba(100, 120, 200, 0.2);
color: rgba(140, 160, 220, 0.7);
}
.tp-15__data {
padding: 10px 13px;
}
.tp-15__row {
display: flex;
justify-content: space-between;
margin-bottom: 5px;
}
.tp-15__key {
font-size: 8.5px;
color: rgba(60, 80, 140, 0.7);
letter-spacing: 0.08em;
}
.tp-15__val {
font-size: 9.5px;
color: rgba(160, 180, 240, 0.75);
}
.tp-15__mag {
display: flex;
align-items: center;
gap: 8px;
margin-top: 8px;
padding-top: 8px;
border-top: 1px solid rgba(100, 120, 200, 0.06);
}
.tp-15__mag-label {
font-size: 7.5px;
color: rgba(60, 80, 140, 0.5);
letter-spacing: 0.08em;
}
.tp-15__mag-stars {
display: flex;
gap: 2px;
}
.tp-15__mag-star {
font-size: 9.5px;
color: rgba(255, 220, 80, 0.7);
}
.tp-15__mag-dim {
color: rgba(60, 80, 140, 0.3);
}
```How this works
The Orion Constellation Chart demo lays down a starfield the way Stellarium or SkyView presents it — #04060e deep-space background, 17 faint field stars rendered as low-opacity SVG circles, and eight thin rgba(140,160,255,0.18) lines connecting the seven bright stars into the Orion figure. Six of those bright stars carry hover hotspots that reveal astronomical data cards: Betelgeuse (alpha), Rigel (beta), Bellatrix (gamma), Alnilam (epsilon), Meissa (lambda), and Saiph (kappa). Each hotspot is a .tp-15__spot absolutely positioned by percentage on the 400x400 chart, with a 22px round .tp-15__hit target — a WCAG-friendly footprint even though the visible star underneath is tiny.
Hover the hotspot and the hit target's ::after pseudo lights up with a soft rgba(180,200,255,0.08) glow plus an 18px blue box-shadow halo, then the .tp-15__card — 230px, positioned via left:calc(100% + 14px); top:50% and vertically centered — fades in with the shared opacity plus translateX(6px) pattern. Cards for the two right-side stars (Rigel, Bellatrix) carry the .tp-15__card-left modifier that swaps to right:calc(100% + 14px) and mirrors the transform, keeping cards inside the frame.
Each card stacks a header with the Bayer designation, star name, constellation position, and a spectral-class pill. Data rows follow — distance in light-years, apparent magnitude, luminosity in solar units, and either radius or temperature. Betelgeuse, Rigel, and Bellatrix also carry a five-star brightness gauge where dim stars use .tp-15__mag-dim. JetBrains Mono and blue-tinted grays sell the observatory-console register.
Make it yours
- Add another star by cloning a
.tp-15__spot, updating itsleft/toppercentages against the 400x400 SVG viewBox, and matching the constellation-line SVG endpoints. Extend the svg lines to connect it. Use.tp-15__card-leftif the star sits on the right half. - Retune the brightness gauge by changing the count of filled versus
.tp-15__mag-dimstar spans. Real Bayer designations follow apparent magnitude — Rigel at 0.13 is brightest, Meissa at 3.39 is dimmest. Keep the visual and the data honest for astronomy audiences. - Change constellation by rebuilding the SVG paths and star positions. The Big Dipper needs seven stars, Cassiopeia five in a W. Keep the 400x400 viewBox and percentage-positioned spots so the demo stays responsive.
- Shift the palette from blue-white to warmer amber (spectral class G or K stars) by editing the rgba stops on
.tp-15__hit::after,.tp-15__cardborder, and.tp-15__val. The starfield background stays#04060efor optical realism. - Add mythology to the card by inserting a paragraph between
.tp-15__topand.tp-15__data. Use the same padding rhythm (12px 13px) and 9.5px 1.5 leading Georgia-italic type for a mythology-notebook feel against the mono data rows.
Gotchas — read before shipping
- The 22px hit target is below Apple's 44x44px HIG recommendation and Google's 48x48px Material guideline. For touch, wrap each
.tp-15__hitin a 44px transparent padding zone using an outer::before. Sighted users see the same star; tap accuracy triples. - The
.tp-15__cardusesz-index:200to stack over the SVG, but the SVG chart sits inside a flex-centered container. A parent stacking context can still swallow the popover — setisolation:isolateon.tp-15__chartto lock the z-index scope. - WCAG SC 1.4.11 (Non-text Contrast) applies to the pill borders —
rgba(100,120,200,0.2)on a near-black card sits well below 3:1. Bump the alpha to 0.5 for interactive elements, or accept the low contrast as decorative and rely on the label text (which does pass 4.5:1). - The card's
rgba(8,12,28,0.96)background bleeds the starfield through slightly. On a stark bug report screen the effect reads intentional; on a dashboard it can look like a rendering glitch. Bump to0.99or a solid#080c1cfor higher-fidelity contexts. - The two
.tp-15__card-leftstars (Rigel, Bellatrix) rely on the wrapper's percentageleftbeing over 50% to have room on the left. If you reposition either star past the center, its card will overflow the chart's left edge. Verify with each layout change. - The unicode solar symbol and Bayer greek letters may fall back to a system font on old Linux distros. Include a webfont subset with those glyphs, or accept that the letters might render as fallback boxes on unfixed setups. Test on Fedora and Debian.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 90+ | 14+ | 88+ | 90+ |
Inline SVG, box-shadow halos, and the transform-based pop-in all render identically. iOS Safari renders the deep-space background slightly warmer than macOS. Firefox's SVG line-antialiasing on 0.8px strokes is very slightly softer than Chromium's.