WordPress 有料テーマ Snow Monkey の基本的な構造について – CSS・エディタースタイル設計編

Snow Monkey アドベントカレンダー6日目の記事です。

昨日はさとうさんが「Snow Monkey オンラインセミナーに参加しました!」というタイトルで Snow Monkey オンラインコミュニティでライブ放送を視聴したときのことを記事にしてくださいました。とても嬉しくなる記事で、ライブ放送もやってよかったなと思いました。ライブ放送はまたやってみたいと思います!

今日は Snow Monkey の CSS 設計や CSS・エディタースタイルに関する Tips なんかを書きたいと思います。

命名規則・CSS フレームワーク

Snow Monkey は Basis という自作の Sass/CSS フレームワークを使用しています。Basis については今までいくつか記事を書いているので詳しくはそちらをご参照ください

Basis は命名規則に FLOCSS を使っているので、Snow Monkey もそれにのっかる形で FLOCSS を使っています。

  • 要素のデフォルトスタイルを定義するレイヤー
  • レイアウトの大枠を定義する層
  • 各コンポーネントを定義するレイヤー
  • 強制的なスタイルを定義するレイヤー

がありさえすれば僕は満足なので、オリジナルで考えるより思想が近そうな FLOCSS を採用したという感じなので、厳密に正しい FLOCSS で書けているのかというと微妙なところはあるかもしれませんが、あまり気にしていません。下記のようなディレクトリ構成で運用しています。

/snow-monkey/
├ style.css                                           # テーマに必須の style.css。ここにはスタイル定義は書かない
├ /dist/                                                # Sass をコンパイルした、実際に読み込む CSS が配置されるディレクトリ
│ ├ style.css
│ ├ style.min.css                               # 実際に読み込まれるフロント用の CSS
│ ├ editor-style.css
│ └ editor-style.min.css                   # 実際に読み込まれる WYSIWYG 用の CSS
└ /src/
    └ /css/                                             # Sass と、カスタマイザーの CSS 定義用ファイルを配置するディレクトリ
        ├ /foundation/                            # 基本スタイルや WordPress 必須クラスのスタイルを定義するレイヤー
        │  ├ /_body/
        │  │  └ _body.scss                    # body 要素のスタイル、ミックスインの定義、Basis のインポート
        │  ├ /_element/                         # 基本スタイルの定義
        │  │  ├ _element.php
        │  │  └ _element.scss
        │  └ /_wordpress/                     # WordPress 必須クラスのスタイルを定義
        │      ├ /_wp-caption/
        │      │ └ _wp-caption.scss
        │      ├ /_wp-image/
        │      │ └ _wp-image.scss
        │      ├ ...
        ├ /layout/                                    # 大枠のレイアウトのスタイルを定義するレイヤー
        │ ├ /_container/
        │ │ └ _container.scss
        │ ├ /_header/
        │ │ └ _header.scss
        │ ├ ...
        ├ /object/
        │ ├ /component/                       # 使いまわし可能な小さいコンポーネントを定義するレイヤー
        │ │ ├ /_btn/
        │ │ │ ├ _btn.php
        │ │ │ └ _btn.scss
        │ │ ├ ...
        │ └ /project/                              # 大きめのコンポーネントを定義するレイヤー
        │ │ ├ /_global-nav/
        │ │ │ ├ _global-nav.php
        │ │ │ └ _global-nav.scss
        │ │ ├ ...
        ├ _settings.scss                          # npm や Composer 由来の Sass をインポートするファイル
        ├ editor-style.scss                      # WYSIWYG 用のスタイル(エディタースタイル)
        └ style.css                                    # フロント用のスタイル

一般的な構成と明らかに違うのは、普通 /component/_btn.scss のようになるところを /component/_btn/_btn.scss と一階層落としているところですね。これは煩雑になりそうなのでかなり悩んだ部分なのですが、各コンポーネントに対しカスタマイザーが出力する CSS を /css/ 以外のディレクトリで管理する煩雑さと天秤にかけてこちらの構成を選択しました。やってみると意外に使いやすくて気に入っています。

