CSSレイアウトチュートリアル:古典的なアプローチから最新のテクニックまで

公開: 2022-03-11

CSSを習得せずにWebレイアウトを習得することは、乾燥した土地で泳ぐことを学ぶのとほぼ同じくらい実現可能です。 しかし、水泳(一度習得すると一生残るスキル)とは異なり、CSSの習得は、CSS自体が絶えず進化しているため、実際には終わらないプロセスです。

この課題は、異なるブラウザー間(および同じブラウザーの異なるバージョン間でも)のCSS実装とサポートの違い、およびCSS推奨の採用率の違いによって悪化します。 10年以上もの間、Webデザイナーと開発者は、新しいブラウザーの各バージョンでサポートされている追加のCSS3機能の散発的で一貫性のないバーストに取り組んできました。

しかし、それでも、CSSをマスターすることは、堅実なWebデザイナーや開発者にとって絶対に必要なことです。 この記事では、従来のCSS2テクニックからCSS3の最新のレイアウトアプローチまで、いくつかの基本的なCSSレイアウトの原則について説明します。

注:この記事のすべてのコードサンプルは、HTML5要素とSass構文を使用しています。 完全に機能するコードは、https://github.com/laureanoarcanio/css-layout-examplesから複製できます。

使用事例

テクノロジーを学ぶための最良の方法の1つは、サポートしようとしている特定のユースケースまたは解決しようとしている特定の問題を用意することです。 そのために、特定の要件セットを使用したユースケースに焦点を当てます。

私たちのユースケースは、動的な動作を伴うWebアプリのレイアウトで構成されています。 ヘッダー、フッター、ナビゲーションメニュー、サブナビゲーションなどの固定要素と、スクロール可能なコンテンツセクションがページに表示されます。 具体的なレイアウト要件は次のとおりです。

  • 基本レイアウト
    • ヘッダー、フッター、ナビゲーションメニュー、およびサブナビゲーションはすべてスクロール時に固定されたままです
    • ナビゲーション要素とサブナビゲーション要素は、すべての垂直方向の空きスペースを占めます
    • コンテンツセクションは、ページ上の残りのすべての空き領域を使用し、スクロール可能な領域があります
  • 動的な動作
    • ナビゲーションメニューにはデフォルトでアイコンのみが表示されますが、展開してテキストを表示することもできます(折りたたんで再びアイコンのみを表示することもできます)
  • レイアウトのバリエーション
    • 一部のページには、ナビゲーションメニューの横にサブナビゲーションがあり、一部にはありません

従来のCSS2テクニックを使用したCSSチュートリアル

CSSチュートリアル

手始めに、クラシックCSSを使用したサンプル実装で使用するHTML5マークアップを次に示します。

 <body class="layout-classic"> <header></header> <nav></nav> <aside></aside> <main></main> <footer></footer> </body>

固定ポジショニング

CSS2では、固定配置を使用する配置レイアウトモデルを採用することで、ページ上の固定要素(ヘッダー、フッターなど)を実現できます。

さらに、 z-index CSSプロパティを使用して、固定要素がページ上の他のコンテンツの「上」にとどまるようにします。 z-indexプロパティは、要素のスタック順序を指定します。スタック順序が大きい要素は、常にスタック順序が小さい要素の「上」にあります。 z-indexプロパティは、配置された要素でのみ機能することに注意してください。 この例では、 z-index値20(デフォルトよりも高い値)を任意に使用して、固定要素が視覚的に最前線にとどまるようにします。

また、 widthプロパティを100%に設定して、要素に使用可能なすべてのスペースを水平方向に使用するようにブラウザーに指示します。

 #header, #footer { position: fixed; width: 100%; z-index: 20; } #header { top: 0; height: 5em; } #footer { bottom: 0; height: 3em; }

OK、これがヘッダーとフッターです。 しかし、#navと#nav#subnavですか?

CSS拡張

#nav#subnavには、 CSS拡張と呼ばれるもう少し洗練された手法を使用します。これは、要素を固定(つまり、ページ上の固定位置)または絶対(つまり、最も近い位置にある祖先または包含ブロックを基準にした指定位置)。

