GODRICH

태그 UI 디자인 9종 — 상태·우선순위·인증 배지 코드

태그 UI 디자인은 상태·카테고리·우선순위 같은 정보를 작은 알약이나 칩 모양으로 압축해 보여주는 장식이다. 온라인 점 하나, 우선순위 색 하나만 봐도 상태를 바로 알 수 있고, 움직임을 더하면 그대로 붙여서 훨씬 눈에 띄게 만들 수 있다. 태그 UI 디자인 9가지를 모았다.

자동 재생 · 눌러서 해당 항목으로 · 전부 한 zip

아홉 개는 인기순이 아니라 화면을 쓰는 사람이 실제로 마주치는 순서로 놓았다. 로그인하면 먼저 팀원의 온라인 상태(01)를 보고, 관심사 태그를 직접 고르거나 지우고(02), 할 일에 우선순위(03)를 매긴다. 둘러보다 세일 리본(04)을 만나고 새 알림(05)을 받으며, 프로필에는 기술 스택(06)과 방금 딴 업적 배지(07), 등급을 증명하는 인증 배지(08)가 쌓이고, 마지막엔 곧 끝나는 쿠폰 만료(09)가 남는다.

01상태 표시 배지 (온라인·자리비움·다른 용무·오프라인)

온라인 점 뒤에 숨은 링이 opacityscale 로 한 번씩 퍼져나가고, 나머지 세 상태는 색만 다른 채 멈춰 있어 온라인만 눈에 띈다.

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제거 버튼 달린 태그 칩

칩의 × 버튼을 누르면 scale·opacity 로 줄어들며 실제로 사라지고, 데모에서는 같은 동작을 한 칩이 스스로 반복한다.

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우선순위 라벨 배지 (낮음·보통·높음·긴급)

긴급 라벨만 opacity·scale 로 깜빡여, 색만 다른 낮음·보통·높음 사이에서 가장 먼저 눈에 띄게 만든다.

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 로 두 번 빠르게 튀어, 메시지 두 개가 막 도착한 리듬을 만든다.

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기술 스택 태그 클라우드

여섯 개 스킬 태그가 opacity·translateY 로 순서대로 떠올랐다 사라지길 반복해, 지연값만으로 물결치는 등장을 만든다.

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); }
}

어디서 깨지는가 — 숫자 칩은 줄 안에 박아 넣으면 깨진다

09번 카운트다운 칩의 초 자리 숫자를 처음엔 본문 글자와 같은 줄 안에 font-size 만 키워서 넣었더니, 숫자가 칩 밖으로 삐져나와 배경 위에 걸쳐 보였다. 원인은 inline-flex 인 칩이 줄 높이를 주변 텍스트 기준으로 계산하는데, 그 안의 큰 글자가 줄 바깥으로 넘치면서 overflow: hidden 이 없는 칩 테두리를 그냥 지나쳐 버린 것이다. 숫자를 가로세로 고정 크기(18×26px)의 독립된 박스로 떼어내고 칩 자체에도 overflow: hidden 을 걸자 숫자가 항상 칩 안에서만 넘어갔다. 압축을 풀 때 묻는 비밀번호는 cwww6ahb 이고, 받은 파일명 그대로 입력하면 아홉 개 폴더가 그대로 열린다. 08번 배지처럼 rotateY 로 회전하는 요소는 backface-visibility: hidden 을 앞뒤 두 면 모두에 넣지 않으면, 회전 중 뒷면 글자가 거울처럼 뒤집힌 채 비쳐 보인다.

접근성

아홉 개 전부 prefers-reduced-motion: reduce 에서 애니메이션이 꺼지고 마지막 상태로 고정된다. 01번 온라인 링은 고리 없이 점만 남고, 07번 업적 배지는 잠금이 풀린 색 그대로 멈추며, 09번 카운트다운 숫자도 더 넘어가지 않고 멈춘다. 링·점·리본 모두 색과 모양만으로 상태를 구분할 수 있게 처음부터 설계했다. 자세한 설정법은 MDN 의 prefers-reduced-motion 문서 에 있다.

FAQ

상태 배지 색은 마음대로 바꿔도 되나요?

네, 대부분 SCSS 맨 위 $color 하나만 바꾸면 된다. 08번 프리미엄·인증 배지처럼 두 면이 각각 다른 색을 쓰는 항목은 두 면의 그라데이션을 각각 고쳐야 한다. 더 많은 배지·태그 아이디어는 뱃지 디자인 UI 9종 에서 볼 수 있다.

자바스크립트 없이 태그 제거 칩을 써도 되나요?

CSS 애니메이션만으로는 실제 제거는 안 된다. 02번 칩은 클릭하면 요소를 지우는 바닐라 JS 10줄이 함께 있어야 진짜로 동작한다. React 버전은 같은 동작을 useState 훅 두 개로 옮겼다.

카운트다운 숫자는 실제 초를 세나요?

이 데모는 움직임을 보여주기 위한 루프라 실제 시계와 연결돼 있지 않다. 진짜 남은 시간을 세려면 setInterval 로 목표 시각과의 차이를 계산해 숫자만 바꿔 끼우면 된다. 만드는 과정은 소개 페이지 에서 더 볼 수 있다.

압축 비밀번호를 입력하세요

비밀번호는 이 글 본문 안에 있습니다. 읽다 보면 나옵니다.