【付録・CSS設計11】設計手法:PRECSSの紹介2【WPテーマ作成】

WordPressテーマ作成

本付録は、メインシリーズであるWordPressのテーマ作成に役立ちそうな情報を補足していくパートだ。

前回からPRECSSの解説を開始し、同時にサンプルも作り始めた。

現時点では、ベースグループ、レイアウトグループを完成させた状態だ。

…とはいえ、paddingなど細かいところは今後もいじる可能性があることはご了承を。

一旦、ベースではリセットCSSを含む各要素のデフォルトを、レイアウトではヘッダーやフッターなどのページを構成する大きな枠組みの設定を行うことを覚えておこう。

以下がその記事だ。

さて、もちろん今回も引き続きPRECSSの内容を扱っていこう。

今回は、モジュールグループを解説する。

やはりそれまでに使っていたモジュールと同じく、どこにでも配置できるというのが大原則となる。

内訳をブロックとエレメントに分けているのはBEMに似ているが、うちエレメントはBEMのものとはだいぶ異なるのでそこにも注意しながら進めていきたい。

なお、本付録は以下の本を参考にしている。

CSS設計完全ガイド ~詳細解説+実践的モジュール集 | 半田 惇志 |本 | 通販 | Amazon
Amazonで半田 惇志のCSS設計完全ガイド ~詳細解説+実践的モジュール集。アマゾンならポイント還元本が多数。半田 惇志作品ほか、お急ぎ便対象商品は当日お届けも可能。またCSS設計完全ガイド ~詳細解説+実践的モジュール集もアマゾン配送商品なら通常配送無料。

気になる方は、実際に本屋で中身を見てみたり、買ってみたりしよう。

また、PRECSSの公式ページも貼っておく。

PRECSS - Manage your CSS with prefixes.
PRECSS is a new modular architecture approach based on OOCSS, SMACSS and BEM.

是非、こちらも参照しながら進めていただきたい。

スポンサーリンク

モジュールグループ

では早速本題へ。

上に書いた通り、モジュールでは再利用可能な部品を扱う。

大きさをブロックエレメントという二つに分けているので、それぞれで見ていこう。

ブロック

ブロックそのモジュール特有の子要素を持つもので、後述するエレメントや他のブロック自身を含むこともできる。

やはりモジュールなのでどこに配置しても大丈夫なもの、というのが基本だ。

接頭語はbl_、またBEMで言うBlockと非常に似ている考え方になる。

例としては、前回のPRECSSの基本の中、命名規則のところで出した例が挙げられる。

以下、再掲しておこう。

<div class="bl_halfMedia">
  <img class="bl_halfMedia_img" src="..." alt="...">
  <div class="bl_halfMedia_desc">
    <h3 class="bl_halfMedia_ttl">タイトル</h3>
    <p class="bl_halfMedia_txt">説明文</p>
  </div>
  <!-- /.bl_halfMedia_desc -->
</div>
<!-- /.bl_halfMedia -->

PRECSSでも、基本的にはBEMと同じく詳細度は均一にすることが推奨されている。

だが、BEMほど厳しく制限されているわけでもない。

例えば、今例を出したブロックのうち、画像部分を少し変えてみる。

<div class="bl_halfMedia">
  <figure class="bl_halfMedia_imgWrapper">
    <img src="..." alt="...">
  </figure>
  <div class="bl_halfMedia_desc">
    <h3 class="bl_halfMedia_ttl">タイトル</h3>
    <p class="bl_halfMedia_txt">説明文</p>
  </div>
  <!-- /.bl_halfMedia_desc -->
</div>
<!-- /.bl_halfMedia -->

先ほどは直接imgタグを使っていたところ、figureタグで囲んでそちらにクラス名をつけた。

これでimgタグにスタイルを決めるとなった時は、子孫セレクターを使うことが許容されている。

条件としては、まず十分にスコープが絞られていること

やはり無駄に広くするのはよくないので、子セレクターで十分な場合はこちらを使うようにしよう。

次に、divspanといった抽象度が高い要素…SMACSSのところで解説した言葉を使えばセマンティック性が低い要素については、やはりクラス名をつけることを推奨している。

その他、あまり階層が深くなるとコードの可読性や詳細度に悪影響が出るので、多くても3階層程度に留めるように。

