2020-01-16 更新

レーティング用に星形のマークを表示する方法

レーティング用に星形のマークを表示したいことが時々あって、いくつか方法があるようなのでメモしておきます。

目次

  • CSSのみで表示
  • Glyphiconsで表示
  • jQueryを使って表示
  • 参考リンク
  • [2020年1月16日 追記] CSSのみでレーティングの入力

CSSのみで表示

HTML


<div class="star-rating">
  <div class="star-rating-item" style="width:50%;"></div>
</div>

CSS


.star-rating {
  position: relative;
  display:inline-block;
  font-size: 25px;
}
.star-rating .star-rating-item{
  position:absolute;
  overflow: hidden;
}
.star-rating .star-rating-item:before{
  content:"★★★★★";
  color: #ffcc33;
}
.star-rating:after {
  content:"★★★★★";
  color: #ccc;
}

widthプロパティでattr()が利用できるようになれば、もうちょっとスッキリしたコードになりそうです。

Glyphiconsで表示

Bootstrapを利用しているサイトであれば、デフォルトでGlyphiconsが利用できます。

HTML


<div class="star-rating-icon">
  <span class="glyphicon glyphicon-star"></span>
  <span class="glyphicon glyphicon-star"></span>
  <span class="glyphicon glyphicon-star"></span>
  <span class="glyphicon glyphicon-star-empty"></span>
  <span class="glyphicon glyphicon-star-empty"></span>
</div>

CSS


.star-rating-icon{
  font-size: 20px;
}
.star-rating-icon .glyphicon-star{
  color: #ffcc33;
}

星マークを完全に塗りつぶさないようにするには、「CSSのみで表示」でやっているような方法にするしかなさそうです。

jQueryを使って表示

「CSSでのみ表示」をベースに属性に設定した「星の最大個数」や「レート」をjQueryで読み取って設置する方法です。

HTML


<div class="star-rating-js" data-rating-value="50" data-rating-max="5"></div>

CSS


.star-rating-js{
  position: relative;
  display:inline-block;
  font-size: 25px;
}
.star-rating-js .rating-front{
  position:absolute;
  overflow: hidden;
  color: #ffcc33;
}
.star-rating-js .rating-back{
  color: #ccc;
}

JavaScript


$(".star-rating-js").each(function(i, e){
    var el = $(e);
    var rateMark = el.data("rating-mark") ? el.data("rating-mark") : "◆";
    var rateStr = Array(el.data("rating-max")+1).join(rateMark);
    el.append($("<div>").addClass("rating-front").html(rateStr).css("width", el.data("rating-value") + "%"));
    el.append($("<div>").addClass("rating-back").html(rateStr));
});

参考リンク

[2020年1月16日 追記] CSSのみでレーティングの入力

レーティングは表示だけであればCSSのみで簡単にでき、入力に関してはJavaScriptを使わないと実装できないと思っていましたが、CSSのみで入力を実装する方法がありました。

以下は参考にした記事のコード(ほとんどそのまま)になります。参考リンクを掲載したかったのですが、しばらく時間が経っていて見つけられませんでした。(見つけたらURL貼っておきます)

HTML


<div class="rating">
  <input class="rating__input hidden--visually" type="radio" id="5-star" name="rating" value="5" required />
  <label class="rating__label" for="5-star" title="5 out of 5 rating">
    <span class="rating__icon"></span>
    <span class="hidden--visually">5 out of 5 rating</span>
  </label>

  <input class="rating__input hidden--visually" type="radio" id="4-star" name="rating" value="4" />
  <label class="rating__label" for="4-star" title="4 out of 5 rating">
    <span class="rating__icon"></span>
    <span class="hidden--visually">4 out of 5 rating</span>
  </label>

  <input class="rating__input hidden--visually" type="radio" id="3-star" name="rating" value="3" />
  <label class="rating__label" for="3-star" title="3 out of 5 rating">
    <span class="rating__icon"></span>
    <span class="hidden--visually">3 out of 5 rating</span>
  </label>

  <input class="rating__input hidden--visually" type="radio" id="2-star" name="rating" value="2" />
  <label class="rating__label" for="2-star" title="2 out of 5 rating">
    <span class="rating__icon"></span>
    <span class="hidden--visually">2 out of 5 rating</span>
  </label>

  <input class="rating__input hidden--visually" type="radio" id="1-star" name="rating" value="1" />
  <label class="rating__label" for="1-star" title="1 out of 5 rating">
    <span class="rating__icon"></span>
    <span class="hidden--visually">1 out of 5 rating</span>
  </label>
</div>

CSS


.rating {
  display: inline-flex;
  flex-direction: row-reverse;
}

.hidden--visually {
    border: 0;
    clip: rect(1px 1px 1px 1px);
    clip: rect(1px, 1px, 1px, 1px);
    height: 1px;
    margin: -1px;
    overflow: hidden;
    padding: 0;
    position: absolute;
    width: 1px;
}

.rating__label {
  cursor: pointer;
  color: gray;
  padding-left: 0.25rem;
  padding-right: 0.25rem;
}

.rating__icon::before {
  content: "★";
}

.rating__input:hover ~ .rating__label {
  color: lightgray;
}

.rating__input:checked ~ .rating__label {
  color: goldenrod;
}

body {
  text-align: center;
  font-size: 4rem;
  padding: 4rem 2rem;
}

上記コードのポイントは以下の通り。

  • ラジオボタン(input type="radio")とラベル(label)を連動(for="ラジオボタンのID")させる。
  • ラジオボタンを非表示(overflow: hidden)にして、ラベルで表示・入力を操作。
  • レーティングの星マークはHTML上では値の大きい順に並べて、CSSの「flex-direction: row-reverse」で画面上は小さい順で表示。
  • 入力した星とそれよりも値が低い星の表示を切り替えるためにCSS3のセレクタである「~」を使用。

最後に書いたポイントのCSS3のセレクタ「~」を使っている点がこちらのコードの最大のポイントで、「~」は該当する要素とそれ以降に存在する同じ階層の要素が対象となるセレクタです。

なぜHTML上で星マークを逆に並べていたのか、その理由がこれになります。

動作確認はこちら

CSS】関連記事