[Rails5] radio buttonをボタンにする


対象読者

radio buttonのデザインに辟易していて、
オリジナルにボタンを作りたいぜ!!って思ってる人

環境

rails 5.2.3
ruby 2.5.1

背景

カリキュラムでメルカリのクローンサイトを作っています。
その中で、ユーザーの評価機能を実装する際にhaml, scssの書き方でハマった

目的

仕上がりはこちら

拙い解説

下は最終的なhamlの記述(ボタン一個分)

new.html.haml
.evaluation
    .evaluation__container
      .evaluation__container__evaluate-box
        = f.radio_button :rating, "1", id:"evaluation__good", class: "evaluation__container__evaluate-box__radio-btn" 
        .evaluation__container__evaluate-box__good
          = f.label "良い", for:"evaluation__good", class: "evaluation__good" do
            .evaluation__container__evaluate-box__good__btn
              = fa_icon "smile-o"

こんな感じで書いて見ました。
f.radio_button [カラム名], [選択した時にカラムに入れたい値], id, class
f.label [ラベル名], for:[連動させたいradio buttonのid], class

完成scssはこちら

new.scss
 &__evaluate-box {
      margin:40px auto;
      width: 500px;
      display: flex;
      justify-content: space-around;

      &__radio-btn {
        &:checked + .evaluation__container__evaluate-box__good {
          border: 2px solid #ea352b;
        }
      }
      &__good {
        display: inline-block;
        height: 100px;
        width: 80px;
        border: 2px solid gray;
        border-radius: 4px;
        &__btn{
          font-size: 57px;
          text-align: center;
          color: #ea352b;
          i {
            &::after {
              display: block;
              content: '良い';
              font-size: 20px;
              color: black;
            }
          }
        }
      }

#evaluation__good {
  display: none;
}

labelのfor

labelに for をつけることで、radio buttonと連動?するようになる
今回だと、radio buttonのidと、labelのforに同じ名前を持たせればlabel要素をクリックして選択できるようになる。

radio buttonを非表示にする

今回、丸ぽちのラジオボタンは無くして、ただのボタンだけの表示にしたかったので、radio buttonのidを使用してdisplay: noneを書いて見えなくしています。classのevaluation_containerevaluate-box_radio-btnに記述しても大丈夫そうですが、ボタンが丸々なくなってしまったので、分けて記述して見ました。

ボタンを選択した時にcssを変える

ラジオボタンの場合、:checked をつければいいのはいろんな記事からわかったんだけど、どう書いていいのかわからなかった。ここが一番はまったところ。

:checkedを受けられるのはradio buttonであるはずなので、radio buttonを指定するクラスにつける必要がある。

今やりたいことは、ラジオボタンではなく、見た目が普通のボタンで、ラジオボタンを同じ働きを持たせること.
なので、ラジオボタンと連動させたlabelに、見た目の変更を記述する必要があります。
それがこの部分。

      &__radio-btn {
        &:checked + .evaluation__container__evaluate-box__good {
          border: 2px solid #ea352b;
        }

で、注意したいポイント
 + と (半角スペーす)ではえらく意味が違う

cssで
+は隣接セレクタで、兄弟要素、つまり同じ深さの要素に対して影響を与え
半角スペースは子孫セレクタで、、子孫要素、つまりインデントがより下がっている要素に対して影響を与えるということ

なので今回の書き方だと

radio-btnがcheckedされた時は、兄弟要素であるevaluationcontainer_evaluate-box_goodのborderを変えるよ

となります

fa-icon

gemで'font-awesome-rails'を入れてあるのでこのように記述するだけで、必要なアイコンが表示されます。
ただ、このgemだとfontawesome4で、
最新のfontawesome5には対応していないので、
これからやる方は'font-awesome-sass'を入れることをおすすめします
https://github.com/FortAwesome/font-awesome-sass

終わりに

誤った内容などありましたらご指摘いただけますと幸いです。

参考記事

クリックすると色が変わるアイコンをHTML/CSSで簡単に作る
ラジオボタンをCSSで異なる見た目にしてみたメモ