それ以上になりそうな場合は、しっかりクラス名をつけてそれで指定したい。

この例としては、箇条書き内のliタグなんかが典型だろう。

<ul class="bl_list">
  <li>list 1</li>
  <li>list 2</li>
</ul>
.bl_list {
  /* リストブロックへの設定 */
}

.bl_list > li {
  /* リスト項目への設定、これはOK */
}

さて、ここで一つ注意。

上にも書いた通りで、ブロックはどこでも配置可能であるというのが基本。

そのため、ブロックモジュールにはレイアウトに関わらない設定のみをすることが原則だ。

具体的には…

  • 100%以外を指定するwidth
  • absolutefixedstickyを指定するposition
  • 位置を指定するtopleftrightbottom
  • margin
  • float

などがレイアウトに該当し、これらはブロックに直接指定することは避けよう。

ブロックモジュールの幅はなるべく初期値のままが望ましく、それにより拡張性だったり移植性だったりを高めることができる。

ただし一つだけ、そのブロックモジュール共通で上下に決まった余白を取りたい場合のみ、margin-topmargin-bottomを直接当てることが許可されている。

もしその他をやりたい場合は、このブロックを含む親要素側で設定する、あるいはラッパーモジュールというものを使う。

前者は公式サイトではコンテキストという名前で後半に紹介されている。

後者は、カラムを形成するブロックモジュールで具体例を見てみよう。

ここはちょっと公式のサンプルを引用し、1つのページとして書いてみた。

そのサンプルはこちらだ。

まずは1カラム、言い換えれば基本の形を書いてみる。

サンプルの該当部分は以下の通り。

<p class="bl_description">1カラムの例</p>
<div class="bl_card">
  <figure class="bl_card_imgWrapper">
    <img alt="Dummy Image" src="./image/sample.jpg">
  </figure>
  <div class="bl_card_body">
    <h3 class="bl_card_ttl">Title Here</h3>
    <p class="bl_card_txt">Write here the description of this card.</p>
  </div>
  <!-- /.bl_card_body -->
</div>
<!-- /.bl_card -->
.bl_description {
  font-weight: 600;
  margin-bottom: 5px;
  margin-top: 10px;
}

.bl_card {
  width: 100%;
  background-color: #fff;
  box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16);
}

.bl_card_imgWrapper {
  position: relative;
  padding-top: 56.25%;
  overflow: hidden;
  margin: 0;
}

.bl_card_imgWrapper > img {
  position: absolute;
  top: 50%;
  width: 100%;
  transform: translateY(-50%);
}

.bl_card_body {
  padding: 15px;
}

.bl_card_body > :last-child {
  margin-bottom: 0;
}

.bl_card_ttl {
  margin-bottom: 5px;
  font-size: 1.125rem;
  font-weight: 700;
  margin-top: 0;
}

.bl_card_txt {
  color: #777;
  margin-top: 0;
}

この内容を元に、複数カラムを実装してみよう。

まず、この複数カラムを実現するために、それ全体を囲むラッパーモジュールを作る。

これ自体もブロックモジュールとして、クラス名はbl_cardUnitとしよう。

これでラップすることにより、他のブロックモジュールに影響を与えることなく、あるいはCSSの修正をすることなく再利用できる。

また、やはりブロックモジュールなので、これ自体を他の場所へ移すことが可能なのもポイントだ。

まだ解説していない内容だが、カラム数はモディファイアを使う。

詳細は後で解説するので、少しお待ちいただきたい。

複数カラムを実装した例は以下の通り、今回は3カラムと4カラムを実装している。

また、HTMLの各li要素の中は1カラム時のbl_cardクラスの中身と一緒。

CSSは既存の内容には手を触れず、ここに出した内容の追記のみを行っている。

<p class="bl_description">3カラムの例</p>
<ul class="bl_cardUnit bl_cardUnit__col3">
  <li class="bl_card">...</li>
  <li class="bl_card">...</li>
  <li class="bl_card">...</li>
</ul>

<p class="bl_description">4カラムの例</p>
<ul class="bl_cardUnit bl_cardUnit__col4">
  <li class="bl_card">...</li>
  <li class="bl_card">...</li>
  <li class="bl_card">...</li>
  <li class="bl_card">...</li>
