Webパーツ辞典

円形プログレスCircular progress

輪っかが時計回りに伸びて、どこまで進んだかを示す部品。真ん中に「72%」のように数字が入る。終わりが読めないときは輪が回る。

表示例

72%
アップロード
処理中

別名・英語表記

  • プログレスリング
  • 円形プログレスバー
  • 進捗リング
  • ドーナツ型の進捗
  • 丸い進捗表示
  • 円のプログレス
  • Circular progress

実装例

<div class="x-progress-circle">
  <div class="x-progress-circle__item">
    <div class="x-progress-circle__ring" role="progressbar" aria-labelledby="x-progress-circle-l1" aria-valuemin="0" aria-valuemax="100" aria-valuenow="72">
      <svg class="x-progress-circle__svg" viewBox="0 0 64 64" aria-hidden="true" focusable="false">
        <circle class="x-progress-circle__track" cx="32" cy="32" r="27"></circle>
        <circle class="x-progress-circle__bar" cx="32" cy="32" r="27" pathLength="100" stroke-dasharray="72 100"></circle>
      </svg>
      <span class="x-progress-circle__num">72%</span>
    </div>
    <span class="x-progress-circle__l" id="x-progress-circle-l1">アップロード</span>
  </div>
  <div class="x-progress-circle__item">
    <!-- 終わりが読めないときは aria-valuenow を付けない(不確定) -->
    <div class="x-progress-circle__ring" role="progressbar" aria-labelledby="x-progress-circle-l2">
      <svg class="x-progress-circle__svg x-progress-circle__svg--spin" viewBox="0 0 64 64" aria-hidden="true" focusable="false">
        <circle class="x-progress-circle__track" cx="32" cy="32" r="27"></circle>
        <circle class="x-progress-circle__bar" cx="32" cy="32" r="27" pathLength="100" stroke-dasharray="25 100"></circle>
      </svg>
    </div>
    <span class="x-progress-circle__l" id="x-progress-circle-l2">処理中</span>
  </div>
</div>

AIへの指示文

「円形プログレス(Circular progress)」を実装してください。

## これは何か
輪っかが時計回りに伸びて、どこまで進んだかを示す部品。真ん中に「72%」のように数字が入る。終わりが読めないときは輪が回る。

## 使いどころ
- アップロードや同期の進み具合を、限られた場所(アイコンの上・カードの角など)に出したいとき
- ダッシュボードで、達成率を数字と一緒に目立たせたいとき

## 実装の要件
- SVG の circle を2枚重ねる(下地の輪と進んだ分の輪)。進んだ分は pathLength="100" と stroke-dasharray="<値> 100" で描く
- SVG を -90度回して、12時の位置から伸ばす
- 不確定は短い弧を CSS の animation で回す
- プログレスバーと役目は同じで、細かい違いは読み取りにくい。横幅がとれるなら、長さを比べやすいプログレスバーを選ぶ
- ローディングスピナーは「待っている」ことだけを伝える。円形プログレスは、数字が分かるなら何%かを必ず出す
- 輪の長さだけでは何%か読み取れない。中央に数字を置く

## アクセシビリティの要件
- role="progressbar" に aria-valuenow / aria-valuemin / aria-valuemax と名前(aria-labelledby など)を付ける。SVG は aria-hidden="true"
- 終わりが読めないときは aria-valuenow を付けない。これで不確定の進捗として伝わる
- 回る動きは prefers-reduced-motion で止め、「処理中」の文字で状態を伝える
- 輪の色と下地の境目を、非テキストのコントラスト(3:1)以上にする

## 参考にする実装
この形を出発点にして、プロジェクトの命名規則・色・余白に合わせて調整してください。

