CSSでバッジを要素の右上に重ねるには
position: absolute のバッジを、親に position: relative を与えてカードの右上へ重ねる基本形を示す。
位置の基準になる祖先を明示しないと、バッジはページ全体を基準に飛んでいく。
公開: 更新:
<div class="card">
<span class="badge">NEW</span>
<p class="card__title">お知らせカード</p>
<p class="card__body">右上のバッジはカードを基準に置いている。</p>
</div>.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;
}position: absolute の要素は「最も近い位置指定済みの祖先」を基準に配置される。
重ねたい相手(ここでは .card)に position: relative を付けるのは、その基準を自分に引き寄せるためである。
つまずき
バッジが意図しない場所に飛ぶ原因のほとんどは、親に position が指定されていないことである。
position: absolute は、static 以外の position を持つ最も近い祖先を基準にする。
基準が見つからないと初期包含ブロック(実質ページ全体)まで遡り、top / right がビューポート基準として解釈される。
逆に、意図しない中間要素に position: relative が付いていると、そちらに基準を横取りされる。
まず開発者ツールで、基準にしたい要素に position: relative が当たっているかを確認するとよい。
.card {
max-width: 200px;
margin-top: 32px;
padding: 16px;
border: 1px solid #e2e8f0;
border-radius: 10px;
}
.badge {
position: absolute;
top: 4px;
right: 4px;
padding: 2px 8px;
border-radius: 999px;
background: #0f766e;
color: #fff;
font-size: 12px;
}.card {
position: relative;
max-width: 200px;
margin-top: 32px;
padding: 16px;
border: 1px solid #e2e8f0;
border-radius: 10px;
}
.badge {
position: absolute;
top: 4px;
right: 4px;
padding: 2px 8px;
border-radius: 999px;
background: #0f766e;
color: #fff;
font-size: 12px;
}はみ出した分が切れるとき
上の例は top: -10px / right: -10px でカードの枠から少しはみ出させている。
このとき祖先のどこかに overflow: hidden があると、はみ出した部分が切り取られて見えなくなる。
角丸のために overflow: hidden を付けている親がいないかを疑う。
切り取らせたくない場合は、次のどちらかにするのが素直である。
overflowを持つ要素の外側にバッジを出す。- はみ出さない値(
top: 8px/right: 8pxなど)に収める。
.card {
position: relative;
overflow: hidden;
width: 160px;
margin: 8px 0 0;
padding: 16px;
border: 1px solid #e2e8f0;
border-radius: 10px;
}
.badge {
position: absolute;
top: -8px;
right: -8px;
padding: 2px 8px;
border-radius: 999px;
background: #0f766e;
color: #fff;
font-size: 12px;
}.card {
position: relative;
overflow: hidden;
width: 160px;
margin: 8px 0 0;
padding: 16px;
border: 1px solid #e2e8f0;
border-radius: 10px;
}
.badge {
position: absolute;
top: 8px;
right: 8px;
padding: 2px 8px;
border-radius: 999px;
background: #0f766e;
color: #fff;
font-size: 12px;
}重なり順が思ったとおりにならないとき
バッジが隣の要素の下に潜る場合は、z-index ではなく、まず重ね合わせコンテキストを疑う。
次のプロパティは新しい重ね合わせコンテキストを作り、その内側の z-index は外へ効かなくなる。
position指定とz-indexの組み合わせtransformfilter- 1 未満の
opacity
バッジだけ z-index を上げても直らないときは、祖先にこれらのプロパティが付いていないかを見る。
.row { display: flex; gap: 8px; }
.card {
position: relative;
width: 110px;
padding: 20px 12px;
border-radius: 10px;
background: #e0e7ff;
}
.a { transform: translateZ(0); }
.badge {
position: absolute;
z-index: 10;
top: 22px;
right: -30px;
padding: 2px 8px;
border-radius: 999px;
background: #0f766e;
color: #fff;
font-size: 12px;
}.row { display: flex; gap: 8px; }
.card {
position: relative;
width: 110px;
padding: 20px 12px;
border-radius: 10px;
background: #e0e7ff;
}
.badge {
position: absolute;
z-index: 10;
top: 22px;
right: -30px;
padding: 2px 8px;
border-radius: 999px;
background: #0f766e;
color: #fff;
font-size: 12px;
}