コンポーネントとレイアウトの違いとは？Turbo Rails Tutorial をやってみた（2章）

本記事は、🔽「Turbo Rails Tutorial」の学習を進めていく際の個人メモです！

https://www.hotrails.dev/turbo-rails

🔽 前章の記事はこちら

https://qiita.com/yuppymam/items/4d7a778040207cc4d698

# 2章 [Organizing CSS files in Ruby on Rails](https://www.hotrails.dev/turbo-rails/css-ruby-on-rails)

この章ではCSSについてのみ、触れていきます。このチュートリアルではCSSフレームワークは使用しませんが、「BEM」の規則に沿って厳格にCSSを1から作成していきます。

`app/assets/stylesheets/`フォルダー下に4つのフォルダーを作成します。

## `mixins`フォルダー
`mixins`フォルダー下に`_media.scss`ファイルを作成し、このアプリケーション内で使える共通のメディアクエリを作成します。
```scss: app/assets/stylesheets/mixins/_media.scss
@mixin media($query) {
  @if $query == tabletAndUp {
    @media (min-width: 50rem) { @content; }
  }
}
```
`media`の引数が`tabletAndUp`の時は`min-width: 50rem`が適用されます。以下のように使えます。


```scss
.my-component {
  @include media(tabletAndUp) {
    // タブレットサイズより大きい時のCSSを記述する
  }
}
```

ブレークポイントはこうして1か所にまとめておくと、何箇所も同じ変更をする手間がなくなる、という訳ですね！

## `config`フォルダー
このフォルダーは、汎用的に使える「変数」や「グローバルな設定」を置く場所です。ここで様々な変数を設定しておくことで、CSSの値を変数でシンプルに書くことができます。

フォントサイズだったらこんな感じに変数を設定しておくことで、
```scss: app/assets/stylesheets/config/_variables.scss
:root {
  --font-size-xs: 0.75rem;   // 12px
  --font-size-s: 0.875rem;   // 14px
  --font-size-m: 1rem;       // 16px
  --font-size-l: 1.125rem;   // 18px
  --font-size-xl: 1.25rem;   // 20px
  --font-size-xxl: 1.5rem;   // 24px
  --font-size-xxxl: 2rem;    // 32px
  --font-size-xxxxl: 2.5rem; // 40px
}
```

以下のように使えます。

```scss
h1 {
  font-size: var(--font-size-xxxl);
}

h2 {
  font-size: var(--font-size-xxl);
}

h3 {
  font-size: var(--font-size-xl);
}

h4 {
  font-size: var(--font-size-l);
}

```

この他にも、空白スペースや、色、ブラウザごとのデフォルトCSSを打ち消すリセット用CSSなどもここで設定します。

## `components`フォルダー
`components`フォルダーには、よく使うCSS（例えば「ボタン」など）を部品化して、分けて置いておきます。CSSの値には先ほど`config`フォルダーで設定した変数を使えます。

```scss: app/assets/stylesheets/components/_btn.scss

.btn {
  display: inline-block;
  padding: var(--space-xxs) var(--space-m);
  border-radius: var(--border-radius);
  background-origin: border-box; // Invisible borders with linear gradients
  background-color: transparent;
  border: solid 2px transparent;
  font-weight: bold;
  text-decoration: none;
  cursor: pointer;
  outline: none;
  transition: filter 400ms, color 200ms;

  &:hover,
  &:focus,
  &:focus-within,
  &:active {
    transition: filter 250ms, color 200ms;
  }
```

これで、クラス名を与えるだけで統一されたボタンのデザインになりますね！チュートリアル内では`.btn--primary`、`.btn--secondary`、`.btn--light`、`.btn--dark`の4種類のボタンデザインを追加しました。

ボタン同様に、「フォーム」や「エラーメッセージ」などもこの`components`以下に部品化して設置しました。

🔽 エラーメッセージ用の設定

```scss: app/assets/stylesheets/components/_error_message.scss
.error-message {
  width: 100%;
  color: var(--color-primary);
  background-color: var(--color-primary-bg);
  padding: var(--space-xs);
  border-radius: var(--border-radius);
}
```

## `layouts`フォルダー
`layouts`フォルダーには、すべてのページで使用される`.container`や、`.header`などの設定を置きます。

## `application.sass.scss`ファイル
これまで設置してきたフォルダー下にあるすべてのファイルを`application.sass.scss`に`import`させます。（これにより、1つのコンパイル済みCSSファイルになるのです！）

```scss: app/assets/stylesheets/application.sass.scss
// Mixins
@import "mixins/media";

// Configuration
@import "config/variables";
@import "config/reset";

// Components
@import "components/btn";
@import "components/error_message";
@import "components/form";
@import "components/visually_hidden";
@import "components/quote";

// Layouts
@import "layouts/container";
@import "layouts/header";
```

これで、2章が終わりです。がっつりCSSを書きました！
デザインって偉大ですね。
![スクリーンショット 2023-02-03 22.13.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293962/b02351c7-64ee-c2ed-66d1-f800aed51f6d.png)

## コンポーネントとレイアウトの違い
この章で得た本記事のタイトルの答えとして、私なりにまとめたものです。
コンポーネントとは、Webページの独立した部品のようなもの。どこに配置されるかは分からないけど、よく使うもの。スタイルを部品ごとに当てておくことで、あらゆる場所で使いやすくする。良い例が「ボタン」など。コンポーネントは基本的に外側のマージンを持たない方が良い。

レイアウトとは、Webページの配置。中央揃えや、コンポーネントの位置を相対的に配置するのに役立つものだけを考慮する。

こんな感じで合っているでしょうか？デザインは奥が深いですね。

🔽 次は3章をやっていきます！やっと本題の「Turbo Drive」に触れていきます。

https://qiita.com/yuppymam/items/e3fef1a153ddcd78927c