垂直方向の拡張は、要素のtopbottomの両方のプロパティを固定値に設定することで実現されるため、要素は垂直方向に拡張され、それに応じて残りの垂直方向のスペースが使用されます。 基本的には、要素の上部をページの上部から特定の距離に結び付け、要素の下部をページの下部から特定の距離に結び付けることで、要素が拡張して垂直方向のスペース全体を埋めます。それらの2つのポイントの間。

同様に、水平方向の拡張は、要素のleft rightのプロパティを固定値に設定することで実現されるため、要素は水平方向に拡張され、それに応じて残りの水平方向のスペースが使用されます。

このユースケースでは、垂直展開を使用する必要があります。

 #nav, #subnav { position: fixed; top: 6em; /* leave 1em margin below header */ bottom: 4em; /* leave 1em margin above footer */ z-index: 20; } #nav { left: 0; width: 5em; } #subnav { left: 6em; /* leave 1em margin to right of nav */ width: 13em; }

デフォルト(静的)ポジショニング

メインのスクロール可能なコンテンツ領域は、デフォルトの(静的な)配置に単純に依存できます。これにより、要素はドキュメントフローに表示される順序でレンダリングされます。 ページ上の他のすべてが固定位置にあるため、この要素がドキュメントフローに含まれる唯一の要素です。 その結果、適切に配置するために必要なのは、固定ヘッダー、フッター、およびnav/subnavとの重複を回避するためにmarginプロパティを指定することだけです。

 #main { margin: 6em 0 4em 20em; }

これで、CSS2を使用したユースケースの基本的なレイアウト要件を満たしましたが、動的機能の追加要件を満たす必要があります。

従来のCSS2手法を使用した動的な動作

要件では、ナビゲーションメニューにはデフォルトでアイコンのみが表示されますが、テキストを表示するように展開することもできます(その後、折りたたんでアイコンのみを表示することもできます)。

CSS2およびCSS3チュートリアル

ナビゲーションメニューが展開されたときに、ナビゲーションメニューの幅に5emを追加することから始めましょう。 これを行うには、ナビゲーションメニュー要素に動的に追加または削除できる「拡張」CSSクラスを作成します。

 #nav { left: 0; width: 5em; &.expanded { /* Sass notation */ width: 10em; } }

