オリジナルのフレキシブルCSSグリッドシステムを作ってみよう。

こんにちは。

ちゃっかりstand.fmで一人喋りを始めた、どうも柴田です。

さて皆さんはコーディングする時にBootstrapなどのフレームワークなどは使われたりしますでしょうか?

僕は普段 Bootstrap などのフレームワークは使ってないのですが、自分がコーディングしやすいように様々なオリジナルのCSSライブラリを使ってコーディングしていたりします。

例えばWebページ内のレイアウトがグリッドで配置されているデザインの場合は、自分流のグリッドシステムのライブラリを使ってコーディングしています。

今回のこの記事では、そんな俺流フレキシブルCSSグリッドシステムを「Olex」と名付けて、その作り方や使い方を紹介させて頂きます。

目次
  1. デモページとコード置き場
  2. 俺のフレキシブルCSSグリッドシステム「Olex」の概要
  3. HTMLの構成 – Olex Container と Olex Item を用意。
  4. Flexible – Flexboxで横並びにさせてみよう。
  5. Grid – 12列のグリッドシステム。必要なグリッド数を指定してレイアウト。
  6. Gutter – アイテムの間のスペースを透明なborderで開ける。
  7. Alignment – 位置揃えも簡単にできるようにしよう。
  8. Direction – アイテムの並び順も変えられる。
  9. デモサイトでの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名を指定します。

sample.html
<div class="olex">
  <div class="olex__item">...</div>
  <div class="olex__item">...</div>
  <div class="olex__item">...</div>
  <div class="olex__item">...</div>
</div>

サンプルは 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 を指定したり、余計な余白などが開かないように、marginpadding0 にしてたりします。

Olex Itemには、今の所特に何も必要はないのですが、ボックスのサイズ指定に便利な、box-sizing: border-box や、余計な余白が開かないように、margin0 にしておくといいです。

また、Olex Item や Olex Itemのさらに子要素の位置揃えなどをするときにも、flexが指定されていると便利なので、僕は Olex Item にも display: flex を指定して、flex-direction: column で子要素を縦方向に並べています。

今回このサンプルでは、ベンダープレフィックスなどは書いてませんが、必要に応じでベンダープレフィックスの指定はご自身でお願いします。

olex.css
.olex {
  display: flex;
  flex-wrap: wrap;
  margin: 0;
  padding: 0;
}

.olex__item {
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  margin: 0;
}

これで、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スマホ
768px1023pxタブレット
1024px1199pxノートPCなど
1200pxデスクトップPCなど

あと、オマケ的に5段組みするためのスタイルや、固定幅じゃなくすためのスタイルも追加しておきましょう。

具体的には以下のように Olex Item に各グリッド(列)の幅を設定するスタイルをブレークポイントごとに追加してみました。

olex.css
/*
  Grid
*/
.olex__item[data-grid~="sp1"] {
  width: 8.33333%;
}

.olex__item[data-grid~="sp2"] {
  width: 16.66667%;
}

.olex__item[data-grid~="sp3"] {
  width: 25%;
}

.olex__item[data-grid~="sp4"] {
  width: 33.33333%;
}

.olex__item[data-grid~="sp5"] {
  width: 41.66667%;
}

.olex__item[data-grid~="sp6"] {
  width: 50%;
}

.olex__item[data-grid~="sp7"] {
  width: 58.33333%;
}

.olex__item[data-grid~="sp8"] {
  width: 66.66667%;
}

.olex__item[data-grid~="sp9"] {
  width: 75%;
}

.olex__item[data-grid~="sp10"] {
  width: 83.33333%;
}

.olex__item[data-grid~="sp11"] {
  width: 91.66667%;
}

.olex__item[data-grid~="sp12"] {
  width: 100%;
}

.olex__item[data-grid~="spFive"] {
  width: 20%;
}

.olex__item[data-grid~="spAuto"] {
  width: auto;
}

