flexboxとgridを併用してレイアウトを作る

# はじめに

railsアプリの基本機能が実装できて
さあ、UIブラッシュアップに着手しよ！と思った時に
「レイアウトどうすればいいか分からん…」という状況になった。

webデザインに関する情報は、ネット・書籍でも豊富にあったが
それゆえに情報整理ができなくなってしまった。

ただ、最終的に私が個人的に合う
レイアウト作成法に出会えたので、まとめておく。



# Flexbox or Grid？

レイアウトを構想している初期段階は
自分のアプリには、`flexbox`か`grid`の`どちらを使うのが良いのだろう…`
と考えていた。

デザインの主流は、flexboxという記事や参考動画も多かったので
基本的にはflexboxを使うべき！
gridは表示させるコンテンツ量が多くなった時に
効果的な応用技だろ！くらいに思っていた。
（楽天やAmazonなどの商品ラインナップを表示させるみたいなイメージ）

でも、整理がしやすいように`両方の技術を併用する`のも
個人的には有りではないかと思う。

# 役割の違い

情報収集していく過程で
両者には`それぞれ役割に違いがある`ことが分かった。
お互いの強みを適材適所で使い分けるのが良いということらしい。

ざっくり違いを整理すると

* flexbox : 1次元のレイアウト

　　　例）対象グループ内のブロック要素を
　　　　　・縦方向に中央揃えにする
　　　　　・横方向に対してコンテンツの間に均一に空白を空ける

* grid    : 2次元のレイアウト

　　　例）対象グループ内のブロック要素を
　　　　　横列の１列目150px、２列目300px、３列目150px ...
　　　　　縦列の１列目150px、２列目300px、３列目150px ...　で表示させる
　
ということかなーと解釈。




# 考えたレイアウト

前置きを前提に、私が勝手に分かりやすい思うレイアウトは

1. まず、`大枠をGridで作る`
2. その後、`各ブロック要素をFlexboxで整える`

となった。



# 実装

まず、application.html.erbでレイアウトの基本構成を整える。
（ヘッダー、ナビゲーションバー、メイン、フッターを
renderで別ファイルを参照する構成にしている。）

```app/views/layouts/application.html.erb
〜〜省略〜〜

<body>
  <header>
    <%= render 'layouts/header' %>
  </header>

  <nav>
    <%= render 'layouts/navigation' %>
  </nav>

  <main>
    <%= yield %>
  </main>

  <footer>
    <%= render 'layouts/footer' %>
  </footer>
</body>
```

次に、基本構成の中の_header.html.erbは

１、ロゴ
２、ログイン・ログアウト・サインインの各リンク

といった２つのブロック要素で構成しておく。

```app/views/layouts/_header.html.erb

<div>
 <%= link_to image_tag('logo.png', id: 'logo', alt:"〇〇"), "サイトURL"%>
</div>


<div>
 <ul>
   <% if logged_in? %>
     <li><%= link_to "ログアウト", logout_path, method: :delete %></li>
   <% else %>
     <li><%= link_to "ログイン", login_path %></li>
     <li><%= link_to "サインイン", signup_path %></li>
   <% end %>
 </ul>
</div>

```

最後に、custom.scssでデザインを整える。

まず、`Gridで`アウトラインを構成する。

１、display: grid;を宣言して
　　grid-template:で縦と横の幅を決定して
　　視覚的にアウトラインを構成する。

２、grid-area: ブロック要素;で
　　application.html.erbで構成したレイアウト（header、main、nav、footer）に
　　grid表内で命名した名前と紐付ける。

続いて、`Flexboxで`ヘッダー内の
ブロック要素の並び方を変更する。

デフォルトではブロック要素が`縦並び`になるが、
`ロゴは左側、各リンクは右側`という具合に`横並びに`表示されるように変更する。

display: flex;を宣言して
justify-content: space-between;で
ブロック要素の間にスペースが空くように設定する。
`（※header{}内にコード記載）`

```app/assets/stylesheets/custom.scss

body{
 display: grid;
 grid-template:
  "..... ...... ...... ...... ...... ...... .....  " auto
  "header header header header header header header" 150px
  "..... ...... ...... ...... ...... ...... .....  " 10px
  "..... navbar ...... main   main   main   .....  " 200px
  "..... ...... ...... main   main   main   .....  " 10px
  "..... footer ...... main   main   main   .....  " 150px
  "..... ...... ...... main   main   main   .....  " 1fr
  "..... ...... ...... ...... ...... ...... .....  " auto
   /10px  200px  10px   1fr    10px   200px  auto;

 header{
  grid-area: header;
  display: flex;
  justify-content: space-between;
 }
  
 main{
  grid-area: main;
 }
  
 nav{
  grid-area: navbar;
 }
  
 footer{
  grid-area: footer;
 }
}
```

# 完成イメージ

ざっくりは下記のような感じになるはず。

この図でいうレイアウト自体はGridで
各ブロック要素（ヘッダー等）はFlexboxで
構成するのが個人的に配置しやすかったということ。

![スクリーンショット 2021-08-07 10.01.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1380401/65645188-0a2a-3eff-b1b3-2da155cd16c1.png)



# 終わりに

初学者のため、現状の気づきでまとめている。

今のところ

また、flexboxに関する参考記事が多い理由は

１、flexboxだけでもレイアウト構成が可能なため
　　・方向性を変更（縦→横並び）
　　・余白を入れる（要素に均一にスペースを空ける）
　　・要素を折り返しさせる
   を全体のレイアウトに適用させる方法

２、gridがflexboxより新しい技術なため

だと思っている。

途中でもっと良い書き方に気づけば、情報を更新する。

最後までお読みいただき、ありがとうございました！