GODRICH

ステータス バッジ UI 9選 — タグ・優先度・認証バッジ

ステータス バッジ ui は、オンライン・優先度・認証といった状態を小さな点やラベル一つで伝える部品です。動きを加えるとそのまま使えるほど目を引きます。ステータス バッジ ui のアイデアを9つ集めました。

自動再生 · タイルを押すとその項目へ · すべて1つのzip

9つは人気順ではなく、実際の画面で出会う順番に並べました。ログインするとまずチームメンバーのオンライン状態(01)を見て、興味のあるタグを選んだり消したり(02)し、タスクに優先度(03)を付けます。閲覧しているとセールリボン(04)に出会い、新着通知(05)が届きます。プロフィールには技術スタック(06)や達成したばかりの実績バッジ(07)、認証バッジ(08)が並び、最後にクーポンの期限カウントダウン(09)が残ります。

01ステータスピル(オンライン・退席・取り込み中・オフライン)

オンラインドットの背後に隠れたリングがopacityscaleで一度だけ広がり、残り3つの状態は色が違うだけで、動きません。

opacity+scale ring::before무대 paper
.pill--online .dot::before {
  content: "";
  position: absolute; inset: -4px;
  border-radius: 50%;
  border: 2px solid $color;
  opacity: 0;
  transform: scale(.6);
}
.stage.is-demo .pill--online .dot::before {
  animation: ping $duration $easing infinite;
}
@keyframes ping {
  0% { opacity: .55; transform: scale(.6); }
  70%, 100% { opacity: 0; transform: scale(2.1); }
}

02削除ボタン付きタグチップ

チップの×ボタンを押すとscaleopacityで縮みながら実際に消え、デモでは同じ動きを一つのチップが自動で繰り返します。

scale+opacity실제 클릭 제거transitionend
.chip--gone {
  transition: transform $dur-quick $easing, opacity $dur-quick $easing;
  transform: scale(.6);
  opacity: 0;
}
.stage.is-demo .chip--demo {
  animation: chip-cycle $duration $easing infinite;
}
@keyframes chip-cycle {
  0%, 38% { transform: scale(1); opacity: 1; }
  55%, 78% { transform: scale(.55); opacity: 0; }
  100% { transform: scale(1); opacity: 1; }
}

03優先度ラベルバッジ(低・中・高・緊急)

緊急ラベルだけがopacityscaleで点滅するため、色だけが違う低・中・高の中でも最初に目に留まります。

opacity+scale flashflag Phosphor duotone정적 3단+동적 1단
.label--urgent {
  background: $error-soft;
  color: $color;
}
.stage.is-demo .label--urgent {
  animation: urgent-flash $duration $easing infinite;
}
@keyframes urgent-flash {
  0%, 40% { opacity: 1; transform: scale(1); }
  55% { opacity: .5; transform: scale(1.05); }
  70%, 100% { opacity: 1; transform: scale(1); }
}

04折りたたみリボンの展開バッジ

カード上端で折りたたまれたリボンがtransform-origin: topを基準にscaleYで開き、また巻き上がります。ほかの回で紹介した、光の帯が流れるリボンとは動き方が異なります。

scaleY unfurltransform-origin: topclip-path polygon
.ribbon {
  clip-path: polygon(0 0, 100% 0, 100% 100%, 50% 82%, 0 100%);
  transform: scaleY(0) rotate(0deg);
  transform-origin: top center;
}
.stage.is-demo .ribbon {
  animation: unfurl $duration $easing infinite;
}
@keyframes unfurl {
  0%, 8% { transform: scaleY(0) rotate(0deg); }
  30% { transform: scaleY(1.06) rotate(-2deg); }
  42%, 78% { transform: scaleY(1) rotate(0deg); }
  92%, 100% { transform: scaleY(0) rotate(0deg); }
}

05通知ドットのダブルパルス

アイコンは動かさず、角のドットだけがscaleで素早く2回跳ね、メッセージが続けて届いたようなリズムを作ります。

scale 더블 스프링@keyframes double-ring무대 ink
.dot {
  background: $color;
  box-shadow: 0 0 0 2px $stage-ink;
}
.stage.is-demo .dot {
  animation: double-pulse $duration $easing infinite;
}
.stage.is-demo .dot__ring {
  animation: double-ring $duration $easing infinite;
}
@keyframes double-pulse {
  0%, 100% { transform: scale(1); }
  8%, 24% { transform: scale(1.35); }
  16%, 32% { transform: scale(1); }
}
@keyframes double-ring {
  0%, 6% { opacity: 0; transform: scale(1); }
  20% { opacity: .5; transform: scale(2.4); }
  34% { opacity: 0; transform: scale(2.6); }
  100% { opacity: 0; transform: scale(1); }
}

06技術スタックタグクラウド

6つのスキルタグがopacitytranslateYで順番に浮かび上がっては消えることを繰り返し、タグごとの遅延だけで波打つような登場を見せます。