@media screen and (min-width: 768px) {

  .olex__item[data-grid~="tab1"] {
    width: 8.33333%;
  }
  .olex__item[data-grid~="tab2"] {
    width: 16.66667%;
  }
  .olex__item[data-grid~="tab3"] {
    width: 25%;
  }
  .olex__item[data-grid~="tab4"] {
    width: 33.33333%;
  }
  .olex__item[data-grid~="tab5"] {
    width: 41.66667%;
  }
  .olex__item[data-grid~="tab6"] {
    width: 50%;
  }
  .olex__item[data-grid~="tab7"] {
    width: 58.33333%;
  }
  .olex__item[data-grid~="tab8"] {
    width: 66.66667%;
  }
  .olex__item[data-grid~="tab9"] {
    width: 75%;
  }
  .olex__item[data-grid~="tab10"] {
    width: 83.33333%;
  }
  .olex__item[data-grid~="tab11"] {
    width: 91.66667%;
  }
  .olex__item[data-grid~="tab12"] {
    width: 100%;
  }
  .olex__item[data-grid~="tabFive"] {
    width: 20%;
  }
  .olex__item[data-grid~="tabAuto"] {
    width: auto;
  }
}

@media screen and (min-width: 1024px) {

  .olex__item[data-grid~="lap1"] {
    width: 8.33333%;
  }
  .olex__item[data-grid~="lap2"] {
    width: 16.66667%;
  }
  .olex__item[data-grid~="lap3"] {
    width: 25%;
  }
  .olex__item[data-grid~="lap4"] {
    width: 33.33333%;
  }
  .olex__item[data-grid~="lap5"] {
    width: 41.66667%;
  }
  .olex__item[data-grid~="lap6"] {
    width: 50%;
  }
  .olex__item[data-grid~="lap7"] {
    width: 58.33333%;
  }
  .olex__item[data-grid~="lap8"] {
    width: 66.66667%;
  }
  .olex__item[data-grid~="lap9"] {
    width: 75%;
  }
  .olex__item[data-grid~="lap10"] {
    width: 83.33333%;
  }
  .olex__item[data-grid~="lap11"] {
    width: 91.66667%;
  }
  .olex__item[data-grid~="lap12"] {
    width: 100%;
  }
  .olex__item[data-grid~="lapFive"] {
    width: 20%;
  }
  .olex__item[data-grid~="lapAuto"] {
    width: auto;
  }
}

@media screen and (min-width: 1200px) {
  .olex__item[data-grid~="desk1"] {
    width: 8.33333%;
  }
  .olex__item[data-grid~="desk2"] {
    width: 16.66667%;
  }
  .olex__item[data-grid~="desk3"] {
    width: 25%;
  }
  .olex__item[data-grid~="desk4"] {
    width: 33.33333%;
  }
  .olex__item[data-grid~="desk5"] {
    width: 41.66667%;
  }
  .olex__item[data-grid~="desk6"] {
    width: 50%;
  }
  .olex__item[data-grid~="desk7"] {
    width: 58.33333%;
  }
  .olex__item[data-grid~="desk8"] {
    width: 66.66667%;
  }
  .olex__item[data-grid~="desk9"] {
    width: 75%;
  }
  .olex__item[data-grid~="desk10"] {
    width: 83.33333%;
  }
  .olex__item[data-grid~="desk11"] {
    width: 91.66667%;
  }
  .olex__item[data-grid~="desk12"] {
    width: 100%;
  }
  .olex__item[data-grid~="deskFive"] {
    width: 20%;
  }
  .olex__item[data-grid~="deskAuto"] {
    width: auto;
  }
}

するとこんな感じです。

spなどのプレフィックスも自由に変えて下さいね。

Bootstrapなどのように xssmmdlg などのように大きさ別のプレフィックスでもいいと思います。

今回はわかりやすく、デバイスごとのプレフィックスにしてます。

また、このあたり sass を使える方は sass のループを使って書いたら楽だと思います。

olex.scss
$column: 12;  // グリッド数の設定