テーマディレクトリ直下の /style.css にはスタイルを書かず、読み込みもせず、/dist/css/style.min.css を読み込むようにしています。知らない方もいらっしゃるかもしれませんが、/style.css って別に読み込まなくても良いんですよね。テーマコメントが書いてあって、ディレクトリに存在だけしとけばいいのです。CSS は普通に書き出したものを圧縮したものと2つ入れておきたかったり、他にも別途読み込ませたい CSS がでてきたりした場合に、フロント用の CSS だけ / において他のは /dist/css/ に入れるとかなるとあとで絶対に混乱するので「CSS 類は全部 /dist/css/ に入れる!」という運用にしています。

余白設計

僕的に他の人がどうしているか気になるのに意外にググっても記事がないランキング上位の余白設計について書きます。

要素間の余白の取り方

皆さんは要素のマージンはどうつけていますか?要素に直に上マージンでしょうか?それとも要素に直に下マージンでしょうか?Snow Monkey はそのどちらでもなく、隣接セレクタを使ってマージンをつけるようにしています。

つまり、

p, ul, ol, dl, table, form {
    margin-bottom: 1.5rem;
}

ではなく、

p, ul, ol, dl, table, form {
    margin-top: 0;
    margin-bottom: 0;
}

.c-entry__content > * + * {
    margin-bottom: 1.5rem;
}

という感じです。実際は見出しはバランスを考えて余白のとり方を変えたりしているので上記の通りではないですが、おおよそこんな感じです。

もともと僕は最初の例のように下マージン派だったのですが、ここでは余白はいらないなというところを毎回打ち消す作業がすごくストレスでした。特に最後の要素の余白!めんどくさすぎ!しかも結局場所場所でバランス考えて余白の大きさを変えることも多いし、それならいっそ基本マージン0にしてしまって、必要に応じてつけるほうが管理しやすいのではないか、と考えたところがはじまります。そして、その場所(例えば記事内とか)の中では各要素間の余白のとり方は基本的に同じなので、隣接セレクタで一気に指定してしまうようにしてみたところ、これが超使いやすい!ということで、次のようなミックスインをつくってそれぞれの場所で要素間の余白を定義できるようにしています。

.c-entry__content {
    @include _content(1);
}

.c-comment__body {
    @include _content(.5);    // コメントエリアでは通常の半分の感覚で要素間の余白をとる
}

ちなみに、このように余白を指定するようにすれば、コンポーネント自体に余白がないので、コンポーネントを使いまわしてページを作っていく現代の Web 制作とすごく相性が良いです。

ちなみに、仕事で某有料テーマを使ったときは

.entry-content h2 {
    margin-top: 2em;
    margin-bottom: 1em;
}

みたいな CSS が定義してあったので、僕が独自に定義した

.block {
    &__title {    // ここは h2.block__title を想定
        margin-bottom: .5em;
    }
}

のようなスタイルを強制的に上書きしてきて、すさまじいストレスでした…。

Basis のミックスイン _margin()、_padding()

通常、マージンやパディングを指定する場合は

.foo {
    padding: 10px;
}

のようにすると思いますが、これだとバランス良い余白を設計しようとしたときに数値をものすごく記憶しておかなければいけません。都度目でみてピクセル調整するというのであれば別ですが、それにしてもあとで「やっぱり全体的に余白をちょっと広めに調整したい」となったときは大変です。

そこで、Basis では _margin()_padding() というミックスインを用意し、

.foo {
     @include _padding(1);
}

のように、なんとなく広めにしたい・狭めにしたいというくらいの感覚で係数を指定すれば勝手に計算して良い感じの余白を設定してくれるようにしました。内部に変数をもっており、全体的に広めにしたい・狭めにしたいというときはその変数を上書きしてやれば1撃で全体の余白バランスが調整できるような仕組みにしています。