</ul>
.bl_cardUnit {
  display: flex;
  flex-wrap: wrap;
}

/* 3カラム */
.bl_cardUnit.bl_cardUnit__col3 {
  margin-bottom: 10px;
}
.bl_cardUnit__col3 > .bl_card {
  width: 31.707%;
  margin-right: 2.43902%;
  margin-bottom: 30px;
}
.bl_cardUnit__col3 > .bl_card:nth-of-type(3n) {
  margin-right: 0;
}

/* 4カラム */
.bl_cardUnit.bl_cardUnit__col4 {
  margin-bottom: -20px;
}
.bl_cardUnit__col4 > .bl_card {
  width: 23.78%;
  margin-right: 1.62602%;
  margin-bottom: 20px;
}
.bl_cardUnit__col4 > .bl_card:nth-of-type(4n) {
  margin-right: 0;
}

@media screen and (max-width: 768px) {
  .bl_cardUnit.bl_cardUnit__col3 {
    margin-bottom: -20px;
  }
  .bl_cardUnit.bl_cardUnit__col4 {
    margin-bottom: -15px;
  }
  .bl_cardUnit > .bl_card {
    width: 100%;
    margin-right: 0;
    margin-bottom: 20px;
  }
}

このように、既存の内容には一切手を触れることなく複数カラムを実現することができている。

つまり、レイアウトはやはりそのブロックモジュール自身ではなく、今回で言えば一つ上のラップしたモジュール側を起点として指定している

これで、高い移植性を保つことができるのだ。

慣れないとなかなかピンと来ないと思うが、それは数をやって慣れていくしかないだろう。

さて、ブロックの最後に、命名に関する内容を少しだけ。

上でも書いたが、PRECSSにおいてはほとんどがこのブロックでページが構成されることになり、非常に重要になってくる。

そのため、分かりづらくなるような単語の省略は推奨されていない。

また、そのブロックの大きさ(粒度)によって特定の文字列を入れることもある。

具体的には以下のようなものだ。

  • Block : ブロックモジュールの基本単位、上で解説した内容そのまま
  • Unit : 複数のBlockが集まったもの、上で言うとbl_cardUnitがこれにあたる
  • Container : 複数のUnitが集まったもの

これについて、Blockという文字列は入れないことも多く、Containerはそもそも使うことはそうそうないだろう。

エレメント

分け方は似ていたが、中身はBEMにおけるElementとはかなり違うので注意。

PRECSSにおけるエレメントは、ボタンやラベル、見出しなど最小単位となるモジュールで、どこにでも埋め込むことができるものだ。

BEMでは必ずBlockの中に配置され、他では使えないものだったことを思い出そう。

どこでも埋め込める、というのを表すため、命名はなるべく汎用的なものをつけることが推奨されている。

命名規則は、先頭にel_をつけてそのエレメント名を書く。

例えば、ボタンをこのエレメントとして実装する場合、そのボタンが何をするものか、という名前をつけるのはあまり良くない。

それが送信ボタンを表すとしても、el_submitButtonという名前は避けよう、ということだ。

この時は、単にel_buttonとする方がいい。

もし色を変えるなどのバリエーションを持たせたい場合は、OOCSSのストラクチャーとスキンの分離、あるいはBEMのModifierのようなイメージでこちらもモディファイアを使う。

詳細は後で見るので、これを使って送信、キャンセルのボタンを実装するときは、以下のようにするといいだろう。

<button class="el_button">送信</button>
<button class="el_button el_button__blue">キャンセル</button>

これは、送信ボタン側では基本となるボタンエレメントの内容を使い、キャンセルボタン側は色を青に変更することを想定している。

なお、どこでも入れれるという性質上、やはりこれ自体にレイアウトに関するスタイルを書くのも推奨されていない

…のだが、ブロックモジュールに比べればバリエーションは少なくなるだろう。

そのため、widthで幅を直接指定する、あるいはモディファイアでサイズ変更を制御することは認められている。

これにも注意があり、例えばレスポンシブデザインをするとき。

PCなど広い場合は直接幅をピクセル指定、スマホなど狭い場合は100%にする、ということを考えてみよう。