.olex {
  &__item {
    @for $i from 1 through $column {
      &[data-grid~="sp#{$i}"] {
        width: percentage($i / $column);
      }
    }
  }
}

これを各ブレークポイントごとに書けばいいですね。

ブレークポイントを mapでまとめて @each でループしたら一気に書けるかと思います。

Gridの使い方

グリッドシステムを使うには、Olex Itemに data-grid 属性を指定して、そこにデバイス(適用される画面サイズ)ごとのプレフィックスと12 を基準とした必要なグリッド数(列数)を指定してあげればOKですね。

プレフィックス適用画面サイズ
sp1px ~
tab768px ~
lap1024px ~
desk1200px ~

今回の作り的にはメディアクエリを min-width しか使ってないので、spというプレフィックスはスマホだけじゃなくスマホ以上全てに適用されて、同様にtab は、タブレット以上全てに適用されるような仕様になってます。

で、例えばどの画面幅でもピッタリ半分半分の2段組みにしたかったら、12分割のグリッドシステムなので、1段につき6グリッド(列)ずつ使えばちょうど半分になるわけです。(12分割 ÷ 2段 = 6グリッド)

なので以下のサンプルのように、data-grid属性に sp6 と指定すると、どのデバイスでも2つのボックスをちょうど半分ずつにわけることができます。

sample.html
<div class="olex">
  <div class="olex__item" data-grid="sp6">
    ...
  </div>
  <div class="olex__item" data-grid="sp6">
    ...
  </div>
</div>

See the Pen Olex – Grid1 by Shiba Hiro (@hilosiva) on CodePen.36915

このように1行の合計が12グリッドになるように調整するように、グリッド数を指定すればOKです。

なので、3段組みにしたければ、sp4 を3つ並べればいいですし、4段組みにしたければ、sp3 を4つ並べればOKです。sp8sp4 などの組み合わせで 12グリッドを使っても大丈夫です。

sample.html
<div class="olex">
  <div class="olex__item" data-grid="sp4">
    <div class="box">Box1</div>
  </div>
  <div class="olex__item" data-grid="sp4">
    <div class="box">Box2</div>
  </div>
  <div class="olex__item" data-grid="sp4">
    <div class="box">Box3</div>
  </div>
  <div class="olex__item" data-grid="sp3">
    <div class="box">Box4</div>
  </div>
  <div class="olex__item" data-grid="sp3">
    <div class="box">Box5</div>
  </div>
  <div class="olex__item" data-grid="sp3">
    <div class="box">Box6</div>
  </div>
  <div class="olex__item" data-grid="sp3">
    <div class="box">Box7</div>
  </div>
  <div class="olex__item" data-grid="sp8">
    <div class="box">Box8</div>
  </div>
  <div class="olex__item" data-grid="sp4">
    <div class="box">Box9</div>
  </div>

</div>

See the Pen Olex – Grid2 by Shiba Hiro (@hilosiva) on CodePen.36915

で、あとは各デバイス(ブレークポイント)ごとで必要なグリッド数(列数)が異なる場合は、各ブレークポイントごとのプレフィックスとグリッド数(列数)を半角スペース区切りで指定すれば自由にレイアウト可能です。

sample.html
<div class="olex">
  <div class="olex__item" data-grid="sp12 tab4 lap6">
    ...
  </div>
  <div class="olex__item" data-grid="sp6 tab4 lap3">
    ...
  </div>
  <div class="olex__item" data-grid="sp6 tab4 lap3">
    ...
  </div>
</div>

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-sizingborder-box にしていても、marginwidth より外に付くことになります。

つまりもし、2段組みのアイテム(sp6 が指定されてるボックス× 2)の間に 10px のスペースを開けたいとした場合、sp6 には width: 50% が指定されていてるので、その時点でこの2つのボックスの幅は100%になってしまいます。

そして、10px のmarginはその外に付くことになるので、 100% を超えてしまい、2つめのボックスは下の行に落ちてしまうんです。

なのでもし margin でスペースを開ける場合は、それに応じてwidthを調整する必要があります。