このような便利ミックスインは子テーマでも Snow Monkey の Sass をインポートすれば使えるようになるので、Gulp や Sass が使える方はぜひ使ってみてください。

Pure CSS Gallery

皆さん、ライトボックスはお好きでしょうか?僕は大好きです。あのオシャレにオーバーレイで画像を拡大表示しれくれるアレです。一般的に、あれを使うには lightbox やら fancybox やらの js ライブラリを使用すると思いますが、簡易なものなら CSS だけで実装することが可能です。

Snow Monkey では、WordPress のギャラリーを挿入した場合、CSS だけでライトボックス表示できるようにしています。js を使っていないので、ガクつかない、軽いなどのメリットがあります。

エディタースタイルで注意が必要なポイント

基本的な設計については以上ですが、エディタースタイルとしてスタイルを共用しようとした場合はもうひと工夫必要になります。エディタースタイルというのは記事編集画面の WYSIWYG 用の CSS のことです。Sass を使っている場合、例えば次のようにするとフロントのスタイルとエディタースタイルを一発で作成できます。

// style.scss
.btn {
    display: inline-block;
    background-color: #f00;
    color: #fff;
    text-decoration: none;
}

// editor-style.scss
@import 'style';

このようにすれば、style.scss にコードを書けば editor-style.scss ではそれをインポートするだけでフロントの CSS(style.css)もエディタースタイル(editor-style.css)も作成することができます。やったー!…とはならないのです…。

a 要素に強制的にスタイルが当たる

こちらをご覧ください。

右下を見て頂きたいのですが、wp-content.css というスタイルが読み込まれています。これは僕がつくったものではなく、WordPress がデフォルトでもつエディタースタイルで、自動的に読み込まれるものです。で、なんとこのエディタースタイル、a 要素 を強制的に上書きしてくるのです!しかも .mce-content-body a という詳細度高めの攻撃で攻めてくるので、a.btn のような要素を記事中においたときに、強制的に上書きしてきて「うわぉ」となっちゃうのです…。

なので、僕は下記のようにして、エディタースタイルでは自分で定義したクラスの詳細度をあげるようにしています。

body.mce-content-body {
   @import 'style';
}

ギャラリーの HTML をフックでカスタマイズしても、WYSIWYG 内のギャラリーの HTML は変わってくれない

WordPress は「メディアを追加」からギャラリーが挿入できます。これですね。

そして、このギャラリーの HTML は post_gallery というフィルターフックでカスタマイズできるようになっています。ただ、このフック、WYSIWYG 内のギャラリーには反映されないのです。つまり、フロントでは

.gallery {
    &__item {
    }
}

のような構成を想定してスタイルを定義したとしても、WYSIWYG 内では

.gallery {}
.gallery-item {}

な HTML で表示されてしまうので、WYSIWYG 内でちゃんとスタイルが当たらないのです!まぁ管理画面内だし、サイトを訪れたユーザーに見えちゃうわけじゃないので良いっちゃ良いのですが、なんかいやじゃないですか。だからもう下記のように蓋をしてしまうことにしました。

これ、なかなか良いアイデアだと思ったのですがどうでしょう?

明日は

明日はものくろさんが参加登録してくださっていまいた、ありがとうございます!今から楽しみです。

この記事を書いた人

キタジマ タカシ

長崎県長崎市在住。地元のWeb制作会社でWebデザイナー/エンジニアとして従事した後、2015年にフリーランス [ モンキーレンチ ] として独立。WordPress のテーマやプラグイン、ライブラリ、CSS フレームワーク等、多数のプロダクトをオープンソースで開発・公開しています。

Snow Monkey オンラインコミュニティ

Snow Monkey をより良いテーマにするために、今後の機能開発等について情報共有したりディスカッションをしたりする場所です。より多くのユーザーの交流があったほうがより良いプロダクトに育っていくと思いますので、ぜひご参加ください!