このとき、モディファイア名にピクセル数を入れると混乱の種になる。

以下のように組んだとしよう。

<button class="el_button el_button__w200">送信</button>
.el_button {
  width: 300px;
}

.el_button.el_button__w200 {
  width: 200px;
}

@media screen and (max-width: 768px) {
  .el_button.el_button__w200 {
    width: 100%;
  }
}

今、通常のボタン横幅は300pxだが、el_button__w200というモディファイアを付けた場合は200pxにすることを意図している。

w200が、widthを200pxにするという意味だ。

そして、さらにスマホなど横幅が狭い場合では、同じこのel_button__w200をつけた対象の横幅を100%としている。

こうすると、名前にw200と入っているのに横幅が狭い場合は100%となり、名前と中身が一致しなくなってしまう

これを避けるため、具体的な数字ではなくsmallmediumなど、キーワードで指定する方が望ましい。

今はデフォルトが300pxでそれより小さいのでsmallというキーワードを使い、さらに省略してsとしてみよう。

これで直すと以下のようになる。

<button class="el_button el_button__s">送信</button>
.el_button {
  width: 300px;
}

.el_button.el_button__s {
  width: 200px;
}

@media screen and (max-width: 768px) {
  .el_button.el_button__s {
    width: 100%;
  }
}

名前と設定値に乖離が生じると、そこからどんどん全体も崩れていってしまうきっかけになるので十分注意しておこう。

もしモディファイアのパターンに上手く当てはまらないような設定をしたい場合には、親要素からの子孫セレクターでスタイリングしてもOKだ。

ここで一つ補足、今解説したブロックとエレメントのどちらを使えばいいか、という部分を見てみよう。

これは、残念ながら明確に定義することはできない。

しかし、大きく二つの方針が提示されている。

一つは、その対象が他の色々なモジュールに含まれるかどうか、という観点。

例えばボタンやラベルなどに関してはページ内の様々な箇所で使われる可能性があり、その場合はエレメントとして定義した方がいいだろう。

もう一つは、ルートとなる要素と子要素を含めて、要素数がおよそ3以下であればエレメントとする、という方針も提示されている。

参考書では後半でエレメントモジュールの例をまとめているので、お持ちの方はそこを見てもらってもいいだろう。

モディファイア

さて、これまでも使ってしまっていたモディファイアを解説していこう。

あるモジュールについて、見た目や振る舞いを少し変えたいといった場合、このモディファイアを使ってそのスタイルを上書きすることが推奨されている。

命名規則は、モディファイアをつける対象のクラス名の後ろにアンダースコアを二つ挟み、モディファイア名をつける。

ここはローワーキャメルケースで、基本的にはBEMのキー、値と同じようにkeyValueのような感じでつける。

例えば背景色を白にしたい場合は、__backgroundColorWhiteのような感じ。

ただ、値だけでもある程度予測がつく場合はキー名は省略可能だ。

また、Emmetのショートハンドに沿う形でキー名を短縮してもいい。

これを使うと、__bgcWhiteとなる。

さて、この命名についてもBEMとの違いがある。

BEMではその名前に意味を持たせることを推奨していた。

例えば、警告表示のため背景色を赤にする場合は_theme_cautionのようにしていた。

それに対し、PRECSSでは見た目通りに__bgcRedという名前をつけることも許容している

これは、全ての色に意味を持たせた名前をつけることが難しいからだ。

とはいえ、もちろんそこを事前にしっかり設計しているのであればBEMのような命名でもOK。

このモディファイアは、今はモジュールブロックで説明しているが、別にモジュールのみにしか付与できないわけではない。

そのため、例えば前回のサンプルでやったようにレイアウトモジュールに対してもモディファイアは作成可能。

最初の説明で括弧にしていたのはこれが理由だ。

一つ注意としては、このモディファイアを付与する場合は基本的にそれで上書きを意図しているため、セレクターに複数クラスを入れて詳細度を高めることが推奨されている

そうすれば、例えば書く順番が変わろうとしっかり上書きしてくれる。

ちなみに、BEMではJavaScriptによって変わるような状態もモディファイアを使っていた。

PRECSSでもそれで可能ではあるのだが、後に解説するプログラムグループでの制御が推奨されているので注意しよう。