次に、ユーザーがナビゲーショントグルアイコンをクリックしたことに基づいて、ナビゲーションメニューを展開モードと折りたたみモードの間で動的に切り替えるために使用できるJavaScriptコードの例(この例ではjQueryを使用)を示します。

 $('.layout-classic #nav').on('click', 'li.nav-toggle', function() { $('#nav'').toggleClass('expanded'); });

これにより、ナビゲーションメニューを動的に展開または折りたたむことができるようになりました。 素晴らしい。

まあ、ちょっと素晴らしいですが、完全ではありません。 ナビゲーションメニューは拡大および縮小できるようになりましたが、ページの残りの部分ではうまく機能しません。 展開されたナビゲーションメニューがサブナビゲーションとオーバーラップするようになりましたが、これは明らかに望ましい動作ではありません。

これにより、CSS2の重要な制限の1つが明らかになります。 つまり、固定位置の値でハードコーディングする必要がある方法が多すぎます。 その結果、拡張ナビゲーションメニューに対応するために再配置する必要があるページ上の他の要素については、さらに固定された位置値を使用して追加の「拡張」CSSクラスを定義する必要があります。

 #subnav { left: 6em; width: 13em; &.expanded { left: 11em; /* move it on over */ } } #main { margin: 6em 0 4em 20; z-index: 10; &.expanded { margin-left: 25em; /* move it on over */ } }

次に、JavaScriptコードを拡張して、ユーザーがナビゲーショントグルをクリックしたときに、これらの他の要素の動的調整も追加する必要があります。

 $('.layout-classic #nav').on('click', 'li.nav-toggle', function() { $('#nav, #subnav, #main').toggleClass('expanded'); });

OK、それはうまくいきます。

従来のCSS2手法を使用したレイアウトのバリエーション

次に、サブナビゲーションメニューを非表示にするページをいくつか用意するという要件に対処しましょう。 具体的には、ユーザーがメインナビゲーション領域の「ユーザー」アイコンをクリックしたときにサブナビゲーションメニューを非表示にする必要があります。

CSSlayourチュートリアル

したがって、最初に、 display: none

 .hidden { display: none; }

また、JavaScript(jQuery)を使用して、ユーザーがユーザーアイコンをクリックしたときに、「非表示」のCSSクラスを#subnav要素に適用します。

 $('#nav.fa-user').on('click', function() { $('#subnav').toggleClass('hidden'); });

この追加により、ユーザーが「ユーザー」アイコンをクリックすると#subnav要素が適切に非表示になりますが、他の要素が#subnav要素によって空いたスペースを使用するように拡張されるのではなく、占有されていたスペースは未使用のままになります。

#subnav要素を非表示にしたときに目的の動作を実現するために、あまり知られていないが非常に便利な、隣接する兄弟セレクターと呼ばれるCSSセレクターの1つを使用します。

隣接する兄弟CSSセレクター

隣接する兄弟セレクターを使用すると、2つの要素を指定して、指定した最初の要素の直後に続く2番目の要素のインスタンスのみを選択できます。

たとえば、以下では、IDsubnavの要素の直後にあるsubnav main要素のみを選択します。

 #subnav + #main { margin-left: 20em; }

上記のCSSスニペットは、表示された#subnavの直後に続く場合に限り、 20em mainの左マージンを#mainに設定します。

ただし、 #navが展開されている場合(以前のコードに基づいて、 expandedたクラスも#mainに追加されます)、#mainの左マージンを#mainに移動します。

 #subnav + #main.expanded { margin-left: 25em; }

また、 #subnavが非表示になっている場合は、#mainの左マージンを#mainまで移動して、#navのすぐ隣に#navします。

 #subnav.hidden + #main { margin-left: 6em; }

(注:隣接する兄弟セレクターを使用することの欠点の1つは、表示されているかどうかに関係なく、常に#subnavがDOMに存在することを強制することです。)

最後に、 #subnavが非表示で、 #navが展開されている場合、#mainの左マージンを#mainに設定し11em

 #subnav.hidden + #main.expanded { margin-left: 11em; }

これにより、重いJavaScriptコードなしで物事を結び付けることができますが、ページに要素を追加すると、このコードがどれほど複雑になるかを確認することもできます。 CSS2では、物事を適切に機能させるために、位置値の多くのハードコーディングが必要であることがさらにわかります。

CSS3の活用

CSS3は、大幅に強化された機能とレイアウト手法を提供し、ハードコードされた値への依存を大幅に減らし、使いやすくします。 CSS3は本質的に、より動的な動作をサポートするように設計されており、その意味で、より「プログラム可能」です。 これらの新機能のいくつかを、ユースケースに関連して調べてみましょう。

CSS3 calc()関数

新しいcalc()関数を使用して、CSSプロパティ値を動的に計算できます(ただし、サポートはブラウザーによって異なることに注意してください)。 calc()関数に提供される式は、標準の演算子の優先順位規則を使用して、基本的な算術演算子( +-*/ )を組み合わせた任意の単純な式にすることができます。

calc()関数を使用すると、CSS2で必要な値のハードコーディングの多くを回避できます。 私たちの場合、これにより、CSS拡張をより動的に実現できます。 例えば:

 #nav, #subnav { position: fixed; height: calc(100% - 10em); /* replaces */ z-index: 20; }

calc()関数を使用した上記のheightの指定により、 top:6embottom:4emを使用してCSS2で行ったのと同じ結果が得られますが、はるかに柔軟で適応性のある方法で、 top bottomをハードコーディングする必要がありません。値。

CSS3Flexboxレイアウト

FlexboxはCSS3で導入された新しいレイアウトです(サポートはブラウザによって異なります)。 フレックスボックスレイアウトを使用すると、さまざまな画面サイズ、解像度、およびデバイス間で予測どおりに動作するように、ページ上の要素を簡単に配置できます。 したがって、レスポンシブWebデザインのコンテキストで特に役立ちます。

主な機能は次のとおりです。

  • 子要素の配置ははるかに簡単で、複雑なレイアウトをより簡単に、よりクリーンなコードで実現できます。
  • 子要素は任意の方向に配置でき、表示スペースに適応するように柔軟な寸法を持つことができます。
  • 子要素は、利用可能な空き領域に適応するために契約を自動的に拡張します。

Flexboxには、独自の用語と概念のセットが導入されています。 これらのいくつかは次のとおりです。

  • フレックスコンテナ。 displayプロパティがflexまたはinline-flexに設定されている要素で、フレックスアイテムのコンテナ要素として機能します。
  • フレックスアイテム。 フレックスコンテナ内の任意の要素。 (注:フレックスコンテナーに直接含まれるテキストは、匿名のフレックスアイテムでラップされます。)
  • 。 すべてのフレックスボックスレイアウトには、フレックスアイテムが配置される主軸を指定するflex-directioがあります。 その場合、交差軸は主軸に垂直な軸になります。
  • 線。 フレックスアイテムは、 flex-wrapプロパティに応じて、1行または複数行に配置できます。
  • 寸法。 高さと幅に相当するフレックスボックスはmain sizecross sizeであり、それぞれフレックスコンテナの主軸とクロス軸のサイズを指定します。

さて、その簡単な紹介で、フレックスボックスレイアウトを使用している場合に使用できる代替マークアップを次に示します。

 <body class="layout-flexbox"> <header></header> <div class="content-area"> <nav></nav> <aside></aside> <main></main> </div> <footer></footer> </body>

このユースケースの例では、メインレイアウト(ヘッダー、コンテンツ、フッター)は垂直であるため、列レイアウトを使用するようにフレックスボックスを設定します。

 .layout-flexbox { display: flex; flex-direction: column; }

メインレイアウトは垂直ですが、コンテンツ領域の要素(nav、subnav、main)は水平にレイアウトされています。 各フレックスコンテナは一方向のみを定義できます(つまり、そのレイアウトは水平または垂直のいずれかである必要があります)。 したがって、レイアウトにこれ以上のものが必要な場合(アプリのレイアウトの一般的なケース)、それぞれが異なる方向のレイアウトを持つ複数のコンテナーを相互にネストできます。

そのため、#nav、 #subnav #navおよび#mainをラップするコンテナ(私はcontent-areaと呼んでいます)を追加しました。 このようにして、コンテンツ領域のコンテンツを水平にレイアウトしながら、全体のレイアウトを垂直にすることができます。

次に、フレックスアイテムを配置するために、フレックスの省略形であるプロパティflexを使用しますflex: <flex-grow> <flex-shrink> <flex-basis>; 。 これらの3つのフレックスプロパティは、次のように、フレックスアイテムの間に残っている空きスペースをフロー方向にどのように配分するかを決定するプロパティです。

  • flex-grow:同じコンテナ内の残りの柔軟なアイテムと比較してアイテムがどれだけ成長できるかを指定します
  • flex-shrink:同じコンテナ内の残りのフレキシブルアイテムに対してアイテムをどのように縮小できるかを指定します
  • flex-basis:アイテムの初期サイズを指定します(つまり、アイテムが縮小または拡大する前)

CSSフレックスコンテナ:クロスvsメイン

flex-growflex-shrinkの両方をゼロに設定すると、アイテムのサイズが固定され、使用可能な空き領域に対応するためにアイテムが拡大または縮小されなくなります。 サイズが固定されているため、ヘッダーとフッターに対してこれを行います。

 #header { flex: 0 0 5em; } #footer { flex: 0 0 3em; }

アイテムに使用可能なすべての空き領域を確保するには、そのflex-growflex-shrink値を両方とも1に設定し、 flex-basis値をautoに設定します。 これは、利用可能なすべての空き領域を占有するようにするため、コンテンツ領域に対して行うことです。

また、前に述べたように、 content-area内のアイテムを行方向に配置する必要があるため、 display: flex ; およびflex-direction: row; 。 これにより、content-areaが#nav#subnav 、および`#mainの新しいフレックスコンテナになります。

これが、 content-areaのCSSで最終的に得られるものです。

 .content-area { display: flex; flex-direction: row; flex: 1 1 auto; /* take up all available space */ margin: 1em 0; min-height: 0; /* fixes FF issue with minimum height */ }

コンテンツ領域では、 #subnav #nav両方のサイズが固定されているため、それに応じてflexプロパティを設定します。

 #nav { flex: 0 0 5em; margin-right: 1em; overflow-y: auto; } #subnav { flex: 0 0 13em; overflow-y: auto; margin-right: 1em; }

overflow-y: hiddenになっています。Chromeは実際にはこれを必要としませんが、FireFoxは必要です。)

#mainは残りの空き領域を占有します:

 #main { flex: 1 1 auto; overflow-y: auto; }

これはすべて良さそうなので、動的な動作をこれに追加して、それがどのように行われるかを見てみましょう。

JavaScriptは以前のものと同じです(ここを除いて、指定しているCSS要素コンテナークラスはlayout-flexboxが、以前はlayout-classicでした):

 $('.layout-flexbox #nav').on('click', 'li.nav-toggle', function() { $('#nav').toggleClass('expanded'); });

次のように、 expandedクラスをCSSに追加します。

 #nav { flex: 0 0 5em; /* collapsed size */ margin-right: 1em; overflow-y: auto; &.expanded { flex: 0 0 10em; /* expanded size */ } }

そして出来上がり!

フレックスボックスレイアウトがすべてを処理するため、今回は幅の変更について他のアイテムに通知する必要がないことに注意してください。

残っているのは、サブナビゲーションを非表示にすることだけです。 そして、何を推測しますか? これも、以前と同じJavaScriptコードを使用して、追加の変更なしで「正しく機能」します。 Flexboxは空き領域を認識しており、余分なコードなしでレイアウトを自動的に機能させます。 かなりクール。

Flexboxは、垂直要素と水平要素の両方を中央に配置するいくつかの興味深い方法も提供します。 ここで、プレゼンテーション言語に空き領域の概念を含めることがいかに重要であるか、およびこれらの種類の手法を使用してコードをスケーラブルにすることができるかを認識します。 一方、ここでの概念と表記法は、従来のCSSよりも習得するのに少し時間がかかる場合があります。

CSS3グリッドレイアウト

FlexboxレイアウトがCSS3の最先端にある場合、グリッドレイアウトは最先端にあると言えます。 W3C仕様はまだドラフト状態であり、ブラウザのサポートはかなり制限されています。 (これは、chrome:// flagsの「実験的なWebプラットフォーム機能」フラグを介してChromeで有効になります)。

とはいえ、私は個人的にこのドラフトを革命的なものとは考えていません。 むしろ、HTML5の設計原則が述べているように、 「作成者の間で慣習がすでに広まっている場合は、それを禁止したり、何か新しいものを発明したりするのではなく、それを採用することを検討してください。」

したがって、マークアップベースのグリッドは長い間使用されてきました。そのため、CSSグリッドレイアウトは実際には同じパラダイムに従っており、マークアップ要件のないプレゼンテーション層ですべての利点とはるかに多くの利点を提供します。

一般的な考え方は、要素を配置できる事前定義、固定、または柔軟なグリッドレイアウトを用意することです。 フレックスボックスと同様に、フリースペースの原則にも基づいて機能し、同じ要素で垂直方向と水平方向の両方の「方向」を定義できるため、コードサイズと柔軟性に利点があります。

グリッドレイアウトでは、2種類のグリッドが導入されています。 つまり、明示的および暗黙的です。 簡単にするために、ここでは明示的なグリッドに焦点を当てます。

フレックスボックスと同様に、グリッドレイアウトには独自の用語と概念のセットが導入されています。 これらのいくつかは次のとおりです。

  • グリッドコンテナ。 displayプロパティが「grid」または「inline-grid」に設定されている要素で、事前定義されたグリッドに配置および位置合わせすることにより、含まれている要素が配置されます(明示モード)。 グリッドは、グリッドコンテナのスペースをグリッドセルに分割する、交差する水平グリッド線と垂直グリッド線のセットです。 グリッド線には2つのセットがあります。 1つは列を定義するためのもので、もう1つは行を定義するためのものです。
  • グリッドトラック。 2つの隣接するグリッド線の間のスペース。 各グリッドトラックにはサイズ設定機能が割り当てられており、列または行の幅または高さ、つまり境界グリッド線の間隔を制御します。
  • グリッドセル。 2つの隣接する行と2つの隣接する列のグリッド線の間のスペース。 これは、グリッドアイテムを配置するときに参照できるグリッドの最小単位です。
  • 柔軟な長さ。 frユニットで指定された寸法。これは、グリッドコンテナの空き領域の一部を表します。

CSSグリッドレイアウトスケッチ

グリッドレイアウトを使用している場合に使用できる代替マークアップは次のとおりです。

 <body class="layout-grid"> <header></header> <nav></nav> <aside></aside> <main></main> <footer></footer> </body>

このレイアウトでは、フレックスボックスの場合のようにコンテンツ領域に追加のラッパーは必要ありませ。このタイプのレイアウトでは、同じグリッドコンテナで両方向の要素スペースの指定を定義できるためです。

今すぐCSSを掘り下げてみましょう:

 .layout-grid { display: grid; grid-template-columns: auto 0 auto 1em 1fr; grid-template-rows: 5em 1em 1fr 1em 3em; }

display: grid; 私たちのコンテナに。 grid-template-columnsプロパティとgrid-template-rowsプロパティはそれぞれ、グリッドトラック間のスペースのリストとして指定されます。 つまり、これらの値はグリッド線の位置ではありません。 むしろ、2つのトラック間のスペースの量を表します。

測定単位は次のように指定できることに注意してください。

  • 長さ
  • グリッドコンテナのサイズのパーセンテージ
  • 列または行を占めるコンテンツの測定、または
  • グリッド内の空き領域の一部

したがって、 grid-template-columns: auto 0 auto 1em 1fr; 私たちは持っているでしょう:

  • auto幅の2列を定義する1トラック( #navスペース)
  • 1ガター0( #subnavのマージンは要素レベルであり、存在する場合と存在しない場合があります。このようにして、ダブルガターを回避します)
  • auto幅の2列を定義する1トラック( #subnavスペース)
  • 1emの1つの側溝
  • 1fr#mainを使用する1トラック(残りのスペースをすべて使用します)

ここでは、トラックのauto値を多用します。これにより、線の位置とサイズが最大コンテンツによって定義される動的な列を作成できます。 (したがって、# #subnav #navのサイズを指定する必要があります。これはまもなく行います。)

同様に、行の行には、 grid-template-rows: 5em 1em 1fr 1em 3em; これにより、 #footer #header固定され、その間のすべての要素が1emを使用しながら残りの空き領域を使用するように設定されます。

次に、定義したグリッドに配置する実際の要素をどのように配置するかを見てみましょう。

 #header { grid-column: 1 / 6; grid-row: 1 / 2; } #footer { grid-column: 1 / 6; grid-row: 5 / 6; } #main { grid-column: 5 / 6; grid-row: 3 / 4; overflow-y: auto; }

これは、ヘッダーをグリッドライン1と6(全幅)の間に配置し、行のグリッドライン1と2の間に配置することを指定します。 フッターについても同じですが、(最初の2行ではなく)最後の2行の間にあります。 そして、メインエリアはそれが占めるはずのスペースに適切に設定されています。

grid-columnプロパティとgrid-rowプロパティは、それぞれgrid-column-start / grid-column-endgrid-row-start / grid-row-endを指定するための省略形であることに注意してください。

では、#navと#nav#subnav 。 以前に#nav#subnavを自動値でトラックに配置したので、これらの要素の幅を指定する必要があります(拡張モードでも同じですが、幅を変更するだけで、残りはグリッドレイアウトが処理します)。

 #nav { width: 5em; grid-column: 1 / 2; grid-row: 3 / 4; &.expanded { width: 10em; } } #subnav { grid-column: 3 / 4; grid-row: 3 / 4; width: 13em; /* track has gutter of 0, so add margin here */ margin-left: 1em; }

これで、#navを切り替えたり、 #subnav #nav非表示/削除したりできるようになり、すべてが完全に機能します。 グリッドレイアウトでは、線にエイリアスを使用することもできます。そのため、最終的にグリッドを変更しても、グリッド線ではなく名前にマップされるため、コードが分割されることはありません。 これがより多くのブラウザによってより広くサポートされることを間違いなく楽しみにしています。

結論

従来のCSS手法を使用しても、多くのWeb開発者が認識または利用するよりもはるかに多くのことを実現できます。 とは言うものの、これの多くは非常に面倒であり、スタイルシート全体で値を繰り返しハードコーディングする必要があります。

CSS3は、プログラミングが非常に簡単で、以前のCSS仕様の面倒な作業の多くを回避する、はるかに洗練された柔軟なレイアウト手法を提供し始めています。

CSS2とCSS3の両方でこれらの手法とパラダイムを習得することは、ユーザーエクスペリエンスとコードの品質の両方を最適化するためにCSSが提供するすべてを活用するために不可欠です。 この記事は、CSSのパワーと柔軟性で達成できるすべてのことを学ぶための氷山の一角を表しています。 どうぞ!

関連: * SMACSSの探索:CSS用のスケーラブルでモジュラーなアーキテクチャ*