CSSだけで星のレーティング【簡単】
公開日:こんにちは、ゆきまるです。
Webの仕事をやっていると、「HTML/CSSだけで星5つのレーティングを実装しなきゃっ!」ってときが、たまにありませんか?
僕はないです。
今回は、JavaScriptなしで星のレーティングを実装する方法を説明していきます。
星のレーティングのデモ
デモはこんな感じです。
1~5まで選択出来て、デフォルトで1が選択された状態にしています。input
のchecked
を変えれば変更できます。
ちゃんとform
として構成しているので、使い勝手はいいと思いますよ。
(actionとかnameとかは各自でカスタマイズしてください。)
See the Pen star5-rating by ゆきまる (@yukimaru-org) on CodePen.
星のレーティングのソースコード
HTML
<form>
<div class="rating">
<input id="rating1" type="radio" name="rating" value="1" checked>
<label for="rating1">★</label>
<input id="rating2" type="radio" name="rating" value="2">
<label for="rating2">★</label>
<input id="rating3" type="radio" name="rating" value="3">
<label for="rating3">★</label>
<input id="rating4" type="radio" name="rating" value="4">
<label for="rating4">★</label>
<input id="rating5" type="radio" name="rating" value="5">
<label for="rating5">★</label>
</div>
</form>
CSS
.rating {
line-height: 1;
color: gold;
font-size: 24px;
}
.rating input {
position: absolute;
opacity: 0;
pointer-events: none;
}
.rating label {
display: inline-block;
}
.rating input:focus + label {
outline: 1px solid currentColor;
}
.rating input:checked + label ~ label {
color: grey;
}
HTMLとCSSだけで実装するために
星の表現の仕方
まず星の表現ですが、普通にテキストでできます。
input
の見かけを変えるのは大変なので、label
に★を入れて、input
は見えないようにします。
見えないようにする方法なのですが、display: none
やvisibility: hidden
を指定してしまうと、フォーカスをあてることができなくなるため、
- position: absolute;(レイアウトのフローから消す)
- opacity: 0;(視覚的に消す)
- pointer-events: none;(クリックやタップできないように)
上記3つのプロパティをinput
に指定しておきましょう。
label
はfor
属性でinput
と紐ずけられており、label
をクリックすることで、対応するinput
が選択状態になります。
星はテキストでなくとも、FontAwesomeなどのアイコンを入れたり、CSSでスタイルを付けたりすることもできるでしょう。
色の変化の表現の仕方
CSSだけで色を切り替える方法は以下。
- ラベルはデフォルトで黄色
- 選択されたラベルより後ろのラベルはグレー
簡単ですね。
ソースコードでは、1つ目のinput
にchecked
を指定していますが、お好みで変更してください。
フォーカス時のCSS
input
にはフォーカス時のCSSがブラウザごとに標準で設定されているでしょうが、今回はinput
は見えないようにして、label
で表現しているので、
自分でlabel
にフォーカス時のCSSを設定しておくのが望ましいでしょう。
これに関係しているのが以下のコードです。
.rating label {
display: inline-block;
}
.rating input:focus + label {
outline: 1px solid currentColor;
}
まずlabel
にdisplay: inline-block
を指定しているのは、ボックスの大きさを整えるためです。
label
はinline
のままだとなぜか縦長になってしまいフォーカス時の見た目が不格好です。
display: inline-block
を指定することで、IE、FireFox、Chromeでは正方形になってくれます。(Edgeはどうしても縦長のままで対処方法不明)
そして、フォーカスされたlabel
にはoutline
を付けています。色はお好みで。
セレクタの解説【補足】
「+
」と「~
」のセレクタを使っています。見慣れない方のために少し補足しておきましょう。
- +
-
1人目の弟を対象とするセレクタです。2人目以降の弟は対象外です。
自分が男5人兄弟の2番目だとしたら、3番目のことです。 - ~
-
弟全員を対象とするセレクタです。
自分が男5人兄弟の2番目だとしたら、3番目と4番目と5番目のことです。
ちなみに、セレクタで「1人目の弟」や「弟全員」を対象とすることは今言ったように可能ですが、
「親」や「兄」を対象とすることは、たぶんCSSだけでは不可能です。