さて、ここでブロックモジュールにモディファイアを当てる場合の注意点を。

考え方8個目、拡張しやすいのところで解説した内容そのままなのだが、モディファイアによる影響範囲をしっかり考えよう。

どういうことかというと、例えばブログのメディア領域で画像に枠線をつけたいという場合、そのメディア領域自体ではなく、内側の画像領域にモディファイアを当てよう、ということ。

逆に、左右反転させるといった場合はその領域全体に影響するので、メディア領域自体にモディファイアを当てて子孫セレクターなどで子要素に反映させる。

例もその時の解説そのままなので、詳細はそちらを確認してほしい。

サンプルのヘッダー領域

今解説した内容を使って、サンプルの続きに取り掛かろう。

…現時点でそこそこ長くなってきているので、全てではなくヘッダー領域のみを対象にやってみる。

前回にも書いたが、ヘッダー領域に関してはちょっと元にするサンプルから形を変える。

具体的には、PC幅の場合は以下のような形だ。

ヘッダーイメージ図

余白の横の縦線は見やすいように入れているだけで、実際には入らない。

また、スマホ幅の場合はメインタイトルの下にサブタイトルを配置、そしてメニューを消してボタンで開閉する形で実装しよう。

ボタン開閉はJavaScriptも絡んでくるのでその時に作るとして、今回は単に非表示にする。

タブレット幅の場合は、左右の余白を無しにするのみ。

実装の方針としては、やはりスマホ幅のパターンをデフォルトとして、タブレット幅やPC幅をモディファイアで実装する。

今回は完成形を出し、それぞれで何をしているかを解説していこう。

というわけで完成形のページはこちら、該当部分のソースは以下の通りだ。

<header class="ly_header">
  <div class="bl_headerTitle bl_headerTitle__wLarge hp_pb2e">
    <div class="el_blogTitle hp_fz1_5e">
      ブログメインタイトル
    </div>
    <!-- /.el_blogTitle -->
    <div class="el_blogTitle">
      ブログサブタイトル
    </div>
    <!-- /.el_blogTitle -->
  </div>
  <!-- /.bl_headerTitle -->
  <div class="bl_headerMenu_wrapper bl_headerMenu_wrapper__wSmall">
    <ul class="bl_headerMenu bl_headerMenu__wLarge">
      <li class="el_headerMenuContent">
        <a href="#">
          <i class="fas fa-home fa-fw"></i> Top 
        </a>
      </li><li class="el_headerMenuContent">
        <a href="#">
          <i class="fas fa-folder fa-fw"></i> Category 
        </a>
      </li><li class="el_headerMenuContent">
        <a href="#">
          <i class="fas fa-user fa-fw"></i> Profile 
        </a>
      </li><li class="el_headerMenuContent">
        <a href="#">
          <i class="fas fa-envelope fa-fw"></i> Contact 
        </a>
      </li>
    </ul>
  </div>
  <!-- /.bl_headerMenu_wrapper -->
</header>
/*
*****************************
* Layout                    *
*****************************
*/

.ly_header {
  width: 100%;
  padding-top: 2em; /* 追加 */

  background-color: #ddd; /* 配置確認用 */
}

/*
*****************************
* Module                    *
*****************************
*/

.bl_headerTitle {
  width: 100%;
  padding-left: 1em;
  padding-right: 1em;
}

.el_blogTitle {
  text-align: center;
}

.bl_headerMenu_wrapper {
  background-color: #000;
}

.bl_headerMenu {
  display: flex;
  justify-content: center;
}

.el_headerMenuContent {
  flex: auto;
}

.el_headerMenuContent > a {
  display: block;
  text-align: center;
  font-weight: bold;
  padding-top: 1em;
  padding-bottom: 1em;
  color: #ddd;
  text-decoration: none;
}

/* スマホ幅 */
@media screen and (max-width: 768px){
  .bl_headerMenu_wrapper.bl_headerMenu_wrapper__wSmall {
    display: none;
  }
}

/* タブレット幅以上の共通設定 */
@media screen and (min-width: 768px){
  .bl_headerTitle.bl_headerTitle__wLarge {
    display: flex;
    align-items: flex-end;
    justify-content: left;
  }

  .bl_headerTitle__wLarge > .el_blogTitle:first-child {
    margin-right: 1em;
  }
}

