FlexboxとSassグリッドのチュートリアル:レスポンシブデザインを合理化する方法

公開: 2022-03-11

最近、自分でグリッドシステムを作ることに挑戦しましたが、車輪の再発明は学習体験として常に役立つので、それを選びました。 面白いチャレンジになるとは思っていましたが、とても簡単だったのでびっくりしました!

SassとFlexboxグリッドのチュートリアル

この実験では、Flexboxレイアウトと、それらがクレイジーなハックを行わずにレイアウトの適切な実装を可能にする方法を調べます。 また、Sassに慣れていない場合は、Sassがどのように機能するかを確認し、便利なSassユーティリティを使用します。 Bootstrapの一部であるようなCSSグリッドについて何か新しいことを学ぶかもしれません。

SassとFlexboxのごく簡単な紹介

Sassは基本的に、CSSの欠点のいくつかを回避できるツールであり、CSSに解釈されるスクリプト言語です。 すでにCSSスタイルを記述している場合、構文は非常によく知られていますが、そのツールボックスには、変数、再利用のためのミックスイン、if、for、each、whileディレクティブなどが含まれています。 Sassの最も便利な点の1つは、有効なCSSコードが有効なSassであるため、コードベースを段階的に変換できることです。

forループの簡単な例:

 @for $i from 1 through 3 { .a-numbered-class-#{$i} { width: (20 * $i) * 1px; } }

この単純なループは1から3まで繰り返し、クラスを作成します。 反復のインデックスは$iに簡単に保存されます。 また、数学を実行して、毎回異なる幅で.a-numbered-class-Xを3回印刷することもできます。 このコードは以下を出力します:

 .a-numbered-class-1 { width: 20px; } .a-numbered-class-2 { width: 40px; } .a-numbered-class-3 { width: 60px; }

ご覧のとおり、CSSで実行する必要のある多くの作業を抽象化できます。 CSSでは、手動でコピー、貼り付け、変更する必要がありますが、これは明らかにエラーが発生しやすく、エレガントではありません。まだ試していない場合は、もう時間を無駄にしないでください。

FlexboxはFlexibleBoxの略で、要素を動的に配置および分散するCSS3レイアウトシステムです。 これは非常に強力なツールであり、最小限の労力で柔軟なレイアウトを可能にします。 Flexboxの学習方法の詳細については、ChrisCoyierのFlexboxの完全ガイドをご覧ください。

グリッド

グリッド自体に移り、その基本的な要素から始めましょう。 これらは、Bootstrapのグリッド要素(コンテナ、行、列)に触発され、それぞれが前者に含まれています。

クラスの名前にはBEMの命名規則を使用します。 BEM規則は非常に簡単に使用でき、要素とそのコンテキストに関する多くの情報を追加します。 簡単に言えば、あなたは持っています:

  • 「それ自体で意味のあるスタンドアロンエンティティをカプセル化する」ブロック.block
  • 「ブロックの一部であり、スタンドアロンの意味を持たない」要素。ブロック名、2つのアンダースコア、および要素.block__elemで示されます。
  • 「ブロックまたは要素のフラグ」などの修飾子。2つのダッシュで表されます: .block .block--mod

コンテナ、行、および列

コンテナ

これはグリッドの最も外側の要素であり、行要素が含まれます。 コンテナには、 .container.container--fluidの2種類があります。

.containerの動作は、特定のポイントの下の幅の100%であり、その上に最大の固定幅があり、左右に等しいマージンがあることによって定義されます。

 $grid__bp-md: 768; .container { max-width: $grid__bp-md * 1px; margin: 0 auto; }

「出力」ウィンドウを拡大および縮小して、ここで試してみてください

常に100%の幅を持つ流体コンテナの場合、これらのプロパティを修飾子でオーバーライドするだけです。

 &--fluid { margin: 0; max-width: 100%; }

ここで遊んでください。

簡単でした! これで、両方のコンテナが実装されました。 次の要素に移りましょう。

行は、コンテンツの水平方向のオーガナイザーになります。

Flexboxを使用して行の子要素を配置し、オーバーフローしないように折り返し、行内に100%の幅を与えます(後でネストできるようにします)。

 &__row { display: flex; flex-wrap: wrap; width: 100%; }

これにより、子要素が並べて配置され、幅の合計がそれ自体よりも大きい場合は、新しい行にラップされます。 ここで、いくつかのdivを追加する必要があり、次のようになります。

行要素

「出力」ウィンドウを拡大および縮小して、ここで試してみてください。

物事は形になり始めていますが、これはまだCSSグリッドではありません。 足りない…

列は、サイトのコンテンツが存在する場所です。 それらは、行が分割される部分の数とそれらが占める量を定義します。 12列のレイアウトを行います。 これは、行を1つまたは最大12の部分に分割できることを意味します。

まず、いくつかの基本的な数学。 1つの列が必要な場合、その幅は100%にする必要があります。 12列が必要な場合。 次に、それぞれが幅の8.333…%または100/12を占める必要があります。

Flexboxでは、この方法でコンテンツを配布するために、 flex-basisを使用できます。

4つの列に分割するために、次のようなものを追加します。

 flex-basis: (100 / 4 ) * 1%;

このようにして、各要素が幅の25%、または任意のパーセンテージを占めるようにすることができます。

ここで遊んでください。

それをもっとダイナミックにしましょう。 これに可能なクラスを反映させたいので、 .col-1を呼び出します。これは、新しい行に折り返す前に12個が収まる必要があるため、幅の8.333%になる列divのクラスです。 パーセンテージは、100%を占める.col-12までずっと増加します。

 $grid__cols: 12; @for $i from 1 through $grid__cols { .col-#{$i} { flex-basis: (100 / ($grid__cols / $i) ) * 1%; } }

何が起こっているのかを明確にするために、幅を4つの等しい部分に分割したいとします。 .col-3は12に4回収まるため、必要になります。つまり、 .col-3のフレックスベースは25%である必要があります。

 100 / ($grid__cols / $i) 100 / (12 / 3) = 25

これはすでにグリッドのように見え始めています!

グリッドのように見えます!

ここで遊んでください。

画面幅に依存する列

ここで、モバイルでは一定の幅を持ち、タブレットなどでは別の幅を持つ要素を作成できるようにしたいと考えています。 ウィンドウの幅に応じて、特定のブレークポイントを使用します。 UIはこれらのブレークポイントに反応し、さまざまなデバイスの画面サイズに合わせた理想的なレイアウトに適応します。 ブレークポイントにサイズで名前を付けます:small(sm)、medium(md)など.col-sm-12は、少なくともsmブレークポイントまで12列を占める要素になります。

.col-*クラスの名前を.col-sm-*に変更しましょう。 グリッドは最初にモバイルになるため、そのプロパティをすべての画面サイズに適用します。 より大きな画面で異なる動作をする必要があるものについては、クラス.col-md-*を追加します。

.col-sm-12.col-md-4を持つ要素を想像してみてください。 予想される動作は、ブレークポイント「md」(中)の下では幅が100%、上では33.333%になることです。これは、モバイルでは要素を横ではなく上にスタックする必要がある場合があるため、非常に一般的な動作です。あなたの幅がはるかに制限されているときにお互い。

ブレークポイントに達した後の列のスタック

このために、ブレークポイントにメディアクエリ(特定の幅の上または下、または特定のデバイスでのみ実行されるコードを含む式)を追加し、 smの場合と同様にmd列を作成する必要があります。

 @media screen and (min-width: $grid__bp-md * 1px) { @for $i from 1 through $grid__cols { &__col-md-#{$i} { flex-basis: (100 / ($grid__cols / $i) ) * 1%; } } }

ここで遊んでください。

それはすでに何か役に立つものに近づいています。 それはかなりウェットです(わかりますか?ドライではありません…)ので、もっと抽象的にしましょう。

これまで見てきたように、ブレークポイントごとにメディアクエリが必要になるので、メディアクエリを動的に作成するブレークポイントを受け取るミックスインを作成しましょう。 次のようになります。

 @mixin create-mq($breakpoint) { @if($breakpoint == 0) { @content; } @else { @media screen and (min-width: $breakpoint *1px) { @content; } } }

それでは、 create-col-classesというミックスインで__colクラスを作成するために持っていたものをラップし、 create-mqミックスインを使用しましょう。

 @mixin create-col-classes($modifier, $grid__cols, $breakpoint) { @include create-mq($breakpoint) { @for $i from 1 through $grid__cols { &__col#{$modifier}-#{$i} { flex-basis: (100 / ($grid__cols / $i) ) * 1%; } } } }

以上です。 これを使用するために、Sassマップでブレークポイントを定義し、それらを繰り返します。

 $map-grid-props: ('-sm': 0, '-md': $grid__bp-md, '-lg': $grid__bp-lg); @each $modifier , $breakpoint in $map-grid-props { @include create-col-classes($modifier, $grid__cols, $breakpoint); }

私たちのグリッドシステムは基本的に完了です! デフォルトとなる.container__col-sm-*クラスを定義し、container__col container__col-md-*およびcontainer__col-lg-* *を使用してより大きな画面での動作を変更できます。

行をネストすることもできます! ここで遊んでください。

これの良いところは、Bootstrap v4と同じブレークポイントをすべて持たせたい場合は、次のことを行う必要があることです。

 $grid__bp-sm: 576; $grid__bp-md: 768; $grid__bp-lg: 992; $grid__bp-xl: 1200; $map-grid-props: ( '': 0, '-sm': $grid__bp-sm, '-md': $grid__bp-md, '-lg': $grid__bp-lg, '-xl': $grid__bp-xl );

以上です! ここで遊んでください。

Bootstrapが最初に説明したよりも完全なモバイルファーストアプローチを採用していることに注目してください。 最小のウィンドウサイズには、 smmdのような接尾辞がありません。これは、 .container__col-Xと同等のクラスが、ウィンドウ幅0〜576pxにのみ適用されるわけではないためです。 明示的に上書きしない場合は、すべてのウィンドウサイズでその列数になります。 それ以外の場合は、クラス.container__col-sm-Yを追加して、 smブレークポイント間のY列の幅にすることができます。

オフセット

オフセットは、前の列に対して残されたマージンを追加します。 .container__col-offset-4は、 margin-left: 33.333%.container__col-md-offset-4は同じことを行いますが、 mdブレークポイントの上にあります。

実装は簡単です。 クラスを作成するのと同じループに-offsetプロパティを追加しますが、 flex-basesの代わりに、プロパティmargin-leftを記述します。 より大きな画面ではマージンをクリアしたい場合があるため、 -offset-0も追加の1つを実行する必要があります。

 @mixin create-col-classes($modifier, $grid-cols, $breakpoint) { @include create-mq($breakpoint) { &__col#{$modifier}-offset-0 { margin-left: 0; } @for $i from 1 through $grid-cols { &__col#{$modifier}-#{$i} { flex-basis: (100 / ($grid-cols / $i) ) * 1%; } &__col#{$modifier}-offset-#{$i} { margin-left: (100 / ($grid-cols / $i) ) * 1%; } } } }

これで、完全に機能するオフセットができました。 ここで遊んでください。

表示可能性

特定のポイントの下または上に要素を表示/非表示にしたい場合があります。 このために、Bootstrapv4のようなクラスを利用できるようにすることができます。

たとえば、クラス.hidden-md-upは、このクラスを持つすべての要素をmdブレークポイントから上に非表示にします。 逆に、 .hidden-md-downは、ブレークポイントからそれを非表示にします。

このためのコードはさらに単純です。ブレークポイントを繰り返し、ブレークポイントfor each.hidden-*クラスを作成するだけです。 ただし、 create-mqクラスをもう少し抽象化するように変更しました。

 @each $modifier , $breakpoint in $map-grid-props { @if($modifier == '') { $modifier: '-xs'; } @include create-mq($breakpoint - 1, 'max') { .hidden#{$modifier}-down { display: none !important; } } @include create-mq($breakpoint, 'min') { .hidden#{$modifier}-up { display: none !important; } } }

ちなみに、これは!importantの数少ない良い使い方の1つではありませんか? 要素はdisplay: blockルールで任意に高い特異性を持っている可能性がありますが、それでもブレークポイントの下または上に非表示にする必要があることに注意してください。 このアプローチに同意できない場合は、コメントでお知らせください。

以上です。現在、表示可能性システムがあります。

ここで遊んでください。

結論

この「フレームワーク」は本番環境に対応していませんが、Flexboxレイアウトがいかに強力であり、Sassがいかに便利であるかを示しています。 ほんの数行のコードで、CSSフレームワーク/グリッドのコア機能を実装しました。

事実上すべてのソフトウェアの基本バージョンを非常に簡単に実装できるという教訓にもなりますように。 足し算を始めて難しくするのは、現実世界の具体的な問題です。

問題を送信したりリクエストをプルしたりできるGitHubリポジトリを作成しました。

どの機能を実装してもらいたいですか? 実装を簡素化することはできますか、それともよりエレガントにすることができますか?

以下のコメントについて、お気軽にご意見をお聞かせください。