/* Adapted from https://github.com/argyleink/gui-challenges/blob/main/tooltips/tool-tip.css */ .tooltip { /* Used to power spacing and layout for RTL languages */ --isRTL: -1; /* internal CSS vars */ --_delay: 200ms; --_triangle-width: 8px; --_triangle-height: 12px; --_p-inline: calc(50% + calc(var(--isRTL) * var(--_triangle-width) / 2)); --_p-block: 4px; --_bg: var(--chalkboard-10); --_shadow-alpha: 5%; --_theme-alpha: 0.15; --_theme-outline: drop-shadow( 0 1px 0 oklch( var(--primary-lightness) var(--primary-chroma) var(--primary-hue) / var(--_theme-alpha) ) ) drop-shadow( 0 -1px 0 oklch(var(--primary-lightness) var(--primary-chroma) var(--primary-hue) / var(--_theme-alpha)) ) drop-shadow( 1px 0 0 oklch( var(--primary-lightness) var(--primary-chroma) var(--primary-hue) / var(--_theme-alpha) ) ) drop-shadow( -1px 0 0 oklch(var(--primary-lightness) var(--primary-chroma) var(--primary-hue) / var(--_theme-alpha)) ); pointer-events: none; user-select: none; /* The parts that will be transitioned */ opacity: 0; transform: translate(var(--_x, 0), var(--_y, 0)); transition: transform 0.15s ease-out, opacity 0.11s ease-out; position: absolute; z-index: 1; inline-size: max-content; max-inline-size: 25ch; text-align: start; font-family: var(--mono-font-family); text-transform: none; font-size: 0.9rem; font-weight: normal; line-height: initial; letter-spacing: 0; padding: var(--_p-block) var(--_p-inline); margin: 0; border-radius: 3px; background: var(--_bg); @apply text-chalkboard-110; will-change: filter; filter: drop-shadow(0 1px 3px hsl(0 0% 0% / var(--_shadow-alpha))) drop-shadow(0 4px 8px hsl(0 0% 0% / var(--_shadow-alpha))) var(--_theme-outline); } :global(.dark) .tooltip { --_bg: var(--chalkboard-110); --_theme-alpha: 40%; @apply text-chalkboard-10; filter: var(--_theme-outline); } .tooltip:dir(rtl) { --isRTL: 1; } /* :has and :is are pretty fresh CSS pseudo-selectors, may not see full support */ :has(> .tooltip) { position: relative; } :is(:hover, :active) > .tooltip { opacity: 1; transition-delay: var(--_delay); } :is(:focus-visible) > .tooltip.withFocus { opacity: 1; } .tooltip:focus-visible { --_delay: 0 !important; } /* prepend some prose for screen readers only */ .tooltip::before { content: '; Has tooltip: '; clip: rect(1px, 1px, 1px, 1px); clip-path: inset(50%); height: 1px; width: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; } /* Sometimes there's no visible label, * so we'll use the tooltip as the label */ .tooltip:only-child::before { content: 'Tooltip:'; } .caret { width: 8px; height: var(--_triangle-height); position: absolute; z-index: -1; transform-origin: center center; color: var(--_bg); } .top, .bottom { text-align: center; } .tooltip.top { inset-inline-start: 50%; inset-block-end: calc(100% + var(--_p-block) + var(--_triangle-height)); --_x: calc(50% * var(--isRTL)); } .top .caret { inset-block-start: calc(100% - 1px); inset-inline-start: 50%; transform: translateX(-50%); } .tooltip.top-right { inset-inline-end: var(--_p-inline); inset-block-end: calc(100% + var(--_p-block) + var(--_triangle-height)); } /* The corner caret SVG is bottom-right oriented by default */ .top-right .caret { inset-block-start: calc(100% - 1px); inset-inline-end: 0; } .tooltip.right { inset-inline-start: calc(100% + var(--_p-inline) + var(--_triangle-height)); inset-block-end: 50%; --_y: 50%; } .right .caret { inset-inline-end: calc(100% - 1px); inset-block-start: 50%; transform: translateY(-50%) rotate(90deg); } .tooltip.bottom-right { inset-inline-end: var(--_p-inline); inset-block-start: calc(100% + var(--_p-block) + var(--_triangle-height)); } .bottom-right .caret { inset-block-end: calc(100% - 1px); inset-inline-end: 0; transform: rotate(180deg) scaleX(-1); } .tooltip.bottom { --_x: calc(50% * var(--isRTL)); inset-inline-start: 50%; inset-block-start: calc(100% + var(--_p-block) + var(--_triangle-height)); } .bottom .caret { inset-block-end: calc(100% - 1px); inset-inline-start: 50%; transform: translateX(-50%) scaleY(-1); } .tooltip.bottom-left { inset-inline-start: var(--_p-inline); inset-block-start: calc(100% + var(--_p-block) + var(--_triangle-height)); } .bottom-left .caret { inset-block-end: calc(100% - 1px); inset-inline-start: 0; transform: rotate(180deg); } .tooltip.left { inset-inline-end: calc(100% + var(--_p-inline) + var(--_triangle-height)); inset-block-end: 50%; --_y: 50%; } .left .caret { inset-inline-start: calc(100% - 1px); inset-block-start: 50%; transform: translateY(-50%) rotate(-90deg); } .tooltip.top-left { inset-inline-start: var(--_p-inline); inset-block-end: calc(100% + var(--_p-block) + var(--_triangle-height)); } .top-left .caret { inset-block-start: calc(100% - 1px); inset-inline-start: 0; transform: rotate(-90deg); } @media (prefers-reduced-motion: no-preference) { /* TOP || BLOCK-START */ :has(> :is(.tooltip.top, .tooltip.top-left, .tooltip.top-right)):not( :hover, :active ) .tooltip { --_y: 3px; } /* RIGHT || INLINE-END */ :has(> :is(.tooltip.right)):not(:hover, :active) .tooltip { --_x: calc(var(--isRTL) * -3px * -1); } /* BOTTOM || BLOCK-END */ :has( > :is( .tooltip.bottom, .tooltip.tooltip.bottom-left, .tooltip.bottom-right ) ):not(:hover, :active) .tooltip { --_y: -3px; } /* BOTTOM || BLOCK-END */ :has(> :is(.tooltip.left)):not(:hover, :active) .tooltip { --_x: calc(var(--isRTL) * 3px * -1); } }