/* PC幅 */
@media screen and (min-width: 1024px){
  .bl_headerMenu.bl_headerMenu__wLarge {
    width: 1024px;
    margin-left: auto;
    margin-right: auto;
  }
}

/* PC幅、タイトル微調整用 */
@media screen and (min-width: 1056px){
  .bl_headerTitle.bl_headerTitle__wLarge {
    width: 1056px;
    margin-left: auto;
    margin-right: auto;
  }
}


/*
*****************************
* Helper                    *
*****************************
*/

.hp_pb2e { padding-bottom: 2em !important; }
.hp_fz1_5e { font-size: 1.5em !important; }

前回作成したレイアウトグループについて、ly_headerpadding-topだけ追加している。

その他は前回通りだ。

では、今回のモジュールグループの詳細を見ていくのだが、まずはブロック単位で見ていこう。

タイトルブロック

ここはブログのメインタイトル、サブタイトルを持つブロックだ。

ここで左右のpaddingを設定しているのは、タブレット幅の時に文字が画面端にくっつくのを避けるためのもの。

…実はこれが原因でちょっとややこしいことをしているが、それは後で紹介する。

さて、デフォルトのスマホ幅ではシンプルに幅を100%にしてあり、中に2つのタイトルをそのまま入れている。

内側のエレメントも見ると、まずメイン、サブともに同じel_blogTitleというクラス名で定義している。

これは、両方とも結局はタイトルを表示するためのものだから同じにしてある。

その中は文字を中央揃えにしているだけだ。

が、メイン側は文字サイズを大きくしたいので、今後解説予定のヘルパーグループのクラスを使用している。

軽く説明してしまうと、ヘルパーとは特定の1プロパティの値を変化させるときに使えるもので、今回は文字サイズを1.5emに変更するヘルパーを作成、メイン側のみに付与している。

また、ヘルパーはもう一つ作成しており、今度はpadding-bottomを2emにするもの。

これをタイトルブロックに付与し、タイトルの下の隙間を確保。

直接タイトルブロックに付与していない理由だが、そもそもブロックは他の場所へ移せるというのが大前提。

そこで移した時のことを考えると、上の余白はこれに付与しているわけではない。

つまり、直接指定してしまうと下だけ余白があることになるのでヘルパーとして切り出した、というわけだ。

これで、スマホ幅のパターンは完成で、メインタイトルの下にサブタイトルが表示され、両方とも中央揃えにできる。

では、タブレット幅以上のパターンを見ていこう。

タブレット幅では、これらを横並びに配置したい。

そのため、タイトルブロックにdisplay: flex;を指定してフレックスボックスに変更している。

配置は左詰めにするのだが、ここで左右のpaddingが効いて、文字が画面端にくっつくことが無くなる。

また、上下の位置についてはalign-items: baseline;を指定し、文字の下端を揃えている。

これはメイン側の文字サイズを変更しているので、しないとサブタイトル側が少し浮いてしまう。

最後、タイトルブロック内にあるエレメントについて、最後の要素以外の右に余白を設ける。

こうすることで、今は二つだがそれ以上になった時にもそれぞれに余白が保たれる、というわけだ。

これでタブレット幅の設定は完了だが、PC幅の場合もこれらの設定を行い、さらに追加している。

PC幅では、左右の余白も考え少し数値が変わっている。

数値以外を見れば、タイトルブロックを特定の大きさにして、左右のmarginautoに、つまりブロックを中央配置にしているだけ。

この数値については、メニューブロックを見た後の方が分かりやすいと思うので後で解説しよう。

以上でタイトル部分の実装は完了。

メニューブロック

次にこちら、メニューブロックだ。

…なのだが、HTMLを見てもらえれば分かると思うが、ブロックの外側に一つbl_headerMenu_wrapperというクラスを付与したdivを追加している。

これが前回の概要で見た汎用的に使える単語というやつで、使っている理由は二つあるが、中身を見てから解説しよう。

このメニューブロックだが、やはりフレックスボックスを使用する。

中のエレメントは全て同じ横幅で実装するため、flex: auto;でOKだ。

