【Rails5】ドロップダウンリスト(ハンバーガーメニュー）の実装（haml,scss編）〜メルカリクローンサイトの作成

#背景
カリキュラムの過程でご存知メルカリのクローンサイトを作りました。
その際に、ヘッダーメニューにあるドロップダウンリスト（ハンバーガーメニュー？）を実装したのでその記録です。

仕上がりはこんな感じです。
[![Image from Gyazo](https://i.gyazo.com/4982d9600afc79ea6ada81f450302960.gif)](https://gyazo.com/4982d9600afc79ea6ada81f450302960)

今回の実装ではカテゴリー名をDBから持ってきて、
その値をcollectionを使ってrenderにて表示させています。詳しくはこちらにまとめましたのでよかったらどうぞ。
[【Rails5】ドロップダウンリストの実装（コントローラー編）メルカリクローンサイトの作成](https://qiita.com/pharma_tech3/items/8d8a10dd8229d0f0847e)


#対象となる読者
CSSだけを使ってドロップダウンリストを実装したいよ〜って方
いつもhamlとsassで書いてるからhtml,cssだとちょっとわかんないなーって方


#要はdisplay: noneとかで隠して、hoverで出せばOK
まずは何個か参考記事を検索して読んでみましょう。
[CSSで作ったドロップダウンメニューのドロップの動きいろいろ](http://weboook.blog22.fc2.com/blog-entry-408.html)
[【CSS】CSSだけで作るドロップダウンメニュー（多階層）](https://webdesignday.jp/inspiration/technique/css/5793/)

他にも色々な記事があるけど、まぁだいたいこのあたりを読むと、display:noneとかvisibilty:hiddenとかoverflow:hiddenで要素を隠して、隠した要素をhoverした時に変更して出現させているってわかりますね。

記事を参照にする時に大事だなって思うのは、
**「その実装で、絶対に外せないポイントは何か？」**
**「いろんな記事で共通することは何か？」**
を探すこと。

結局、記事を書いた人の背景とか環境と、自分が今作っている環境って同じじゃないし、
コピペしても、他のファイルの要素が影響したりすることもあって、
まぁ一発でうまく行くことってない。

だから複数の記事を参考にして、その要点を抽象化して抜き出すってことが大事。（自戒も込めて残しとこ）

#仕上がりコード

```_header.html.haml
    .header__menu-box
      .header__menu-box--left
        %ul
          %li.header__menu-box--left__category
            = link_to category_index_path do
              = fa_icon "list-ul", class: 'header__menu-box--left__icon'
              カテゴリーから探す
            %ul.header__menu-box--left__parents -#親カテゴリの大枠
              %li.header__menu-box--left__parents__parent　-#親カテゴリの中身
                = link_to "レディース", category_path(id: 1)
                %ul.header__menu-box--left__children -#子カテゴリの大枠
                  = render partial: "products/header_child", collection: @category_children1, as: "category"

　　　　　　　　　　　-#以下は"_header_child.html.haml"で切り出す部分
　　　　　　　　　　　%li.header__menu-box--left__children__child -#子カテゴリの中身
  　　　　　　　　　　　= link_to "#{category.category}", category_path(id: category.id)
  　　　　　　　　　　　%ul.header__menu-box--left__grand-children -#孫カテゴリーの大枠
    　　　　　　　　　　　= render partial: "products/header_grand-child", collection: category.children, as: "children"

                      -#以下は"_header_grand-child.html.haml"で切り出す部分
　　　　　　　　　　　　　　%li.header__menu-box--left__grand-children__grand-child -#孫カテゴリーの中身
 　　　　　　　　　　　　　　 = link_to "#{children.category}", category_path(id: children)

              %li.header__menu-box--left__parents__parent
                = link_to "メンズ", category_path(id: 2)
                %ul.header__menu-box--left__children
                  = render partial: "products/header_child", collection: @category_children2, as: "category"

```
リストの中にリストをネストさせ、さらにリストをさせることで孫の階層までを作っています。

```haml

%ul親
  %li親1
  %ul子
    %li子1
    %ul孫
      %li孫1
      %li孫2
      %li孫3
      %li孫4
    %li子2
    %ul孫
      %li孫1
      %li孫2
      %li孫3
      %li孫4

　%li親2
  %ul子
    %li子1
    %ul孫
      %li孫1
      %li孫2
      %li孫3
      %li孫4
    %li子2
    %ul孫
      %li孫1
      %li孫2
      %li孫3
      %li孫4


```



肝心のCSSはこちら
今回は特にアニメーションとか不要だったので、display:noneで隠して、
hoverした時にdisplay:blockにすることで出現するように実装しました。

実装の際は最初からdisplay:noneをかけずに、とりあえずblockと書いておいて、
absoluteの位置関係とかスタイルの調整をして、
最後にhoverした時の挙動を実装するって順番でやると
作業しやすかったです。


```_header.scss

中略

  .header__menu-box {
    height: 46px;
    margin: 8px 0 0;
    display: flex;
    align-items: center;
    justify-content: space-between;

    &--left {
      display: flex;
      justify-content: space-between;
      &__icon {
        color: $main_red;
        font-size: 12px;
        margin-right: 4px;
      }
      ul {
        li.header__menu-box--left__category {
          font-weight: bold;
          font-size:14px;
          margin-right: 10px;
          height: 55px;
          line-height: 46px;
          position: relative;
          &:hover {
            color: $main_blue;
            ul {
              li {
                display: block;
                height: 44px;
              }
            }
          }
          ul {
            position: absolute;
            top: 44px;
            z-index: 1000;
            font-weight: normal;
            li {
              width: 220px;
              height: 0;
              display: none;
              background-color: white;
              &:hover {
                color: $main_blue;
                .header__menu-box--left__children {
                  &__child {
                    display: block;
                    height: 30px;
                  }
                }
              }
              a {
                @include dropMenu_aTag(44px);
                &:hover {
                  background-color: $main_red;
                  color: white;
                }
              }
              .header__menu-box--left__children {
                position: absolute;
                top: 0;
                left: 220px;
                z-index: 1000;
                height: 616px;
                background-color: white;
                border-right: 1px solid $main_gray;
                &__child {
                  width: 220px;
                  height: 0;
                  display: none;
                  background-color: white;
                  &:hover {
                    color: $main_blue;
                    .header__menu-box--left__grand-children {
                      &__grand-child {
                        display: block;
                        height: 30px;
                      }
                    }
                  }
                  a {
                    @include dropMenu_aTag(30px);
                    font-size: 14px;
                    &:hover {
                      background-color: #f3f3f3;
                    }
                  }
                  .header__menu-box--left__grand-children {
                    position: absolute;
                    top: 0;
                    left: 220px;
                    z-index: 1000;
                    height: 616px;
                    background-color: white;
                    border-right: 1px solid $main_gray;
    
                    &__grand-child {
                      width: 300px;
                      height: 0;
                      display: none;
                      background-color: white;
                      a {
                        @include dropMenu_aTag(30px);
                        font-size: 14px;
                        &:hover {
                          background-color: #f3f3f3;
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }

中略
```

@include　dropMenu_aTag(30px);はmixinの呼び出し
$main_blueは変数の呼び出しです。

sassの書き方は他の記事をご参照くださいませ。

要点だけ抜き出すとこんな感じ。
これを階層分ネストを繰り返し、作りました。

```scss
     ul {
        li.header__menu-box--left__category {
          position: relative;　子要素のabsoluteのための記述
          &:hover {
　　　　　　　以下はマウスオーバーした時の挙動
            color: $main_blue;
            ul {
              li {
　　　　　　　　　　出現させる記述をかく
                display: block;
                height: 44px;
              }
            }
          }
          ul {
            出現した時の位置をかく
            position: absolute;
            top: 44px;
            z-index: 1000;
            li {
              隠す記述をかく。上記のhoverで出現させる。
              height: 0;
              display: none;
             
```

はじめにも書きましたが、これをこのままコピペしても、多分うまくいかないと思います。
要点を掴んで適応させてくださいね

では。