opacity+translateY staggeranimation-delay다크 무대
.cloud li {
  transform: translateY(10px);
  opacity: 0;
}
.stage.is-demo .cloud li {
  animation: rise $duration $easing infinite;
  animation-delay: calc(var(--i) * 90ms);
}
@keyframes rise {
  0% { opacity: 0; transform: translateY(10px); }
  22%, 70% { opacity: 1; transform: translateY(0); }
  92%, 100% { opacity: 0; transform: translateY(-6px); }
}

07実績バッジのロック解除アニメーション

くすんだトロフィーがscaleで弾みながら色を取り戻す瞬間、対角線の光が一度だけ通り過ぎて達成を強調します。

filter grayscale→colorscale bounceshine sweep translateX
.badge {
  filter: grayscale(1) brightness(.85);
  transform: scale(.85);
}
.stage.is-demo .badge {
  animation: unlock $duration $easing infinite;
}
@keyframes unlock {
  0%, 30% { transform: scale(.85); filter: grayscale(1) brightness(.85); }
  55% { transform: scale(1.12); filter: grayscale(0) brightness(1); }
  70% { transform: scale(.96); }
  82%, 100% { transform: scale(1); filter: grayscale(0) brightness(1); }
}

08プレミアム・認証バッジの反転

カード全体がrotateYで3D回転し、金色のPremium面と青のVerified面を交互に見せます。

rotateY 3D flipbackface-visibilityperspective
.flip__inner {
  transform-style: preserve-3d;
}
.flip__face {
  backface-visibility: hidden;
}
.flip__face--back {
  transform: rotateY(180deg);
}
.stage.is-demo .flip__inner {
  animation: flip $duration $easing infinite;
}
@keyframes flip {
  0%, 40% { transform: rotateY(0deg); }
  55%, 85% { transform: rotateY(180deg); }
  100% { transform: rotateY(360deg); }
}

09期限間近カウントダウンチップ

秒の桁の数字10個を縦に並べ、translateYで一段ずつ送ることで、機械式フリップカウンターのように数字がめくれます。

translateY steps(10)@keyframes tickoverflow: hidden window
.chip__digit {
  width: 18px; height: 26px;
  overflow: hidden;
}
.chip__digit-track span {
  height: 26px; line-height: 26px;
}
.stage.is-demo .chip__digit-track {
  animation: tick $duration $easing infinite;
}
@keyframes tick {
  0% { transform: translateY(0); }
  100% { transform: translateY(-260px); }
}

どこで壊れるか — 数字を文中に詰め込むと崩れます

カウントダウンチップの一の位の数字は、最初は周囲の文字と同じ行の中でfont-sizeだけを大きくして入れていました。すると数字がチップの外にはみ出し、背景の上に乗ってしまいました。原因は、チップがinline-flexで行の高さを周囲のテキストに合わせて決めており、overflow: hiddenがないと大きな文字がそのままチップの外側にはみ出してしまうことにあります。数字を固定サイズ(18×26px)の独立した箱に切り離し、チップ自体にもoverflow: hiddenを掛けたことで、数字は常にチップの中でだけ切り替わるようになりました。解凍時に聞かれるパスワードはcwww6ahbで、届いたファイル名のまま入力すると9つのフォルダがそのまま開きます。08番の3D回転バッジも同様の落とし穴があり、両面にbackface-visibility: hiddenを付け忘れると、回転中に裏面の文字が鏡写しのまま透けて見えます。

アクセシビリティ

9つともprefers-reduced-motion: reduceでアニメーションが止まり、最終状態のまま固定されます。01番のオンラインリングはリングが消えてドットだけが残り、07番の実績バッジは解除後の色のまま止まり、09番のカウントダウン数字もそれ以上は進みません。動きが止まっても色と形だけで状態が分かるように設計しています。設定方法はMDNのprefers-reduced-motionドキュメントにまとまっています。

FAQ

バッジの色は自由に変えられますか?

はい、ほとんどのデモはSCSS冒頭の$color一つを変えるだけで色が変わります。08番のプレミアム・認証バッジは例外で、両面それぞれのグラデーションを直す必要があります。ほかのバッジのアイデアはバッジデザインUI 9選でご覧いただけます。

削除できるタグチップにJavaScriptは必要ですか?

CSSだけでは要素の削除はできません。02番のタグチップにはクリックで実際に削除するバニラJSが10行ほど付いています。React版では同じ処理をuseStateフックで管理しています。

カウントダウンの数字は実際の時間を計測していますか?

いいえ、動きを見せるためのループで、実際の時計とは連動していません。本当に残り時間を数えるには、setIntervalで目標時刻との差を計算し、数字だけ差し替えます。制作の様子は紹介ページでご覧いただけます。

解凍パスワードを入力してください

パスワードはこの記事の本文の中にあります。読み進めると出てきます。