Star Rating — 評価スター(レーティング)

フォーム入力 初級

このコンポーネントについて

ユーザーが5段階で評価を入力できる星形レーティングコンポーネントです。 ECサイトの商品レビュー・アプリストアの評価・アンケートフォームなど、段階的な評価入力が必要な場面で広く使われます。

星にカーソルを合わせると評価値がプレビューされ、クリックで確定します。 クリアボタンで選択を解除できるため、入力ミスにも対応しやすい設計です。

  • ホバープレビュー — カーソルを合わせた星までが金色に光り、評価値を仮表示する
  • クリック確定 — 任意の星をクリックして評価を確定する
  • クリア機能 — クリアボタンで選択した評価をリセットできる
  • 評価ラベル表示 — 確定した評価を「N点を選択中」のテキストで補足表示する

実装のポイント・注意点

星の表示には Unicode の「★」(U+2605)を使用し、CSS の color 切り替えで金色・グレーを表現します。 画像や SVG が不要なため、コードが非常にシンプルになります。

ホバー・クリックのイベントは各 .star 要素に個別に付けるのではなく、 親の .star-rating コンテナに1つずつ付けて event.target.closest('.star') でターゲットを特定します(イベント委譲)。 要素数が増えても処理が変わらず、メモリ効率も良くなります。

状態管理のポイントは「確定済みの評価(currentRating)」を変数1つで持つことです。 ホバー時は仮のクラスを付けて見せかけだけ変え、マウスが外れたら currentRating に基づいて元の状態に戻します。 クリアボタンの disabled 属性は clearBtn.disabled = true / false で切り替え、 未選択時はボタンを操作不能にしてUXを改善します。

HTML・CSS・バニラJavaScriptのみで実装しており、フレームワーク不要でコピペすぐに動きます。

デモ

未選択

サンプルソース

3つのファイルを同じフォルダに保存し、index.html をブラウザで開くとすぐに動作確認できます。
ファイル名:index.html / style.css / script.js — 保存時の文字コードは UTF-8 を指定してください(Shift-JISだと日本語が文字化けします)。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>評価スター サンプル</title>
  <link rel="stylesheet" href="./style.css">
</head>
<body>

<div class="star-rating-wrapper">
  <!-- data-value 属性で各星の評価値を管理する -->
  <div class="star-rating" id="starRating">
    <span class="star" data-value="1">★</span>
    <span class="star" data-value="2">★</span>
    <span class="star" data-value="3">★</span>
    <span class="star" data-value="4">★</span>
    <span class="star" data-value="5">★</span>
  </div>
  <p class="star-rating-label" id="starRatingLabel">未選択</p>
  <button class="star-clear-btn" id="starClearBtn" disabled>クリア</button>
</div>

<script src="./script.js"></script>
</body>
</html>
/* === 評価スター ===
   色を変えたいときは :root の変数を書き換えるだけでOKです */
:root {
  --color-star-empty:  #D0D7E0; /* 未選択・未ホバー時の星の色 */
  --color-star-filled: #F5C518; /* 選択済み・ホバー中の星の色(金色) */
  --color-muted:       #8A9BAE; /* 「未選択」ラベルの色 */
  --color-border:      #D0D7E0; /* クリアボタンのボーダー色 */
}

*, *::before, *::after { box-sizing: border-box; }
body {
  font-family: sans-serif;
  padding: 24px;
  max-width: 400px;
  margin: 0 auto;
}

.star-rating-wrapper {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
}

/* 星を横並びにして、コンテナへのイベント委譲でまとめて制御する */
.star-rating {
  display: flex;
  gap: 4px;
  cursor: pointer;
}

.star {
  font-size: 40px;
  color: var(--color-star-empty);
  user-select: none;
  line-height: 1;
  transition: color 0.1s;
}

/* filled: 確定済みの評価 / hover: ホバー中の仮プレビュー */
.star.filled,
.star.hover {
  color: var(--color-star-filled);
}

.star-rating-label {
  font-size: 14px;
  color: var(--color-muted);
  margin: 0;
}