でもそこを border にすることで、box-sizingborder-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__itembackground を指定したら、borderの部分にまで背景が付いちゃうので、結局スペースに見えなくなってしまいます。

そこで、background-clip: padding-box を指定して、背景はpadding のエリアにしか付かないようにしておきます。

つまりこんな感じで、スタイルを追加します。

olex.css
/* Gutter */ 
.olex[data-gutter] {
  width: auto;
}

.olex[data-gutter] > .olex__item {
  border: solid transparent;
  background-clip: padding-box;
}


.olex[data-gutter="small"] {
  margin: -1.25vw;
}

.olex[data-gutter="small"] > .olex__item {
  border-width: 1.25vw;
}

.olex[data-gutter="normal"] {
  margin: -2.5vw;
}

.olex[data-gutter="normal"] > .olex__item {
  border-width: 2.5vw;
}

.olex[data-gutter="large"] {
  margin: -3.75vw;
}

.olex[data-gutter="large"] > .olex__item {
  border-width: 3.75vw;
}

@media screen and (min-width: 768px) {
  .olex[data-gutter="small"] {
    margin: -0.5vw;
  }

  .olex[data-gutter="small"] > .olex__item {
    border-width: 0.5vw;
  }
  .olex[data-gutter="normal"] {
    margin: -1vw;
  }

  .olex[data-gutter="normal"] > .olex__item {
    border-width: 1vw;
  }

  .olex[data-gutter="large"] {
    margin: -1.5vw;
  }

  .olex[data-gutter="large"] > .olex__item {
    border-width: 1.5vw;
  }

}

これももっとカスタマイズして、グリッドの指定のように各ブレークポイントごとにスペース量を付け替えれるようにするのもいいかもですね。

きっとそのほうが柔軟にデザインに対応できると思います。

なので、このあたりも sass が使える方は、変数やらmapやらでスペースのサイズを管理して、容易に変更できるようにしたりしておくといいと思いますよ。

olex.scss
// Gutter Size
$gutters: (
  "small": 1vw,
  "normal": 2vw,
  "large": 3vw,
) !default;


.olex {
  &[data-gutter] {
    width: auto;

    & > .olex__item {
      border: solid transparent;
      background-clip: padding-box;
    }
  }

  @each $size, $val in $gutters {
    &[data-gutter="#{$size}"] {
      margin: -($val  / 2);

      & > .olex__item {
        border-width: ($val  / 2);
      }
    }
  }
}

Gutter の使い方

このアイテム間のスペースを指定する場合は、Olex Container にdata-gutter属性を指定し、その属性値でスペースの大きさを、smallnormallarge の中から選んで指定すれば適用できます。

属性値スペース量
smallスマホ:2.5vw / タブレット以上:1vw
normalスマホ:5vw / タブレット以上2vw
largeスマホ:7.5vw / タブレット以上:3vw

例えば、normal サイズのスペースを開けたい場合は以下のようになります。

sample.html
<div class="olex" data-gutter="normal">
  <div class="olex__item" data-grid="sp4">
    <div class="box">Box1</div>
  </div>
  <div class="olex__item" data-grid="sp4">
    <div class="box">Box2</div>
  </div>
  <div class="olex__item" data-grid="sp4">
    <div class="box">Box3</div>
  </div>
  <div class="olex__item" data-grid="sp3">
    <div class="box">Box4</div>
  </div>
  <div class="olex__item" data-grid="sp3">
    <div class="box">Box5</div>
  </div>
  <div class="olex__item" data-grid="sp3">
    <div class="box">Box6</div>
  </div>
  <div class="olex__item" data-grid="sp3">
    <div class="box">Box7</div>
  </div>
  <div class="olex__item" data-grid="sp8">
    <div class="box">Box8</div>
  </div>
  <div class="olex__item" data-grid="sp4">
    <div class="box">Box9</div>
  </div>
</div>

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という属性を用意して、各位置揃えのスタイルを追加して行きます。

