できない.dev

CSSでバッジを要素の右上に重ねるには

position: absolute のバッジを、親に position: relative を与えてカードの右上へ重ねる基本形を示す。
位置の基準になる祖先を明示しないと、バッジはページ全体を基準に飛んでいく。

実行確認済み

実行確認済みは、ブラウザで実際に描画して見た目を確認したものである。

公開:

プレビュー
<style>
.card {
  position: relative; /* バッジの位置基準になる */
  width: 260px;
  padding: 16px;
  border: 1px solid #e2e8f0;
  border-radius: 10px;
  background: #fff;
}
.badge {
  position: absolute;
  top: -10px;
  right: -10px;
  padding: 4px 10px;
  border-radius: 999px;
  background: #0f766e;
  color: #fff;
  font-size: 12px;
  font-weight: 700;
}
.card__title {
  margin: 0 0 6px;
  font-weight: 700;
}
.card__body {
  margin: 0;
  font-size: 14px;
  color: #475569;
}
</style>
<div class="card">
  <span class="badge">NEW</span>
  <p class="card__title">お知らせカード</p>
  <p class="card__body">右上のバッジはカードを基準に置いている。</p>
</div>

position: absolute の要素は「最も近い位置指定済みの祖先」を基準に配置される。
重ねたい相手(ここでは .card)に position: relative を付けるのは、その基準を自分に引き寄せるためである。

つまずき

バッジが意図しない場所に飛ぶ原因のほとんどは、親に position が指定されていないことである。
position: absolute は static 以外の position を持つ最も近い祖先を基準にするため、基準が見つからないと初期包含ブロック(実質ページ全体)まで遡り、top / right がビューポート基準として解釈される。
逆に、意図しない中間要素に position: relative が付いていると、そちらが基準に横取りされる。
まず開発者ツールで、基準にしたい要素に position: relative が当たっているかを確認するとよい。

はみ出した分が切れるとき

上の例は top: -10px / right: -10px でカードの枠から少しはみ出させている。
このとき祖先のどこかに overflow: hidden があると、はみ出した部分が切り取られて見えなくなる。
角丸のために overflow: hidden を付けている親がいないかを疑う。
切り取らせたくない場合は、overflow を持つ要素の外側にバッジを出すか、はみ出さない値(top: 8px / right: 8px など)に収めるのが素直である。

重なり順が思ったとおりにならないとき

バッジが隣の要素の下に潜る場合は z-index ではなく、まず重ね合わせコンテキストを疑う。
position 指定と z-index の組み合わせのほか、transform・filter・opacity が 1 未満といったプロパティも新しい重ね合わせコンテキストを作り、その内側の z-index は外へ効かなくなる。
バッジだけ z-index を上げても直らないときは、祖先にこれらのプロパティが付いていないかを見る。