.star-clear-btn {
  padding: 6px 20px;
  font-size: 13px;
  color: #5A6A7A;
  background: #fff;
  border: 1.5px solid var(--color-border);
  border-radius: 6px;
  cursor: pointer;
  font-family: sans-serif;
  transition: background 0.15s, border-color 0.15s;
}

.star-clear-btn:hover:not(:disabled) {
  background: #F4F6F9;
  border-color: #9AA5B4;
}

/* 未選択時はクリアボタンを薄くして操作不能にする */
.star-clear-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* スマホ対応 */
@media (max-width: 480px) {
  body { padding: 16px; }
  .star { font-size: 32px; }
}
var starContainer = document.getElementById('starRating');
var stars         = document.querySelectorAll('.star');
var label         = document.getElementById('starRatingLabel');
var clearBtn      = document.getElementById('starClearBtn');

// 確定済みの評価(0 = 未選択)
var currentRating = 0;

// ホバー: その星までを金色にプレビューする(イベント委譲)
starContainer.addEventListener('mouseover', function (e) {
  var star = e.target.closest('.star');
  if (!star) return;
  updateStars(parseInt(star.dataset.value, 10), true);
});

// ホバー解除: 確定済み評価の表示に戻す
starContainer.addEventListener('mouseleave', function () {
  updateStars(currentRating, false);
});

// クリック: 評価を確定して currentRating に保存する
starContainer.addEventListener('click', function (e) {
  var star = e.target.closest('.star');
  if (!star) return;
  currentRating = parseInt(star.dataset.value, 10);
  updateStars(currentRating, false);
  // textContent で評価ラベルを更新する(innerHTML は使わない)
  label.textContent = currentRating + '点を選択中';
  clearBtn.disabled = false;
});

// クリアボタンはリセットと同じ処理
clearBtn.addEventListener('click', resetRating);

// 全星のクラスを更新する共通関数
function updateStars(value, isHover) {
  stars.forEach(function (star) {
    var starValue = parseInt(star.dataset.value, 10);
    star.classList.remove('filled', 'hover');
    if (starValue <= value) {
      star.classList.add(isHover ? 'hover' : 'filled');
    }
  });
}

function resetRating() {
  currentRating = 0;
  updateStars(0, false);
  label.textContent = '未選択';
  clearBtn.disabled = true;
}

// ページのリセットボタン(demo-controls)からも呼べるようにする
function resetDemo() {
  resetRating();
}

AI用プロンプト

以下のプロンプトをコピーしてAIに渡すと、同様のコンポーネントを生成できます。

ChatGPTやClaudeにこのプロンプトを渡すと、同様のコンポーネントをゼロから生成・カスタマイズできます。星の数の変更や色のカスタマイズなど、要件を追記して使うのがおすすめです。

※ このプロンプトを使ってもデモとまったく同じ動作にならない場合があります。AIの解釈や生成タイミングによって差が出ることをご了承ください。

💡 jQuery・Vue・React など特定のライブラリで実装したい場合は、プロンプトの末尾に「〇〇を使って実装してください」と追記してください。

# 5つ星レーティング入力UI 作成依頼

## 概要
ユーザーが1〜5の段階評価をクリックで入力できる星形レーティングUIを作成してください。

## 要件
- 星を5つ横並びに表示する
- カーソルを合わせると、その星までが金色にハイライトする(ホバープレビュー)
- クリックした星の値で評価が確定し、確定後は星がその状態で固定される
- 確定した評価を「N点を選択中」のテキストで表示する
- クリアボタンをクリックすると評価がリセットされる
- クリアボタンは未選択のとき非活性(disabled)にする

## 技術仕様
- HTML / CSS / バニラJavaScript で実装
- 外部ライブラリ:なし
- レスポンシブ対応:必要

## 動作詳細
JavaScriptでcurrentRating(整数)を管理し、mouseover時はホバープレビュー、mouseleave時は確定状態に戻す2段階の星ハイライトを実装します。星のデザインは「★」文字のCSSカラー切り替えで実現します。イベントは親コンテナに委譲し、event.target.closest('.star')でターゲットの星を特定してください。

## 出力形式
HTML・CSS・JavaScriptを分けて出力してください。
各ファイルは単独でコピー&ペーストして使えるよう記述してください。