olex.css
/*
  Align 
*/

.olex[data-align~="start"] {
  justify-content: flex-start;
}

.olex[data-align~="center"] {
  justify-content: center;
}

.olex[data-align~="end"] {
  justify-content: flex-end;
}

.olex[data-align~="justify"] {
  justify-content: space-between;
}

.olex[data-align~="top"] {
  align-items: flex-start;
}

.olex[data-align~="middle"] {
  align-items: center;
}

.olex[data-align~="bottom"] {
  align-items: flex-end;
}

.olex__item[data-align~="start"] {
  align-items: flex-start;
}

.olex__item[data-align~="center"] {
  align-items: center;
}

.olex__item[data-align~="end"] {
  align-items: flex-end;
}

.olex__item[data-align~="top"] {
  justify-content: flex-start;
}

.olex__item[data-align~="middle"] {
  justify-content: center;
}

.olex__item[data-align~="bottom"] {
   justify-content: flex-end;
}

Alignment の使い方

位置揃えをするときは、data-align属性を使います。

Olex Container に使う場合は Olex Item 全体の水平方向や垂直方向の位置揃えができます。

水平方向や垂直方向の位置揃えは、組み合わせて使うことが可能です。

属性値役割
start左揃え(逆順の時は右)
center中央揃え
end右揃え(逆順の時は左)
justify両端揃え
top上揃え
middle垂直方向の中央揃え
bottom下揃え

水平方向の指定と垂直方向を両方指定する場合は、半角スペースで区切って指定してください

sample.html
<div class="olex" data-align="end">
  <div class="olex__item">
    <div class="box">Box1</div>
  </div>
  <div class="olex__item">
    <div class="box">Box2</div>
  </div>
  <div class="olex__item">
    <div class="box">Box3</div>
  </div>
</div>

See the Pen Olex – Align1 by Shiba Hiro (@hilosiva) on CodePen.36915

Olex Item に使う場合は、そのアイテムのみの位置揃えが可能で、水平方向と垂直方向のどちらも使えますし、組み合わせて使うことも可能です。

属性値役割
start左揃え(逆順の時は右)
center水平方向の中央揃え
end右揃え(逆順の時は左)
top上揃え
middle垂直方向の中央揃え
bottom下揃え

水平方向の指定と垂直方向を両方指定する場合は、半角スペースで区切って指定してください。

sample.html
<div class="olex">
  <div class="olex__item" data-grid="sp6">
    <div class="box large">Box1</div>
  </div>
  <div class="olex__item" data-grid="sp6" data-align="center middle">
    <div class="box">Box2</div>
  </div>
</div>

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-directionorder などを活用することで容易に対応できます。

今回は Olex Container に flex-direction を使って 全てのOlex Item を一気に並び替えれるようにしようと思います。

なお、Olex Itemを個別に並び替えれるようにするには、order を活用してカスタマイズしてもらえればと思います。

ということで、以下のようなスタイルを追加していきます。

olex.css
 /* 
  Order 
*/
.olex[data-dir="normal"] {
  flex-direction: row;
}

.olex[data-dir="reverse"] {
  flex-direction: row-reverse;
}

Direction の使い方

並び順を変えたい場合は、data-dir 属性で並び順を指定します。

属性値役割
normal通常
reverse逆順
sample.html
<div class="olex" data-dir="reverse">
  <div class="olex__item" data-grid="sp6">
    Box1
  </div>
  <div class="olex__item"  data-grid="sp6">
    Box2
  </div>
</div>

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 を指定して、各ナビのアイテムを横並びにしています。

