scssの中身をコンポーネントごとに振り分け
前回の時点で、納品フォルダ(wordpress)の外にsrcディレクトリを設け、そこに開発に必要なファイル (sass、js)を配置しました。
コンパイル先を納品フォルダ(wordpress)にすることにより、開発側のファイルは含まれないようになりました。
今回はsrcディレクトリの中のscssの構造を組み立てていきます。
scssの記述をグループ分け
FLOCCSで行こうか悩みましたが、汎用的なコンポーネントを後からプロジェクト特有に作り変えるのがほとんどな経験から、
「c-」とか「p-」とか接頭辞を書くのも意味を感じられなくなっている自分がいます。
しかもReactなどコンポーネント思考の構築をしてみると、余計命名を気にするより
BEMっぽ~くクラス名をつけ、そのコンポーネントごとにscssファイルを管理していくのがいいかと自分の中で着地しました。
でもグループ分けはFLOCSSを参考にしました。
scssファイルを移植した時点でのディレクトリ構造は、以下のとおりです。
.
├── .gitignore
├── .vscode/
├── .github/
├── bs-config.js
├── docker-compose.yml
├── node_modules/
├── package-lock.json
├── package.json
├── src/
│ ├── js/
│ │ └── main.js
│ └── sass/
│ ├── editor-style.scss
│ ├── style.scss
│ ├── foundation/
│ │ ├── _base.scss
│ │ └── _index.scss
│ ├── global/
│ │ ├── _index.scss
│ │ ├── mixin/
│ │ │ ├── _breakpoints.scss
│ │ │ ├── _lineheight.scss
│ │ │ ├── …
│ │ │ └── _index.scss
│ │ └── setting/
│ │ ├── _font-family.scss
│ │ ├── …
│ │ └── _index.scss
│ ├── layout/
│ │ ├── _footer.scss
│ │ ├── _gnav.scss
│ │ ├── _header.scss
│ │ ├── …
│ │ └── _index.scss
│ └── object/
│ ├── _index.scss
│ ├── component/
│ │ ├── _breadcrumb.scss
│ │ ├── _button.scss
│ │ ├── _card.scss
│ │ ├── …
│ │ └── _index.scss
│ └── utility/
│ ├── _font-size.scss
│ ├── _padding.scss
│ ├── _margin.scss
│ ├── …
│ └── _index.scss
└── wordpress/
└── wp-content/
└── themes/
└── mytemplate/
├── assets/
│ ├── css/
│ │ ├── editor-style.css
│ │ ├── lib/
│ │ │ └── atom-one-dark.min.css
│ │ ├── static-app.css
│ │ └── style.css
│ ├── img/
│ └── js/
│ ├── lib/
│ │ ├── highlight.min.js
│ │ └── toc.js
│ ├── home.js
│ ├── main.js
│ └── static-home.js
sassのキャッシュを削除
最初にこの構成にしたときに、src/sass/foundation/_base.scssから@use '../global/' as *;
が読み込めないエラーが出ていたのですが、
以下の方法でsassのキャッシュを削除(依存関係の初期化)して再コンパイルをしたら、無事に読み込まれるようになりました。
rm -rf node_modules package-lock.json
npm install
npm run watch:sass(私の環境ではnpm startでも可)
Gutenbergコアブロックとスタイルを共有
さて、サイト全体のスタイルはこれでなんとか組み立てられたところですが、問題はGutenbergコアブロックです。
wordpress/wp-content/themes/mytemplate/single.phpのこの部分は、ブロックを挿入するのでそのブロックにスタイルを充てていかなければなりません。
今まではフロント側だけをみていたので、.post ul li の様に書けばブロックエディタのul liに適用されて共有できていました。
<?php if ( have_posts() ) : ?>
<?php while ( have_posts() ) : the_post(); ?>
<article id="post-<?php the_ID(); ?>" <?php post_class('post'); ?>>
…
<div class="post__content">
…
<div class="content">
<?php the_content(); ?>
</div>
…
</div>
…
</article>
<?php endwhile; ?>
<?php endif; ?>
しかし、.postクラスは管理画面側に存在しません。
せっかくscssで書くなら1つのスタイルを共有し管理しやすくしたいです。
調査したところ、2つほど候補を見つけました。
- render_block フィルターでGutenbergコアブロックにクラス追加
→サイト全体に適用していたクラスをブロックにも付与して使え便利そうだが、ブロックが出てくるたび登録する必要がある
- エディタ画面側に自動付与される「.editor-styles-wrapper」配下のHTMLタグに同じスタイルを充てる
(例: .editor-styles-wrapper h2 {…})
→将来カスタムブロックを作るときにタグセレクタ指定だと競合しそう
さてどうしたものかと悩み出したらここから沼にハマりました。
結果、コアブロックのクラス名「wp-block-⚫︎⚫︎⚫︎」はフロントでもエディタでも共通して付与されているのを確認できました。
それであれば、以前書いたこの記事のように.post__content ul li
などと書かなくても、 .wp-block-list li
と書いてeditor-style.scssとstyle.scssから読み込ませ共通化すれば良い事に気づきました。
管理画面に必要なcssのみ読み込む構造にする
先ほどの構造から、変化したのはこの箇所になります。
.
├── src/
│ └── sass/
│ ├── editor-style.scss ←管理画面用(管理画面のブロックエディタが読み込む)css
│ ├── style.scss ←フロント側用(サイト全体と、フロントのブロックエディタが読み込む)css
│ └── object/
│ ├── _index.scss
│ ├── component/
│ │ ├── _breadcrumb.scss
│ │ ├── _button.scss
│ │ ├── _card.scss
│ │ ├── _heading.scss
│ │ ├── _list.scss
│ │ ├── _index.scss
│ │ ├── mixin/ ←サイト全体とブロックエディタ共通で使用するcss
│ │ │ ├── _heading.scss
│ │ │ ├── _list.scss
│ │ │ └── _index.scss
│ │ └── wp-block/ ←ブロックエディタ用css
│ │ ├── _heading.scss
│ │ ├── _list.scss
│ │ └── _index.scss
src/sass/object/component/mixin/_heading.scss
// サイト全体、ブロックエディタ両方に共通するcss
@use '../../../global' as *;
@mixin post-heading-primary {
…
@include mq {
…
}
}
@mixin post-heading-secondary {
…
}
src/sass/object/component/wp-block/_heading.scss
//共通cssであるmixinをブロックエディタに引用
@use "../mixin/heading" as heading;
.wp-block-post-title {
@include heading.post-heading-primary;
}
.wp-block-heading {
&:is(h2) {
@include heading.post-heading-secondary;
}
}
src/sass/object/component/wp-block/_index.scss
//ブロックエディタcssをまとめて、フロント側とエディタ側に読み込ませる
@use 'heading';
@use 'list';
src/sass/object/component/_heading.scss
@use "../../global" as *;
// mixinを読み込み、サイト全体用cssに渡す
@use "mixin/heading" as heading;
.heading {
&--primary {
@include heading.post-heading-primary;
}
&--secondary {
@include heading.post-heading-secondary;
}
}
src/sass/object/component/_index.scss
// style.scssにブロックエディタcssを追加
@forward 'wp-block';
src/sass/style.scss (変更なし)
@charset "utf-8";
@use '../../node_modules/destyle.css/destyle.css';
@use 'foundation';
@use 'layout';
@use 'object';
src/sass/editor-style.scss
// ブロックエディタで使われるcssのみをまとめて読み込み
@use 'object/component/wp-block' as *;
なるべくコンポーネントの構造を変えたくなかったのですが、不要なcssを管理画面側のeditor-style.scssに読み込ませない様にするには、mixinディレクトリを作る必要がありました。
そしてブロックエディタにmixinを取り込むためのwp-blockディレクトリも併設し、それをeditor-style.scssとstyle.scss両方とも読み込ませました。
こうすることで、サイト全体とコアブロック(フロント側、エディタ側)で共通するscssを一箇所に書けば展開されるようになりました。
もっと良い構造があるんじゃないか、、そもそもなんでフロントと管理画面用と分ける必要があるんだ、、と悩みは絶えませんが、これで進もうと思います。
それにしても、調べるほどに色々な手法があり、自分に適した方法はなんなのか迷ってしまいますね。。
続けることにより、最適解を見つけ出せると信じつつ、頑張りたいと思います。