その領域をボタンとして扱いたいため、中のaタグをdisplay: block;でブロック要素にし、これでスタイルを調整。

この中身は見てもらえれば分かると思うので省略しよう。

これで、メニュー欄をブロックとして実装できる。

なお、背景色は上にちらっと書いたbl_headerMenu_wrapper側に設定している。

ではレスポンシブデザインを。

まずスマホ幅、これは非表示にしたい。

そこで、bl_headerMenu_wrapperにスマホ幅の時はdisplay: none;を指定して消している。

次にタブレット幅、この時は何もしなくてもOKだ。

上で説明した内容でそのまま実装ができている。

最後にPC幅、この時もシンプルでメニューブロックの横幅を固定、かつ左右中央揃えで完成。

さて、wrapperを使っている理由をそろそろ説明しよう。

一つ目の理由は、背景色だ。

今、PC幅の時はメニュー欄の背景色は画面いっぱいに引き伸ばしたい。

しかし、メニューブロックに背景色を設定してサイズを指定すると、そのサイズまでしか背景色が設定されない。

そのため、このwrapper側で背景色を設定することで、左右に伸ばせるということだ。

二つ目の理由は、スマホ幅の時の非表示を実装するため。

もしデフォルトでdisplay: none;を指定すると、他の場所でも非表示になってしまう。

移植性を保つため、ここはモディファイアでスマホ幅の場合にdisplay: none;としている。

こうすれば、他ではこのモディファイアを外して配置することで問題なくメニューブロックが機能してくれる。

心配なら、例えばメインコンテンツ領域にHTMLをコピーして、モディファイアだけ消して表示してもらうと分かりやすい。

そこでも、しっかりメニューが表示されるようになっている。

…ここまでの内容で少し漏れていたが、基本レスポンシブデザインに関わるものは全てモディファイアを絡ませている

モディファイア名の__wSmallはスマホ幅の時に反映される設定を、__wLargeはタブレット幅以上の時に反映される設定を行っている。

これで、レスポンシブデザインの設定をしているかどうかも分かりやすい。

PC幅のタイトルブロック

さて、最後にPC幅の時のタイトルブロックを見てみよう。

今回、他の場所でやっている1024pxではなく、1056pxを境界として設定している。

この理由はかなり細かいが、タイトルを以下のように配置したいからだ。

  • スマホ幅の時は中央揃え
  • タブレット幅の時は左に余白を設けて左揃え
  • PC幅の時は左端をメニューブロックの左端と合わせて左揃え

ちょっと文字だと分かりづらいので、図で見てみよう。

スマホ幅は関係ないので、タブレットとPC幅を見てみる。

また、分かりやすいようにメニューのaタグ背景を少し変えて表示してみよう。

左がタブレット幅、右がPC幅の時の表示だ。

タブレット幅、PC幅の配置

これでお分かりいただけるだろうか。

タブレット幅の時はしっかり画面から余白を設けて配置する。

PC幅では文字の左端をメニューの左端と合わせる、というのはこういうことだ。

で、これをもし1024pxで切り替えてしまうと、メニューの左端からさらに1文字分、言い換えると16px分右にずれて表示されてしまう。

それを無くすために、1024pxから変えているのだ。

実際、今は左右の両方に16px分、つまり32pxメニューより大きい領域が必要になる。

だから、1024 + 32 = 1056pxを境界として設定している、というわけだ。

非常に細かいところではあるが、こういった意図があって数値を変えているということは認識しておいてほしい。

おわりに

今回はPRECSSのモジュールグループ、具体的にはブロックエレメントモディファイアを解説した。

エレメントはBEMと異なる点モディファイアは今回のモジュールだけでなく他のグループでも可能ということを覚えておこう。

サンプルではヘッダー部分の中身を実装した。

何を実現するために、どういったことをどんな理由でやっているか、あたりを理解しながら進めてもらうといいだろう。

さて、次回はヘルパーグループの解説に進む。

わりと量が少ないので、その次のユニークグループも解説するかもしれない。

サンプルについて、他領域の中身はまた別で実装してみるとしよう。

今回までの内容でもある程度は組めるはずなので、よかったら公式サイトも参照しながら何か作ってみてもらいたい。

コメント

タイトルとURLをコピーしました