sample.html
<header>
  <div class="l-container">

    <div class="olex" data-align="justify">
      <div class="olex__item" data-align="middle">
        <h1 >
          <a href="/">Olex.css</a>
        </h1>
      </div>
      <!-- /.olex__item -->

      <div class="olex__item">
        <nav>
          <ul class="olex" data-gutter="normal" data-align="middle">
            <li class="olex__item">
              <a href="#overview">Overview</a>
            </li>
            <li class="olex__item">
              <a href="#grid">Grid</a>
            </li>
            <li class="olex__item">
              <a href="#alignment">Alignment</a>
            </li>
            <li class="olex__item">
              <a href="#direction">Direction</a>
            </li>
            <li class="olex__item">
              <a href="https://shibajuku.net/olex/" target="_blank">How to Make</a>
            </li>
          </ul>
          <!-- /.olex -->
        </nav>
      </div>
      <!-- /.olex__item -->
    </div>
    <!-- /.olex -->
  </div>
  <!-- /.l-container -->
</header>

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属性を指定しています。

sample.html
<section class="l-spacer">
  <div class="l-container">

    <div class="olex" data-gutter="normal">
      <div class="olex__item" data-grid="desk3">

        <h3 lang="en">Feature</h3>
        <p>
          Flexboxを利用したグリッドシステムで、単なる横並びや12カラムをベースとしたグリッドレイアウトも可能です。グリッド間のスペースにはborderを利用していて間隔の調整が容易にできます。もちろんこのページのレイアウトは「Olex.css」を使っているので、詳しくはデベロッパーツールで。
        </p>

      </div>
      <!-- /.olex__item -->

      <div class="olex__item" data-grid="desk9">
        <div class="olex" data-gutter="normal">

          <section class="olex__item" data-grid="sp12 tab4">

            <div class="c-card p-feature">
              <img src="https://shibajuku.net/demo/olex/assets/img/icon-grid.svg" alt="" />
              <h4 class="p-feature__title">Grid</h4>
              <p class="p-feature__text">12カラムを基準としたグリッドシステム。</p>
            </div>
            <!-- /.c-card -->

          </section>
          <section class="olex__item" data-grid="sp12 tab4">

            <div class="c-card p-feature">
              <img src="https://shibajuku.net/demo/olex/assets/img/icon-alignment.svg" alt="" />
              <h4 class="p-feature__title">Alignment</h4>
              <p class="p-feature__text">各アイテムの位置を揃えることもできる。</p>
            </div>
            <!-- /.c-card -->

          </section>
          <section class="olex__item" data-grid="sp12 tab4">

            <div class="c-card p-feature">
              <img src="https://shibajuku.net/demo/olex/assets/img/icon-dir.svg" alt="" />
              <h4 class="p-feature__title">Direction</h4>
              <p class="p-feature__text">アイテムの並び順を逆順に変更できる。</p>
            </div>
            <!-- /.c-card -->

          </section>
        </div>
        <!-- /.olex -->
      </div>
      <!-- /.olex__item -->
    </div>
    <!-- /.olex -->

  </div>
  <!-- /.l-container -->
</section>
<!-- /.l-spacer -->

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属性を活用して各デバイスごとにグリッドを調整してこのレイアウトを行っています。

