Zoeken...  ⌘K GitHub

Tooltip UI Elements

Pure CSS tooltip. 4 posities. Optionele delay. Geen JS vereist.

/tooltip
src/components/ui/Tooltip.astro
---
/**
 * Tooltip
 * Hover/focus tooltip wrapper. Puur CSS, geen JS nodig.
 * Positie: top (default), bottom, left, right.
 */
interface Props {
  content: string;
  position?: 'top' | 'bottom' | 'left' | 'right';
  delay?: boolean;
  dark?: boolean;
}

const {
  content,
  position = 'top',
  delay = true,
  dark = true,
} = Astro.props;
---

<span
  class:list={['tt', `tt--${position}`, { 'tt--delay': delay, 'tt--light': !dark }]}
  data-component="tooltip"
  data-tip={content}
>
  <slot />
  <span class="tt__bubble" role="tooltip">{content}</span>
</span>

<style>
  .tt {
    position: relative;
    display: inline-flex;
    align-items: center;
  }

  /* Bubble */
  .tt__bubble {
    position: absolute;
    background: var(--color-primary, #0a0a0a);
    color: #fff;
    font-size: 0.75rem;
    font-weight: 500;
    padding: 0.375rem 0.625rem;
    border-radius: 0.375rem;
    white-space: nowrap;
    pointer-events: none;
    z-index: 50;
    opacity: 0;
    transition: opacity 0.15s, transform 0.15s;
    box-shadow: 0 4px 12px rgba(0,0,0,0.15);
    line-height: 1.4;
    max-width: 200px;
    white-space: normal;
    text-align: center;
  }

  .tt--light .tt__bubble {
    background: var(--color-bg, #fff);
    color: var(--color-primary, #0a0a0a);
    border: 1px solid rgba(0,0,0,0.1);
  }

  /* Arrow */
  .tt__bubble::before {
    content: '';
    position: absolute;
    border: 5px solid transparent;
  }

  /* Position: top (default) */
  .tt--top .tt__bubble {
    bottom: calc(100% + 8px);
    left: 50%;
    transform: translateX(-50%) translateY(4px);
  }

  .tt--top .tt__bubble::before {
    top: 100%;
    left: 50%;
    transform: translateX(-50%);
    border-top-color: var(--color-primary, #0a0a0a);
    border-bottom: none;
  }

  .tt--top.tt--light .tt__bubble::before { border-top-color: rgba(0,0,0,0.1); }

  /* Position: bottom */
  .tt--bottom .tt__bubble {
    top: calc(100% + 8px);
    left: 50%;
    transform: translateX(-50%) translateY(-4px);
  }

  .tt--bottom .tt__bubble::before {
    bottom: 100%;
    left: 50%;
    transform: translateX(-50%);
    border-bottom-color: var(--color-primary, #0a0a0a);
    border-top: none;
  }

  /* Position: left */
  .tt--left .tt__bubble {
    right: calc(100% + 8px);
    top: 50%;
    transform: translateY(-50%) translateX(4px);
  }

  .tt--left .tt__bubble::before {
    left: 100%;
    top: 50%;
    transform: translateY(-50%);
    border-left-color: var(--color-primary, #0a0a0a);
    border-right: none;
  }

  /* Position: right */
  .tt--right .tt__bubble {
    left: calc(100% + 8px);
    top: 50%;
    transform: translateY(-50%) translateX(-4px);
  }

  .tt--right .tt__bubble::before {
    right: 100%;
    top: 50%;
    transform: translateY(-50%);
    border-right-color: var(--color-primary, #0a0a0a);
    border-left: none;
  }

  /* Show on hover/focus */
  .tt:hover .tt__bubble,
  .tt:focus-within .tt__bubble {
    opacity: 1;
  }

  .tt--top:hover .tt__bubble,
  .tt--top:focus-within .tt__bubble { transform: translateX(-50%) translateY(0); }

  .tt--bottom:hover .tt__bubble,
  .tt--bottom:focus-within .tt__bubble { transform: translateX(-50%) translateY(0); }

  .tt--left:hover .tt__bubble,
  .tt--left:focus-within .tt__bubble { transform: translateY(-50%) translateX(0); }

  .tt--right:hover .tt__bubble,
  .tt--right:focus-within .tt__bubble { transform: translateY(-50%) translateX(0); }

  /* Delay */
  .tt--delay .tt__bubble { transition-delay: 0s, 0s; }
  .tt--delay:hover .tt__bubble { transition-delay: 0.3s; }
</style>

Props

Prop Type Default Beschrijving
content * string Tooltip tekst
position 'top' | 'bottom' | 'left' | 'right' 'top' Positie ten opzichte van trigger
delay boolean false 300ms vertraging voor hover

* = verplicht