```html
<div class="x-progress-circle">
  <div class="x-progress-circle__item">
    <div class="x-progress-circle__ring" role="progressbar" aria-labelledby="x-progress-circle-l1" aria-valuemin="0" aria-valuemax="100" aria-valuenow="72">
      <svg class="x-progress-circle__svg" viewBox="0 0 64 64" aria-hidden="true" focusable="false">
        <circle class="x-progress-circle__track" cx="32" cy="32" r="27"></circle>
        <circle class="x-progress-circle__bar" cx="32" cy="32" r="27" pathLength="100" stroke-dasharray="72 100"></circle>
      </svg>
      <span class="x-progress-circle__num">72%</span>
    </div>
    <span class="x-progress-circle__l" id="x-progress-circle-l1">アップロード</span>
  </div>
  <div class="x-progress-circle__item">
    <!-- 終わりが読めないときは aria-valuenow を付けない(不確定) -->
    <div class="x-progress-circle__ring" role="progressbar" aria-labelledby="x-progress-circle-l2">
      <svg class="x-progress-circle__svg x-progress-circle__svg--spin" viewBox="0 0 64 64" aria-hidden="true" focusable="false">
        <circle class="x-progress-circle__track" cx="32" cy="32" r="27"></circle>
        <circle class="x-progress-circle__bar" cx="32" cy="32" r="27" pathLength="100" stroke-dasharray="25 100"></circle>
      </svg>
    </div>
    <span class="x-progress-circle__l" id="x-progress-circle-l2">処理中</span>
  </div>
</div>
```

```css
/* 貼った先のリセットに頼らないよう、この部品の中だけ border-box にする */
.x-progress-circle,
.x-progress-circle *:not([class*="fa-"]),
.x-progress-circle *:not([class*="fa-"])::before,
.x-progress-circle *:not([class*="fa-"])::after {
  box-sizing: border-box;
  /* 貼った先の既定の書体に引きずられないようにする。書体が変わると
     文字の幅と高さが変わり、枠のサイズまでずれる */
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Hiragino Sans", "Noto Sans JP", "Yu Gothic UI", Meiryo, sans-serif;
}

.x-progress-circle {
  display: flex;
  gap: 28px;
  width: 240px;
  max-width: 100%;
}
.x-progress-circle__item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
}
.x-progress-circle__ring {
  position: relative;
  width: 88px;
  height: 88px;
}
.x-progress-circle__svg {
  display: block;
  width: 100%;
  height: 100%;
  /* 円の描き始めは右(3時)なので、上(12時)から始まるよう回す */
  transform: rotate(-90deg);
}
.x-progress-circle__track,
.x-progress-circle__bar {
  fill: none;
  stroke-width: 7;
}
.x-progress-circle__track {
  stroke: #cfd4dc;
}
.x-progress-circle__bar {
  stroke: #1d4ed8;
  stroke-linecap: round;
}
.x-progress-circle__num {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  color: #1b2028;
  font-size: 18px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.x-progress-circle__l {
  color: #4b5563;
  font-size: 13px;
  font-weight: 700;
}
.x-progress-circle__svg--spin {
  animation: x-progress-circle-turn 1s linear infinite;
}
@keyframes x-progress-circle-turn {
  from {
    transform: rotate(-90deg);
  }
  to {
    transform: rotate(270deg);
  }
}
/* 動きを減らす設定では回さない。「処理中」の文字で状態を伝える */
@media (prefers-reduced-motion: reduce) {
  .x-progress-circle__svg--spin {
    animation: none;
  }
}
```

## 出力の約束
- HTML と CSS を分けて出す。JavaScript が要るときは素の JavaScript で書き、UIフレームワークは使わない。
- 参考実装がアイコンに Font Awesome のクラスを使っている場合は、プロジェクトで使っているアイコンかインライン SVG に置き換えてよい。
- 上のアクセシビリティ要件を満たす。満たせない箇所があるときは、理由を添えて先に知らせる。
- 色・角丸・余白は既存のデザイントークンがあればそれを使う。無ければ CSS 変数として切り出す。

使いどころ

  • アップロードや同期の進み具合を、限られた場所(アイコンの上・カードの角など)に出したいとき
  • ダッシュボードで、達成率を数字と一緒に目立たせたいとき

注意点

  • プログレスバーと役目は同じで、細かい違いは読み取りにくい。横幅がとれるなら、長さを比べやすいプログレスバーを選ぶ
  • ローディングスピナーは「待っている」ことだけを伝える。円形プログレスは、数字が分かるなら何%かを必ず出す
  • 輪の長さだけでは何%か読み取れない。中央に数字を置く

アクセシビリティの要点

  • role="progressbar" に aria-valuenow / aria-valuemin / aria-valuemax と名前(aria-labelledby など)を付ける。SVG は aria-hidden="true"
  • 終わりが読めないときは aria-valuenow を付けない。これで不確定の進捗として伝わる
  • 回る動きは prefers-reduced-motion で止め、「処理中」の文字で状態を伝える
  • 輪の色と下地の境目を、非テキストのコントラスト(3:1)以上にする

作るときに使えるツール

見分け方

関連するパーツ