sample.html
<div class="olex" data-gutter="normal" data-dir="reverse">

  <div class="olex__item" data-grid="sp12 lap4">  
   <h3 lang="en">Flexible</h3>
   <p class="c-detail">
     スマホ、タブレット、PCで異なるカラムのレイアウトも容易に対応できます。 12カラムをベースとして、必要なカラム数をカスタムデータ属性で指定するだけでレイアウトが可能。
    </p>
  </div>
  <div class="olex__item" data-grid="sp12 lap8">
    <ul class="olex">
      <li class="olex__item" data-grid="sp6">
        <figure>
          <img src="assets/img/img-kyoto1.jpg" alt="" />
          <figcaption>SP: 6/12 - TAB: 6/12</figcaption>
        </figure>
        <!-- /.c-card -->
      </li>
      <li class="olex__item" data-grid="sp6">
        <figure>
          <img src="assets/img/img-kyoto2.jpg" alt="" />
          <figcaption>SP: 6/12 - TAB: 6/12</figcaption>
        </figure>
        <!-- /.c-card -->
      </li>
      <li class="olex__item" data-grid="sp6 tab3">
        <figure>
          <img src="assets/img/img-kyoto3.jpg" alt="" />
          <figcaption>SP: 6/12 - TAB: 3/12</figcaption>
        </figure>
        <!-- /.c-card -->
      </li>
      <li class="olex__item" data-grid="sp6 tab3">
        <figure>
          <img src="assets/img/img-kyoto4.jpg" alt="" />
          <figcaption>SP: 6/12 - TAB: 3/12</figcaption>
        </figure>
        <!-- /.c-card -->
      </li>
      <li class="olex__item" data-grid="sp6 tab3">
        <figure>
          <img src="assets/img/img-kyoto5.jpg" alt="" />
          <figcaption>SP: 6/12 - TAB: 3/12</figcaption>
        </figure>
        <!-- /.c-card -->
      </li>
      <li class="olex__item" data-grid="sp6 tab3">
        <figure>
          <img src="assets/img/img-kyoto6.jpg" alt="" />
          <figcaption>SP: 6/12 - TAB: 3/12</figcaption>
        </figure>
        <!-- /.c-card -->
      </li>
      <li class="olex__item" data-grid="sp12 tab8">
        <figure>
          <img src="assets/img/img-kyoto7.jpg" alt="" />
          <figcaption>SP: 12/12 - TAB: 8/12</figcaption>
        </figure>
        <!-- /.c-card -->
      </li>
      <li class="olex__item" data-grid="sp6 tab4">
        <figure>
          <img src="assets/img/img-kyoto8.jpg" alt="" />
          <figcaption>SP: 6/12 - TAB: 4/12</figcaption>
        </figure>
        <!-- /.c-card -->
      </li>

      <li class="olex__item" data-grid="sp6 tab4">
        <figure>
          <img src="assets/img/img-kyoto9.jpg" alt="" />
          <figcaption>SP: 6/12 - TAB: 4/12</figcaption>
        </figure>
        <!-- /.c-card -->
      </li>
      <li class="olex__item" data-grid="sp12 tab8">
        <figure>
          <img src="assets/img/img-kyoto10.jpg" alt="" />
          <figcaption>SP: 12/12 - TAB: 8/12</figcaption>
        </figure>
        <!-- /.c-card -->
      </li>
      <li class="olex__item" data-grid="sp4">
        <figure>
          <img src="assets/img/img-kyoto11.jpg" alt="" />
          <figcaption>SP: 4/12 - TAB: 4/12</figcaption>
        </figure>
        <!-- /.c-card -->
      </li>
      <li class="olex__item" data-grid="sp4">
        <figure>
          <img src="assets/img/img-kyoto12.jpg" alt="" />
          <figcaption>SP: 4/12 - TAB: 4/12</figcaption>
        </figure>
        <!-- /.c-card -->
      </li>
      <li class="olex__item" data-grid="sp4">
        <figure>
          <img src="assets/img/img-kyoto13.jpg" alt="" />
          <figcaption>SP: 4/12 - TAB: 4/12</figcaption>
        </figure>
        <!-- /.c-card -->
      </li>
    </ul>
  </div>
  <!-- /.olex__item -->
</div>
<!-- /.olex -->
</div>

See the Pen Olex – Demo3 by Shiba Hiro (@hilosiva) on CodePen.36915

※上記のプレビューの下部にある「0.5×」か「0.25×」を押すとPCでの表示イメージも確認できます。

まとめ

如何でしたでしょうか?

この記事を書くより、デモサイトを作るほうが時間がかかってしまいましたw

ただ、こんな感じで僕はオリジナルのCSSグリッドシステムを作って使っています。

もしよかったら皆さんも作ってみてもらえたらと思います。

あ、大事なことなのでもう一度お伝えしておきますね。

「Olex」という名前は恥ずかしいので、ご自身で適切な名前に変更して作ってくださいね。

一応、すでに出来上がってるコードもGitHubに置いておきますね。

また、Shibajukuの中ではより詳細なOlexの使い方に関する解説などもしてますので、よかったら覗いてみてください。

では。