こんにちは。
ちゃっかりstand.fmで一人喋りを始めた、どうも柴田です。
さて皆さんはコーディングする時にBootstrapなどのフレームワークなどは使われたりしますでしょうか?
僕は普段 Bootstrap などのフレームワークは使ってないのですが、自分がコーディングしやすいように様々なオリジナルのCSSライブラリを使ってコーディングしていたりします。
例えばWebページ内のレイアウトがグリッドで配置されているデザインの場合は、自分流のグリッドシステムのライブラリを使ってコーディングしています。
今回のこの記事では、そんな俺流フレキシブルCSSグリッドシステムを「Olex」と名付けて、その作り方や使い方を紹介させて頂きます。
- 目次
-
- デモページとコード置き場
- 俺のフレキシブルCSSグリッドシステム「Olex」の概要
- HTMLの構成 – Olex Container と Olex Item を用意。
- Flexible – Flexboxで横並びにさせてみよう。
- Grid – 12列のグリッドシステム。必要なグリッド数を指定してレイアウト。
- Gutter – アイテムの間のスペースを透明なborderで開ける。
- Alignment – 位置揃えも簡単にできるようにしよう。
- Direction – アイテムの並び順も変えられる。
- デモサイトでのOlexの活用
デモページとコード置き場
まずは「olex.css」をフル活用した使ったデモサイトはこちらです。
このページのレイアウトは Olex のみで出来上がっています。(装飾やアニメーションは別)
Olexを使えばこの様なレイアウトのWebページでしたら容易に形にすることができます。
この記事ではそんな俺流のフレキシブルCSSグリッドシステムのコードを解説してますので、是非みなさんもご自身のCSSグリッドシステムを作ってもらえたらと思います。
また、自分で作るのはめんどくさいからOlexのコードだけ知りたいという方に関しましては、一応 GitHubにあげてます。
ですが、できるだけ自分で作ったほうが、理解が深まりますよ。
俺のフレキシブルCSSグリッドシステム「Olex」の概要
Olexは、俺のFlexible CSS Grid System の略で、Webページのレイアウトを比較的簡単に組むことができる僕流、いや俺流のCSSライブラリです。
基本的には Flexbox を使った、ただのCSSなのでそれほど難しいことはしていないです。
ですが、HTMLのカスタムデータ属性を活用し、デザインに合わせて属性値を指定することで複雑なレイアウトも容易に対応できるようになります。
また、ひとつの特徴としてアイテム間のスペースを border
を使って開けていることがひとつポイントになっています。
これにより、よくあるカード型モジュールを等間隔に開けた一覧ページなどで、最後の行だけ半端な数になった時にも、変な両端揃えにならず、左揃えにすることができるほか、スペースの調整も用意することが可能です。
また、スペースの拡張も容易で、より柔軟なデザインに対応することが出来ます。
HTMLの構成 – Olex Container と Olex Item を用意。
「Olex」には Flexbox と同じように、Olex Container(親要素)と Olex Item(子要素)が必要になります。
横並びになるアイテム全体囲む要素が Olex Containerで、各アイテムをOlex Itemとします。
Olex Container には「olex
」、Olex Item には「olex__item
」など、それぞれの役割がわかるClass名を指定します。
サンプルは div
要素で行っておりますが、 他のブロックレベルの要素でも問題ありません。
例えばナビゲーションとかを横並びにする場合は、<ul>
を Olex Container として、<li>
を Olex Item にするとかでも問題ありません。
ただ、何よりも大事なことがあります。
それは、「Olex」という名前は恥ずかしいので、なにかclass名はカッコいい適切なものに変更することです。
Flexible – Flexboxで横並びにさせてみよう。
以前の「Olex」は、display: inline-block
をフル活用して作っていたのですが、今回からは、Flexbox を利用しています。
仕様・考え方
Olex Container に display: flex
を指定して、Olex Itemを横並びにします。
あとは、親要素の幅で折り返してほしいので、flex-wrap: wrap
を指定したり、余計な余白などが開かないように、margin
や padding
を 0
にしてたりします。
Olex Itemには、今の所特に何も必要はないのですが、ボックスのサイズ指定に便利な、box-sizing: border-box
や、余計な余白が開かないように、margin
を 0
にしておくといいです。
また、Olex Item や Olex Itemのさらに子要素の位置揃えなどをするときにも、flexが指定されていると便利なので、僕は Olex Item にも display: flex
を指定して、flex-direction: column
で子要素を縦方向に並べています。
今回このサンプルでは、ベンダープレフィックスなどは書いてませんが、必要に応じでベンダープレフィックスの指定はご自身でお願いします。
これで、Olex Itemは横並びになります。
See the Pen Olex – Step1 by Shiba Hiro (@hilosiva) on CodePen.36915
Grid – 12列のグリッドシステム。必要なグリッド数を指定してレイアウト。
Olexでは、ページ内のあらゆるレイアウトに容易に対応するために、HTMLのカスタムデータ属性で、必要なグリッド数を指定するだけでレイアウトが出来るようなグリッドシステムを採用しています。
仕様・考え方
Olexでは Bootstrap のグリッドシステム同様、12列を基準としたグリッドシステムを採用しています。(12列が嫌だったらご自由にカスタマイズしてくださいね。)
つまり、1列分から12列数分までの幅を指定したスタイルを作成する必要があります。
以前の「Olex」では class属性(modifier)で作ってたのですが、classが散らかるので今回は data-grid
というカスタムデータ属性を用意して作ってみました。(class属性のほうがいい方はカスタマイズしてください。)
1つの data-grid
属性で、各デバイス(ブレークポイント)ごとで異なるレイアウトに対応できるようにするため、各デバイス(ブレークポイント)ごとのグリッド数を半角スペース区切りで指定できるように属性セレクタ([属性名~="属性値"]
)を作ります。
今回は以下のような感じでブレークポイント設定してみました。
サイズ | 想定デバイス |
---|
~767px | スマホ |
768px 〜 1023px | タブレット |
1024px 〜 1199px | ノートPCなど |
1200px 〜 | デスクトップPCなど |
あと、オマケ的に5段組みするためのスタイルや、固定幅じゃなくすためのスタイルも追加しておきましょう。
具体的には以下のように Olex Item に各グリッド(列)の幅を設定するスタイルをブレークポイントごとに追加してみました。
するとこんな感じです。
sp
などのプレフィックスも自由に変えて下さいね。
Bootstrapなどのように xs
、sm
、md
、lg
などのように大きさ別のプレフィックスでもいいと思います。
今回はわかりやすく、デバイスごとのプレフィックスにしてます。
また、このあたり sass を使える方は sass のループを使って書いたら楽だと思います。
これを各ブレークポイントごとに書けばいいですね。
ブレークポイントを mapでまとめて @each
でループしたら一気に書けるかと思います。
Gridの使い方
グリッドシステムを使うには、Olex Itemに data-grid
属性を指定して、そこにデバイス(適用される画面サイズ)ごとのプレフィックスと12 を基準とした必要なグリッド数(列数)を指定してあげればOKですね。
プレフィックス | 適用画面サイズ |
---|
sp | 1px ~ |
tab | 768px ~ |
lap | 1024px ~ |
desk | 1200px ~ |
今回の作り的にはメディアクエリを min-width
しか使ってないので、sp
というプレフィックスはスマホだけじゃなくスマホ以上全てに適用されて、同様にtab
は、タブレット以上全てに適用されるような仕様になってます。
で、例えばどの画面幅でもピッタリ半分半分の2段組みにしたかったら、12分割のグリッドシステムなので、1段につき6グリッド(列)ずつ使えばちょうど半分になるわけです。(12分割 ÷ 2段 = 6グリッド)
なので以下のサンプルのように、data-grid
属性に sp6
と指定すると、どのデバイスでも2つのボックスをちょうど半分ずつにわけることができます。
See the Pen Olex – Grid1 by Shiba Hiro (@hilosiva) on CodePen.36915
このように1行の合計が12グリッドになるように調整するように、グリッド数を指定すればOKです。
なので、3段組みにしたければ、sp4
を3つ並べればいいですし、4段組みにしたければ、sp3
を4つ並べればOKです。sp8
と sp4
などの組み合わせで 12グリッドを使っても大丈夫です。
See the Pen Olex – Grid2 by Shiba Hiro (@hilosiva) on CodePen.36915
で、あとは各デバイス(ブレークポイント)ごとで必要なグリッド数(列数)が異なる場合は、各ブレークポイントごとのプレフィックスとグリッド数(列数)を半角スペース区切りで指定すれば自由にレイアウト可能です。
See the Pen Olex – Grid by Shiba Hiro (@hilosiva) on CodePen.36915
※上記のプレビューの下部にある「0.5×」か「0.25×」を押すとPCでの表示イメージも確認できます。
このようにすることで、各デバイスごとに異なるレイアウトであっても容易にレイアウト可能です。
もちろん、入れ子にすることもできるので、まずは大きく画面を半々に分けて、そこからその中で更に12分割のグリッドを利用することも可能です。
また、5段組にする場合は、「spFive
」や「tabFive
」 などのように、プレフィックスの後ろに「Five」を付けることで実装できます。
「lapAuto
」などのように、プレフィックスの後ろに「Auto」を付けることで、ノートPC以上では要素の幅に合わせるなんてこともできます。
Gutter – アイテムの間のスペースを透明なborderで開ける。
各Olex Item間にスペースを開けることができるようにしましょう。
仕様・考え方
今回は、Olex Containerに data-gutter
というカスタムデータ属性を指定することでスペースを開けれるようにしようと思います。
通常こういったスペースは margin
を使って開けると思いますが、Olexは各アイテム間の間隔を border
を使って指定しています。
これによって、スペース量によってOlex Itemの幅を計算しなくていいようにしています。
どういうことかと言うと、通常 margin
でスペースを開けると、例えbox-sizing
を border-box
にしていても、margin
は width
より外に付くことになります。
つまりもし、2段組みのアイテム(sp6
が指定されてるボックス× 2)の間に 10px のスペースを開けたいとした場合、sp6
には width: 50%
が指定されていてるので、その時点でこの2つのボックスの幅は100%になってしまいます。
そして、10px のmargin
はその外に付くことになるので、 100% を超えてしまい、2つめのボックスは下の行に落ちてしまうんです。
なのでもし margin
でスペースを開ける場合は、それに応じてwidth
を調整する必要があります。
でもそこを border
にすることで、box-sizing
が border-box
であれば、このborder
の量は width
の中に含まれることになるので、各アイテムのwidth
を変更しなくても、border
分のスペースをあけることが出来るんです。
これにより、スペースの量をどんだけ変更しても、width
を変更する必要がないので、拡張性があるんです。
なので、小さいスペース用、大きいスペース用などのスタイルを書いておけば、いろんなサイズのスペースにも対応できたりします。
で、border
の付け方なんですが、.olex__item
に 透明のボーダーを上下左右全てに指定します。
この時ポイントは、スペースとして開けたい量の半分のサイズを指定します。
つまりもし各アイテム間のスペースを 16px 開けたかったとしたら、その半分の8pxのborder
を指定します。
こうすることで、各アイテムをグリッド上に配置する時にお互いのボーダーが隣接するので、結果 8px のborder
どおしがぶつかって、16px のスペースになるんです。
でもこのままじゃ、先頭の列にあるアイテムの左側や、先頭の行にあるアイテムの上側、最後の列にあるアイテムの右や最後の行にあるアイテムの下に不必要なborder
が付いてしまいますので、そこを調整します。
その調整は、Olex Container側でやります。
具体的には、.olex
に 不要なborder
分のネガティブマージンを指定します。
これで、その不要なボーダーを相殺するというテクニックです。
今回は以下の3種類のスペースを用意してみましょうか。
ただ、ここは案件ごとに調整が必要になると思いますので、案件ごとに自由にカスタマイズしてくださいね。
属性値 | スペース量 |
---|
small | スマホ:2.5vw / タブレット以上:1vw |
normal | スマホ:5vw / タブレット以上2vw |
large | スマホ:7.5vw / タブレット以上:3vw |
今回は手軽に vw
を使ってブラウザの幅でスペース量を調整するようにしますが、案件によっては、各デバイスごとにスペース量が違ったり、様々なスペース量が登場すると思います。
そのあたりはデザインに合わせて 単位はもちろん、メディアクエリによる記述など柔軟にカスタマイズしてもらえたらと思います。
ただこのままだと、もし .olex__item
に background
を指定したら、border
の部分にまで背景が付いちゃうので、結局スペースに見えなくなってしまいます。
そこで、background-clip: padding-box
を指定して、背景はpadding
のエリアにしか付かないようにしておきます。
つまりこんな感じで、スタイルを追加します。
これももっとカスタマイズして、グリッドの指定のように各ブレークポイントごとにスペース量を付け替えれるようにするのもいいかもですね。
きっとそのほうが柔軟にデザインに対応できると思います。
なので、このあたりも sass が使える方は、変数やらmapやらでスペースのサイズを管理して、容易に変更できるようにしたりしておくといいと思いますよ。
Gutter の使い方
このアイテム間のスペースを指定する場合は、Olex Container にdata-gutter
属性を指定し、その属性値でスペースの大きさを、small
、normal
、large
の中から選んで指定すれば適用できます。
属性値 | スペース量 |
---|
small | スマホ:2.5vw / タブレット以上:1vw |
normal | スマホ:5vw / タブレット以上2vw |
large | スマホ:7.5vw / タブレット以上:3vw |
例えば、normal
サイズのスペースを開けたい場合は以下のようになります。
See the Pen Olex – Gutter by Shiba Hiro (@hilosiva) on CodePen.36915
※上記のプレビューの下部にある「0.5×」か「0.25×」を押すとPCでの表示イメージも確認できます。
という感じ です。
あとは、スペースのサイズをデザインに合わせて変更したり拡張したりカスタマイズしてください。
Alignment – 位置揃えも簡単にできるようにしよう。
「各アイテムを右端に揃えたい」や「中央で揃えたい」などのように水平方向の位置揃えがしたい時や、各アイテムの高さが違う時に、アイテムを天地中央で揃えたり、下で揃えたりしたい時があると思います。
そういう時に対応できるように、位置揃えも簡単にできるようにしてみましょうか。
仕様・考え方
位置揃えも、data-align
というカスタムデータ属性で設定できるようにしてみましょう。
すでに Olex Container とOlex Itemのどちらにも、display: flex
を指定しているのでこれらは容易にできます。
Olex Item 全てを一気に水平方向で揃えるには、Olex Container に justify-content
を使えば対応できて、水平方向で揃えるには、align-items
を使えば対応できます。
また、Olex Item を個別に調整する場合ですが、Olex Item には、flex-direction: column
が指定されているので、水平方向の位置揃えには align-items
を使い、垂直方向の位置揃えには justify-content
を使います。
では、data-align
という属性を用意して、各位置揃えのスタイルを追加して行きます。
Alignment の使い方
位置揃えをするときは、data-align
属性を使います。
Olex Container に使う場合は Olex Item 全体の水平方向や垂直方向の位置揃えができます。
水平方向や垂直方向の位置揃えは、組み合わせて使うことが可能です。
属性値 | 役割 |
---|
start | 左揃え(逆順の時は右) |
center | 中央揃え |
end | 右揃え(逆順の時は左) |
justify | 両端揃え |
top | 上揃え |
middle | 垂直方向の中央揃え |
bottom | 下揃え |
水平方向の指定と垂直方向を両方指定する場合は、半角スペースで区切って指定してください
See the Pen Olex – Align1 by Shiba Hiro (@hilosiva) on CodePen.36915
Olex Item に使う場合は、そのアイテムのみの位置揃えが可能で、水平方向と垂直方向のどちらも使えますし、組み合わせて使うことも可能です。
属性値 | 役割 |
---|
start | 左揃え(逆順の時は右) |
center | 水平方向の中央揃え |
end | 右揃え(逆順の時は左) |
top | 上揃え |
middle | 垂直方向の中央揃え |
bottom | 下揃え |
水平方向の指定と垂直方向を両方指定する場合は、半角スペースで区切って指定してください。
See the Pen Olex – Align2 by Shiba Hiro (@hilosiva) on CodePen.36915
このように左に高さのあるコンテンツ(写真など)があり、右側のコンテンツがその左側の高さに対して天地中央に配置するなども可能です。
Direction – アイテムの並び順も変えられる。
Webデザインによっては、スマホでは「見出し」→「テキスト」→「画像」の順番で見せたいけど、PCでは画像を先に見せたいなどということもあると思います。
こういうケースにも対応できるようにOlex Itemの並び順を変更できるようにもしましょう。
仕様・考え方
並び順は data-dir
というカスタムデータ属性で対応しようかと思います。
これも Olex Container 、Olex Itemのどちらもに display: flex
が指定されいるので、flex-direction
や order
などを活用することで容易に対応できます。
今回は Olex Container に flex-direction
を使って 全てのOlex Item を一気に並び替えれるようにしようと思います。
なお、Olex Itemを個別に並び替えれるようにするには、order
を活用してカスタマイズしてもらえればと思います。
ということで、以下のようなスタイルを追加していきます。
Direction の使い方
並び順を変えたい場合は、data-dir
属性で並び順を指定します。
See the Pen Olex – Order by Shiba Hiro (@hilosiva) on CodePen.36915
※上記のプレビューの下部にある「0.5×」か「0.25×」などを押すとPCでの表示イメージも確認できます。
デモサイトでのOlexの活用
デモサイトで利用しているような使い方をいくつか抜粋して紹介します。
header部分
このようなヘッダーのデザインは多いと思います。
デモサイトの様なヘッダー(このサンプルではPCのみ)を作る場合は以下の様なHTMLの構成にするとレイアウト可能です。
まずはロゴ部分とナビ部分を Olex Item にして、Olex Container に data-align
属性で justify
(両端揃え) を指定して配置してます。
そして、ナビ部分のOlex Item の中に更に ul
要素に olex
classと余白を開けるため data-gutter
属性に normal
を指定し、li
要素に olex__item
を指定して、各ナビのアイテムを横並びにしています。
See the Pen Olex – Demo1 by Shiba Hiro (@hilosiva) on CodePen.36915
※上記のプレビューの下部にある「0.5×」か「0.25×」を押すとPCでの表示イメージも確認できます。
Feature 部分
デモサイトの「Feature」部分は、スマホ、タブレット、PCでレイアウトがちょこちょこ変わる部分で、まず「Feature」という見出しのボックスを div で囲って olex__item
を 、各特徴部分(「Grid」、「Alignment」、「Direction」)のボックスにも olex__item
を指定して Olex Item を分けています。
そして、各特徴部分のOlex Itemの中に、更にOlex を入れ子にして、各特徴のボックスをそれぞれ Olex Item にしています。
あとは、スマホ時にはすべてが縦に並ぶようにして、タブレットでは「Feature」のボックスは上に、各特徴のボックスは3段組みに横並びにして、大きなPCで見た時は、「Feature」のボックスも横に並んで、4段組みに見えるように data-grid
属性を指定しています。
See the Pen OLex – Demo2 by Shiba Hiro (@hilosiva) on CodePen.36915
※上記のプレビューの下部にある「0.5×」か「0.25×」を押すとPCでの表示イメージも確認できます。
Grid の Flexible 部分
デモサイトの「Grid」の「Flexible」もOlexを入れ子で使ってます。
まず「Flexibie」の見出しがあるエリアと、写真のエリアそれぞれ Olex Itemとして配置しています。
そして、data-dir
属性を使って、逆順にすることで写真のエリアを左に持ってきてます。
そして、その写真のエリアの中にガターなしの Olex Container を配置し各写真をOlex Itemとしています。
あとは、data-grid
属性を活用して各デバイスごとにグリッドを調整してこのレイアウトを行っています。
See the Pen Olex – Demo3 by Shiba Hiro (@hilosiva) on CodePen.36915
※上記のプレビューの下部にある「0.5×」か「0.25×」を押すとPCでの表示イメージも確認できます。
まとめ
如何でしたでしょうか?
この記事を書くより、デモサイトを作るほうが時間がかかってしまいましたw
ただ、こんな感じで僕はオリジナルのCSSグリッドシステムを作って使っています。
もしよかったら皆さんも作ってみてもらえたらと思います。
あ、大事なことなのでもう一度お伝えしておきますね。
「Olex」という名前は恥ずかしいので、ご自身で適切な名前に変更して作ってくださいね。
一応、すでに出来上がってるコードもGitHubに置いておきますね。
また、Shibajukuの中ではより詳細なOlexの使い方に関する解説などもしてますので、よかったら覗いてみてください。
では。