Skip to content

Tooltip

For a line or two of explanation that will not fit on screen — it appears right where the question mark was tapped.

Overlays

Live preview

Source

<div class="dc-tip-stage">
  <div class="dc-tip-row">
    <span class="dc-tip-label">받는 분 번호</span>
    <span class="dc-tip-wrap">
      <button class="dc-tip-target" type="button" aria-expanded="true" aria-describedby="dc-tip-1">
        <span class="dc-sr">받는 분 번호 안내 닫기</span>
        <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="8.2" fill="none" stroke="currentColor" stroke-width="1.6"/><path d="M12 11v5.2" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/><circle cx="12" cy="8.1" r="1.1" fill="currentColor"/></svg>
      </button>
      <span class="dc-tip" role="tooltip" id="dc-tip-1">이 번호로만 배송 안내 문자가 갑니다. 주문 뒤에는 바꿀 수 없습니다.</span>
    </span>
  </div>
</div>
.dc-tip-stage {
  display: flex; align-items: flex-end; justify-content: center;
  min-height: 180px; padding: var(--dc-6) var(--dc-5);
  background: var(--dc-bg);
  border-radius: var(--dc-r-md);
  font-family: var(--dc-font);
}
.dc-tip-stage--top { align-items: flex-start; }
.dc-tip-row {
  display: flex; align-items: center; gap: var(--dc-1);
  width: 100%; max-width: 330px;
  padding: var(--dc-3) var(--dc-4);
  background: var(--dc-surface);
  border: 1px solid var(--dc-line); border-radius: var(--dc-r-md);
}
.dc-tip-label { font-size: 14px; font-weight: 600; color: var(--dc-text); }
.dc-tip-wrap { position: relative; display: inline-flex; }
.dc-tip-target {
  display: grid; place-items: center;
  width: 44px; height: 44px;
  border: 0; border-radius: var(--dc-r-full);
  background: transparent; color: var(--dc-text-mute);
}
.dc-tip-target svg { width: 20px; height: 20px; }
.dc-tip-target[aria-expanded="true"] { color: var(--dc-brand-text); background: var(--dc-brand-soft); }
.dc-tip {
  position: absolute; left: 50%; bottom: calc(100% + 10px);
  z-index: 2;
  width: 232px; transform: translateX(-50%);
  padding: var(--dc-3) var(--dc-4);
  background: var(--dc-surface);
  border: 1px solid var(--dc-line-bold); border-radius: var(--dc-r-sm);
  box-shadow: var(--dc-sh-2);
  font-size: 12px; line-height: 1.7; color: var(--dc-text);
  text-align: left;
}
.dc-tip::after {
  content: ""; position: absolute;
  left: calc(50% - 6px); top: 100%;
  width: 12px; height: 12px;
  margin-top: -6px;
  transform: rotate(45deg);
  background: var(--dc-surface);
  border-right: 1px solid var(--dc-line-bold);
  border-bottom: 1px solid var(--dc-line-bold);
}
.dc-tip--down { bottom: auto; top: calc(100% + 10px); }
.dc-tip--down::after {
  top: 0; margin-top: -6px;
  border: 0;
  border-left: 1px solid var(--dc-line-bold);
  border-top: 1px solid var(--dc-line-bold);
}
.dc-tip-stage--coach { position: relative; overflow: hidden; align-items: flex-start; min-height: 300px; }
.dc-tip-coach { position: absolute; inset: 0; background: var(--dc-overlay); }
.dc-tip-hole {
  position: relative; z-index: 1;
  display: grid; place-items: center;
  width: 64px; height: 64px;
  border-radius: var(--dc-r-full);
  background: var(--dc-surface);
  box-shadow: 0 0 0 6px var(--dc-brand-soft);
  color: var(--dc-brand-text);
}
.dc-tip-hole__ico svg { width: 30px; height: 30px; }
.dc-tip--coach {
  left: 50%; bottom: auto; top: calc(var(--dc-6) + 74px);
  display: flex; flex-direction: column; gap: var(--dc-2);
  width: min(300px, 100%);
  padding: var(--dc-4) var(--dc-5) var(--dc-3);
  border-color: var(--dc-brand);
  box-shadow: var(--dc-sh-3);
}
.dc-tip--coach::after { border-color: var(--dc-brand); }
.dc-tip__step { font-size: 11px; font-weight: 700; letter-spacing: .04em; color: var(--dc-brand-text); }
.dc-tip__title { font-size: 14px; font-weight: 700; line-height: 1.5; color: var(--dc-text); }
.dc-tip__body { font-size: 12px; line-height: 1.7; color: var(--dc-text-sub); }
.dc-tip__acts { display: flex; align-items: center; justify-content: space-between; gap: var(--dc-2); margin-top: var(--dc-1); }
.dc-tip__skip {
  min-height: 44px; padding: 0 var(--dc-2);
  border: 0; background: transparent; color: var(--dc-text-mute);
  font-family: inherit; font-size: 12px; font-weight: 600;
}
.dc-tip__next {
  min-width: 88px; min-height: 44px; padding: 0 var(--dc-4);
  border: 0; border-radius: var(--dc-r-sm);
  background: var(--dc-brand); color: var(--dc-text-on);
  font-family: inherit; font-size: 13px; font-weight: 700;
}
.dc-tip__next:active { background: var(--dc-brand-hi); }

How to use it

  • Touch screens have no hover: open it on tap and close it on the next tap
  • Keep the text to help people can do without; anything required belongs on the screen itself
  • Past two lines, move the content into a bottom sheet instead
  • A first-run coach mark should point at one thing at a time and offer a way out

Watch out for

  • Without aria-describedby tying button to bubble, screen readers never announce the help
  • Near a screen edge the bubble clips — shift the arrow or flip it below
  • The question-mark button still needs 44×44px, and a dc-sr name since it is icon-only

Next