パターンライブラリファースト:CSSを管理するためのアプローチ
公開: 2022-03-10この記事では、トロントで開催されたSmashing Conferenceでの講演に基づいて、プロジェクト全体でCSSを管理するのに役立つ過去2年間に採用した作業方法について説明します。
パターンライブラリツールであるフラクタルを使用して、コンポーネントごとにCSSを管理すると同時に、使い慣れたツールを使用できるようにする方法を紹介します。 これはフラクタルの紹介として役立ち、なぜこの特定のパターンライブラリを選択したのかということですが、この作業方法は他のソリューションに移行する可能性があります。
私たちのプロジェクト
私の会社には、PerchとPerch Runway CMS、およびパブリックスピーカー向けのサービスアプリケーションとしてのソフトウェアであるNotistという2つの製品があります。 これらの製品は、特にPerchがセルフホストシステムであり、NotistがSaaSであることを考えると、まったく異なりますが、どちらも開発するための多くのユーザーインターフェイスを備えています。 また、これらの製品に関連するすべてのWebサイトとドキュメントに加えて、24 WaysWebサイトなどのその他の作業も行っています。 2年前にフラクタルを発見した後、私たちは大小を問わずすべての新しいプロジェクトをフラクタルに移しました。
解決したい問題
2年前にバージョン3のPerchUIの再構築作業を開始したときに、パターンライブラリソリューションの調査を開始しました。Perchの機能は、Webサイトのコンテンツの出力用に作成したテンプレートが管理UIのスキーマになることです。 つまり、テンプレートで使用されるフィールドタイプは、他のフィールドタイプと一緒に存在できる必要があります。 お客様がこれらをどのように組み合わせるかはわかりません。また、可能な組み合わせは非常にたくさんあります。 また、これは「Webサイト」ではないため、パターンライブラリをWebサイトのパターンを整理するために設計されたものに強制しようとはしませんでした。
Perchは自己ホスト型であるため(ユーザーはダウンロードして自分のサーバーでホストします)、ユーザーの前に参入障壁を追加しないようにするために、可能な限りシンプルな技術スタックを使用する必要があります。 CMS。 さらに楽しいレベルを追加するために、Internet Explorer 9に戻ることをサポートしていますが、グリッドレイアウトが出荷される前のように、多くのFlexboxを使用するつもりでした。
また、私たちの働き方を再学習し、プロセスを完全に変えることに伴うツールの使用を避けたいと思っていました。 追加のツールやプロジェクトでの作業方法の変更は、新しい摩擦をもたらします。 1つの問題を解決することはできますが、作業方法に大きな変更を加えると、まったく新しい一連の問題が発生します。 私たちの場合、かなり限られた方法でSassを使用し、Gulpを使用してそれを処理していました。 私たちのプロジェクトはどれもJavascriptフレームワークを使用しておらず、HTML、CSS、JavaScriptを記述しているだけです。
フラクタルは私たちのニーズに完全に適合します。 開発方法や使用したいツールについては不可知論者です。 重要なのは、私たちの目的のために、私たちがWebサイトを構築しているとは想定していなかったということです。 実験は非常に成功したため、CSSでの作業プロセスがはるかに簡単になるため、大小のすべてのプロジェクトでFractalを使用していることがわかりました。 私が自分で作成した小さなサイトでさえ、フラクタルで生活を始めることがよくあります。これは、パターンライブラリを操作するという点で想像以上のメリットがあり、それらのメリットの多くは、大規模なチームと同じくらい1人のチームにとって意味があります。 。
Fractalを使用して開発する方法と、大規模なプロジェクトだけでなく小規模なプロジェクトでも意味があると思う理由を考える前に、環境をセットアップする方法を見てみましょう。
フラクタル入門
Fractalを使用するための最も簡単なアプローチは、Fractal Webサイトにアクセスして、スタートガイドを参照することです。 最初にFractalをグローバルにインストールする必要があります。次に、ここにリストされている手順に従って、新しいFractalプロジェクトを作成できます。
新しいプロジェクトをインストールしたら、コマンドラインで作成したフォルダーに変更し、コマンドを実行します。
fractal start --sync
これにより、ポート3000で小さなサーバーが起動するため、Webブラウザーでhttps://localhost:3000
にアクセスして、プロジェクトを確認できるはずです。
プロジェクトが稼働しているので、お気に入りのテキストエディタでプロジェクトフォルダを開き、 components/example
の下にあるサンプルコンポーネントを見つけます。 設定ファイルとexample.hbsという名前のファイルがあります。 example.hbsテンプレートはコンポーネントのHTMLであり、それにHTMLを追加すると、Fractalが自動的にリロードして表示します。 ファイルを次のように変更します。
<h1>This is my heading</h1> <p>{{ text }}</p>
ブラウザに見出しが表示されるはずです。 構成ファイルを使用して、コンテンツを追加したり、コンポーネントを構成したりできます。 そのファイルから見出しテキストを読み上げたい場合は、次の例のようにそのファイルを編集します。
title: Example component context: text: This is an example component! heading: My heading
次に、 example.hbsファイルを変更してそのテキストを読み取ります。
<h1>{{ heading }}</h1> <p>{{ text }}</p>
追加コンポーネントの追加
サンプルコンポーネントのパターンに従って、独自のコンポーネントを追加できます。 少なくとも、フォルダー(コンポーネントの名前)と同じ名前の.hbsファイルが必要です。 構成オプションを設定する場合は、構成ファイルを追加できます。
コンポーネントをフォルダにネストして、特定のコンポーネントを見つけやすくすることができます。フォルダの構造は完全にあなた次第です。
注:コンポーネントに名前を付ける方法について心配することに多くの時間を費やしていることに気付くのは本当に簡単です。 少なくともフラクタルでは、コンポーネントの名前を変更したり、フォルダーに再編成したりするのは簡単です。 それらの名前を変更または移動すると、Fractalが更新されて新しい構造が表示されます。 多くの場合、理想的な構造は私が開発しているときにのみ明らかになるので、最初はあまり心配せず、後でそれを固めます。
CSSワークフローの追加
これまでのところ、ハンドルバーテンプレートとしてHTMLコンポーネントを作成し、データを挿入するための構成ファイルを作成することができますが、CSSは追加していません。 理想的には、各コンポーネントのCSSを残りのコンポーネントファイルと同じフォルダーに追加してから、すべてを結合する必要があります。
フラクタルはあなたのワークフローについてほとんど仮定をしていません。 このため、特定の作業方法を強制する場合よりも、箱から出してすぐに実行できることははるかに少なくなります。 ただし、FractalをGulpセットアップで動作させるのはかなり簡単です。
フラクタル、サス、そしてガルプを組み合わせる
以下では、GulpとSassを使用して単一の出力CSSファイルを作成するための最小限のセットアップについて説明します。 うまくいけば、このプロセスに従って、Gulpで通常行う他のことを行うことができます。 注意すべき重要な点は、これのほとんどはフラクタル固有ではないため、フラクタル部分が機能するようになったら、同じパターンに従って他のものを追加できることです。 別のビルドツールに精通している場合は、同様のプロセスを作成できる可能性があります。 もしそうなら、そして喜んで共有してください、コメントで知らせてください。
最初にいくつかのセットアップを行います。次の方法で、このチュートリアルにリストされているコードに従うことができます。Sassファイルと出力CSSの場所は、最終的には私のものとは異なる場合があります。 重要なのは、出力CSSファイルがパブリックフォルダーのどこかにある必要があるということです。
- Fractalインストールのパブリックフォルダー内に、 cssという名前のフォルダーを追加します。
- Fractalのルートフォルダに、フォルダscssであるフォルダアセットを追加してインストールします。 そのフォルダー内にglobal.scssという名前のSassファイルを作成します。 そのファイル内に次の行を追加します。
@import "../../components/**/*.scss";
-
example
コンポーネントディレクトリにexample.scssという名前のファイルを作成します。 - Fractalプロジェクトのルートにgulpfile.jsを作成し、以下のコードを追加します。
'use strict'; const gulp = require('gulp'); const fractal = require('./fractal.js'); const logger = fractal.cli.console; const sass = require('gulp-sass'); const sassGlob = require('gulp-sass-glob'); const plumber = require('gulp-plumber'); const notify = require('gulp-notify'); const path = require('path'); gulp.task('sass',function() { return gulp.src('assets/scss/**/*.scss') .pipe(customPlumber('Error running Sass')) .pipe(sassGlob()) .pipe(sass()) .pipe(gulp.dest('public/css')) }); gulp.task('watch', ['sass'], function() { gulp.watch([ 'components/**/*.scss', 'assets/scss/**/*.scss' ], ['sass']); }); function customPlumber(errTitle) { return plumber({ errorHandler: notify.onError({ title: errTitle || "Error running Gulp", message: "Error: <%= error.message %>", }) }); } gulp.task('fractal:start', function(){ const server = fractal.web.server({ sync: true }); server.on('error', err => logger.error(err.message)); return server.start().then(() => { logger.success(`Fractal server is now running at ${server.url}`); }); }); gulp.task('default', ['fractal:start', 'sass', 'watch']);
次に、ファイルの先頭にリストされている依存関係をインストールします。 これらをコマンドラインでインストールする場合は、次のコマンドを実行します。
npm install gulp gulp-sass gulp-sass-glob gulp-plumber gulp-notify
sass
関数は、Sassをアセットから単一のファイルにコンパイルし、 public
のフォルダーに出力します。
gulp.task('sass',function() { return gulp.src('src/assets/scss/**/*.scss') .pipe(customPlumber('Error running Sass')) .pipe(sassGlob()) .pipe(sass()) .pipe(gulp.dest('public/css')) });
次に、 assets
と個々のコンポーネントでSassを監視するwatch
関数を作成し、パブリックのフォルダーにコンパイルします。
gulp.task('watch', ['sass'], function() { gulp.watch([ 'components/**/*.scss', 'assets/scss/**/*.scss' ], ['sass']); });
それが私のCSSの構築です。 gulpを実行できるようにしたいので、CSSファイルの監視とフラクタルの開始を開始します。 これを行うには、フラクタル開始コマンドを実行するgulpタスクを作成します。
gulp.task('fractal:start', function(){ const server = fractal.web.server({ sync: true }); server.on('error', err => logger.error(err.message)); return server.start().then(() => { logger.success(Fractal server is now running at ${server.url}); }); });
最後に、gulpとコマンドラインを実行するときに、Sassの構築とフラクタルが実行されるようにする必要があります。
gulp.task('default', 'fractal:start', 'sass', 'watch');
これが私の完成したgulpfile.jsです。 これをデフォルトのフラクタルプロジェクトに追加する場合は、フォルダーが上記のパスに対応していることを確認してください。 コマンドラインに移動してgulp
を実行すると、Fractalが起動します。
global.scssファイルに変数を追加することで、Sassをテストできます。 これらのコンポーネントで変数を使用できるように、コンポーネントを含む行の上にこれを追加する必要があります。
$color1: rebeccapurple;
次に、 example.scss
で、前に追加したレベル1の見出しのルールを追加します。
h1 { color: $color1; }
すべてが正しく設定されている場合は、public / cssに次のルールを含む.cssファイルがあることがわかります。
h1 { color: rebeccapurple; }
構築しているCSSを使用してコンポーネントをプレビューできるように、もう1つ行う必要があります。 パブリックフォルダからスタイルシートにリンクするプレビューファイルを作成する必要があります。
コンポーネントフォルダ内に、 _preview.hbsという名前のファイルを作成します。
プレビューファイルは基本的にHTMLドキュメントであり、CSSやその他の含める必要のあるものすべてにリンクしています。 本体にはタグ{{ yield }}
があり、ここにコンポーネントが配置されます。
<!doctype html> <html lang="en"> <head> <meta charset="utf-8" /> <title>Preview Layout</title> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <link rel="stylesheet" href="{{ path '/css/global.css' }}"> </head> <body> {{{ yield }}} </body> </html>
注:パブリックフォルダーには、画像やフォントなどのコンポーネントに表示する必要のあるその他のアセットを格納することもできます。
真実の情報源としてのパターンライブラリ
これまで見てきたように、フラクタルはCSSを構築できます。 私たちのプロジェクトでは、フラクタルがサイトのCSSやその他のアセットを構築および処理する唯一の場所になるようにしています。 これが意味するのは、パターンライブラリとサイトまたはアプリケーションがドリフトしないということです。 人々がサイトのCSSの編集を開始し、それらの変更をパターンライブラリに戻さない場合、サイトを展開した後にドリフトが発生します。 パターンライブラリをCSSが処理される場所にすることができれば、変更はそこから開始する必要があります。これにより、ライブサイトとライブラリの間のドリフトが防止されます。
すべてをFractalで構築し、それらのパブリックアセットをライブサイトにコピーしてデプロイします。 システム間のドリフトを防ぐだけでなく、ソース管理でのCSSの管理もはるかに簡単になります。 複数の人が1つのCSSファイルで作業する場合、マージの競合に対処するのはかなり難しい場合があります。 パターンライブラリ内の個々のコンポーネントで作業している人は、通常、2人が同時に同じファイルに変更を加えることを回避できます。そうする場合、CSSのすべてではなく、整理するための小さなファイルにすぎません。
フォールバックを管理するためのパターンライブラリの最初のアプローチの使用
パターンライブラリを使用すると、最初に、完全なサイトまたはアプリケーションを一度に修正しようとするよりも、コード内のフォールバックをはるかに簡単に処理でき、手間がかからないことがわかりました。 また、サポートされていないブラウザーでどのように機能するかを心配することで、私たちが行うことを制限するのではなく、可能な限り最良のケースに集中し、新しい技術で創造的になることができます。
メディアオブジェクトコンポーネントの単純なケースを見て、それがどのように機能するかを確認できます。 続いて、Fractalのコンポーネント内にメディアフォルダーを作成し、 media.hbsファイルとmedia.scssファイルを追加します。
良いマークアップから始める
出発点は、常に適切に構造化されたマークアップである必要があります。 パターンライブラリでは、このコンポーネントをさまざまなマークアップで使用する場合があります。たとえば、ある場所では図としてマークアップされたコンテンツを持ち、別の場所ではdivだけでマークアップされたコンポーネントを使用できます。 ただし、コンテンツは、意味があり、上から下に読むことができるように構成する必要があります。
これにより、コンテンツに非常に基本的なレベルでアクセスできるようになりますが、通常のフローを利用できることも意味します。 通常のフローは、ブラウザがデフォルトでコンテンツを表示する方法であり、ブロック要素はブロックディメンションで次々に進行し、インライン要素(文中の単語など)はインライン軸に沿って実行されます。 まさにあなたが望むものである多くのコンテンツのために、そしてそれと戦うのではなく通常の流れを利用することによって、あなたはあなたのレイアウトを作成するときにあなたの仕事をはるかに簡単にします。
したがって、私のコンポーネントには、 media.hbsに追加する次のマークアップがあります。
<div class="media"> <div class="img"> <img src="/img/placeholder.jpg" alt="Placeholder"> </div> <h2 class="title">This is my title</h2> <div class="content"> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis vehicula vitae ligula sit amet maximus. Nunc auctor neque ipsum, ac porttitor elit lobortis ac. Vivamus ultrices sodales tellus et aliquam. Pellentesque porta sit amet nulla vitae luctus. Praesent quis risus id dolor venenatis condimentum.</p> </div> <div class="footer"> An optional footer goes here. </div> </div>
これがフラクタル内にどのように表示されるかを確認できます。
必要なマークアップを取得したら、念頭に置いているデスクトップディスプレイで作業します。 CSSグリッドレイアウトとgrid-template-areas
メソッドを使用します。 以下をmedia.scssに追加します。
img { max-width: 100%; } .media > .title { grid-area: title; } .media > .img { grid-area: img; } .media > .content { grid-area: bd; } .media > .footer { grid-area: ft; } .media { margin-bottom: 2em; display: grid; grid-column-gap: 20px; grid-template-columns: 200px 3fr; grid-template-areas: "img title" "img bd" "img ft"; }
これで、単純なメディアオブジェクトレイアウトができました。
フラクタルでできることは、コンポーネントのバリエーションを追加することです。 画像が右側になるように、メディアオブジェクトを反転することをお勧めします。
次に、レイアウトを反転するために、CSSをmedia.scssに追加します。
.media.media-flip { grid-template-columns: 3fr 200px ; grid-template-areas: "title img" "bd img" "ft img"; }
バリアントを作成するには、ファイルベースと構成ベースの2つの方法があります。 ファイルベースは最も単純で、バリアントのマークアップが異なる場合にも役立ちます。 ファイルベースのバリアントを作成するには、mediaフォルダーにmedia --flip.hbs (ファイル名に2つのダッシュ)という名前でコンポーネントのコピーを作成します。
このコンポーネントには、最初の行に追加されたクラスmedia-flip
と同じマークアップが必要です。そうすると、両方のバージョンを表示できるようになります。
<div class="media media-flip">
または、この場合のように、クラスを追加するだけで、構成ファイルを使用してバリアントを作成できます。
これを行う場合は、バリアントファイルを削除し、代わりに次のコードを含むmedia.config.jsonという名前の構成ファイルを追加します。
{ "title": "Media Object", "context": { "modifier": "default" }, "variants": [ { "name": "Flipped", "context": { "modifier": "flip" } } ] }
次に、 media.hbsの最初の行を次のように変更します。
<div class="media media-{{ modifier }}">
注:バリアントはいくつでも追加できます(詳細については、バリアントのドキュメントを参照してください)。
ここで、画面サイズに基づいてレイアウトを変更するためにCSSを追加することを検討するかもしれません。 メディアクエリで作成したレイアウトをラップし、それよりも小さいデバイス用の単一列レイアウトを作成します。
img { max-width: 100%; } .media > .title { grid-area: title; } .media > .img { grid-area: img; } .media > .content { grid-area: bd; } .media > .footer { grid-area: ft; } .media { display: grid; grid-column-gap: 20px; grid-template-areas: "title" "img" "bd" "ft"; } @media (min-width: 600px) { .media { margin-bottom: 2em; display: grid; grid-column-gap: 20px; grid-template-columns: 200px 3fr; grid-template-areas: "img title" "img bd" "img ft"; } .media.media-flip { grid-template-columns: 3fr 200px ; grid-template-areas: "title img" "bd img" "ft img"; } }
次に、コンポーネント内の小さなデバイスのビューを管理するのと同じように、グリッドをサポートしていない古いブラウザーのレイアウトを管理できます。
この場合、フロートベースのフォールバックを作成します(これはほとんどすべてのレガシーブラウザーで機能します)。 画面サイズが広い場合にのみ心配し、古いモバイルデバイスの場合はコンポーネントを通常のフローで表示したままにします。
メディアクエリのすぐ内側に、次のCSSを追加します。
.media:after { content: ""; display: table; clear: both; } .media > .media { margin-left: 160px; clear: both; } .media .img { float: left; margin: 0 10px 0 0; width: 150px; } .media.media-flip .img { float: right; margin: 0 0 0 10px; } .media > * { margin: 0 0 0 160px; } .media.media-flip > * { margin: 0 160px 0 0; }
これにより、グリッド以外のブラウザでの表示が整理されます。 グリッドをサポートしているブラウザの場合、フロートについて心配する必要はありません。つまり、フロートされたアイテムがグリッドアイテムになると、フロートは削除されます。 問題になるのはマージンです。 グリッドをサポートするブラウザのレイアウトは、余分なマージンがあるため、すべて間隔が空けられます。
ここで機能クエリを追加し、ブラウザがグリッドをサポートしていることがわかっている場合は余白を削除できます。
@supports(display: grid) { .media > *, .media.media-flip > * { margin: 0; } .media .img, .media.media-flip .img { width: auto; margin: 0; } .media:after { content: none; } }
これで小さなコンポーネントが完成しました。 簡単な例ですが、フォールバックが必要な場合はグリッドをまったく必要としないと主張されるかもしれませんが、大小を問わず、すべてのプロジェクトで採用しているアプローチを示しています。
CSSファイルを本番環境に移行するには、パブリックフォルダーからCSSファイルを取得して、本番サイトに追加します。 このプロセスをスクリプト化して、ビルド時にサイトフォルダーにコピーすることもできます。
削減されたテストケースの最初の開発
このように作業することの重要な利点として私が発見したことは、それが実際にパズルのブラウザサポート部分をより簡単にするということです。 このコンポーネントに含まれているフォールバックCSSを確認しやすくなるだけでなく、ブラウザーで問題が発生した場合でも、デバッグがはるかに簡単になります。
あなたがブラウザの問題と戦っているとき、あなたが一般的にするように言われることは、縮小されたテストケースを作成することです。 問題を示す最小のものに問題を減らします。 パターンライブラリのコンポーネントは、多くの場合、すでにその縮小されたテストケースに非常に近いものです。 Webサイト全体を見ながら問題をデバッグしようとしている場合よりも、確かにはるかに近くなります。
ブラウザのデバッグを容易にすることに加えて、CSSの残りの部分と一緒にフォールバックを含めると、必要がなくなったフォールバックコードを簡単に削除できます。このフォールバックコードがこのコンポーネント用であることは明らかです。 それを削除しても、他のものの表示方法は変わらないことを私は知っています。
このようにコードを簡単に整理できるため、小さなプロジェクトでもFractalが理にかなっています。 とにかく(小規模なプロジェクトでも)GulpとSassを使用する傾向があることを考えると、Fractalをミックスに追加することは大きなオーバーヘッドではありません。 小さなサイトでも適度な量のCSSがある可能性があるため、大規模なプロジェクトだけでそれを確認する必要はありません。
コードを参照してください
記事に記載されているすべてのコードを含むGitHubプロジェクトを作成しました。 記事で説明されているようにFractalを設定してから、リポジトリからgulpfileやプレビューレイアウトなどのビットを取得することをお勧めします。
追加のリファレンスとして、またいくつかの公開されたFractalプロジェクトを確認するために、公開されたバージョンのPerchパターンライブラリと、24 Waysのパターンライブラリ(Paul Robert Lloydによって作成)があります。 これらは、非Webサイトのパターンライブラリの良い例であり、サイトに使用されるより伝統的なものです。
CSSをどのように管理しますか?
私はこの働き方が本当に好きです。 それは私がCSSを簡単で漸進的に強化された方法で書くことを可能にします。 プロジェクトによっては、ファイルのツールと処理がはるかに多く含まれる場合があります。 または、単純なサイトを構築している場合もあります。その場合、セットアップはこの記事で見たものとほぼ同じになります。Sassを少し処理します。 Fractalは、大小さまざまなサイト、WebアプリケーションまたはWebサイトで同じプロセスを実行できることを意味します。 それは私たちがいつも慣れ親しんだ方法で働くことができることを意味します。
これは私たちのために機能します、そして私はこの記事があなたに実験するためのいくつかのことを与えるかもしれないことを願っています。 しかし、私はあなたとあなたのチームがあなたのプロジェクトでCSSを管理するためにどのようにアプローチしたか、そしてあなたが試みたアプローチの長所と短所を知りたいです。 別のパターンライブラリソリューションを使用して同様のプロセスを開発した人からの連絡に特に興味があります。 コメントにあなたの経験を追加してください。