スタイルシステムのコーディング方法について

このビデオでは、Experience Managerのコアタイトルコンポーネントのスタイル設定に使用されるCSS(またはLESS)とJavaScriptの構造と、これらのスタイルがHTMLおよびDOMにどのように適用されるかについて説明します。

スタイルシステムのコーディング方法について

提供されているAEMパッケージ(technical-review.sites.style-system-1.0.0.zip)では、サンプルのタイトルスタイル、We.Retailレイアウトコンテナおよびタイトルコンポーネントのサンプルポリシー、およびサンプルページがインストールされます。

technical-review.sites.style-system-1.0.0.zip

CSS

次に、にあるサンプルスタイルのLESS定義を示します。

  • /apps/demo/sites/style-system/clientlib-example/components/titles/styles/example.less

CSSを好むユーザーの場合、このコードスニペットの下に、このLESSによってコンパイルされるCSSが表示されます。

/* LESS */
.cmp-title--example {
 .cmp-title {
  text-align: center;

  .cmp-title__text {
   color: #EB212E;
   font-weight: 600;
   font-size: 5rem;
   border-bottom: solid 1px #ddd;
   padding-bottom: 0;
   margin-bottom: .25rem
  }

  // Last Modified At element injected via JS
  .cmp-title__last-modified-at {
   color: #999;
   font-size: 1.5rem;
   font-style: italic;
   font-weight: 200;
  }
 }
}

上記のLESSは、次のCSSにExperience Managerでネイティブにコンパイルされます。

/* CSS */
.cmp-title--example .cmp-title {
 text-align: center;
}

.cmp-title--example .cmp-title .cmp-title__text {
 color: #EB212E;
 font-weight: 600;
 font-size: 5rem;
 border-bottom: solid 1px #ddd;
 padding-bottom: 0;
 margin-bottom: 0.25rem;
}

.cmp-title--example .cmp-title .cmp-title__last-modified-at {
 color: #999;
 font-size: 1.5rem;
 font-style: italic;
 font-weight: 200;
}

JavaScript

次のJavaScriptは、サンプルスタイルがタイトルコンポーネントに適用されている場合に、現在のページの最終変更日時をタイトルテキストの下に収集し、挿入します。

jQueryの使用はオプションで、使用する命名規則も同様です。

次に、にあるサンプルスタイルのLESS定義を示します。

  • /apps/demo/sites/style-system/clientlib-example/components/titles/styles/js/title.js
/**
 * JavaScript supporting Styles may be re-used across multi Component Styles.
 *
 * For example:
 * Many styles may require the Components Image (provided via an <img> element) to be set as the background-image.
 * A single JavaScript function may be used to adjust the DOM for all styles that required this effect.
 *
 * JavaScript must react to the DOMNodeInserted event to handle style-switching in the Page Editor Authoring experience.
 * JavaScript must also run on DOM ready to handle the initial page load rendering (AEM Publish).
 * JavaScript must mark and check for elements as processed to avoid cyclic processing (ie. if the JavaScript inserts a DOM node of its own).
 */
jQuery(function ($) {
    "use strict;"

    moment.locale("en");

    /**
     * Method that injects p element, containing the current pages last modified date/time, under the title text.
     *
     * Similar to the CSS Style application, component HTML elements should be targeted via the BEM class names (as they define the stable API)
     * and targeting "raw" elements (ex. "li", "a") should be avoided.
     */
    function applyComponentStyles() {

        $(".cmp-title--example").not("[data-styles-title-last-modified-processed]").each(function () {
            var title = $(this).attr("data-styles-title-last-modified-processed", true),
                url = Granite.HTTP.getPath() + ".model.json";

            $.getJSON(url, function(data) {
                var dateObject = moment(data['lastModifiedDate']),
                    titleText = title.find('.cmp-title__text');

                titleText.after($("<p>").addClass("cmp-title__last-modified-at").text("Last modified " + dateObject.fromNow()));
            });
        });
    }

    // Handle DOM Ready event
    applyComponentStyles();

    // Apply Styles when a component is inserted into the DOM (ie. during Authoring)
    $(".responsivegrid").bind("DOMNodeInserted", applyComponentStyles);
});

開発のベストプラクティス

HTMLのベストプラクティス

  • HTML(HTLを使用して生成)は、できるだけ構造的に意味のあるものにする必要があります。要素の不要なグループ化やネストを回避する。
  • HTML要素は、BEMスタイルのCSSクラスを使用してアドレス可能にする必要があります。

良い — コンポーネント内のすべての要素は、BEM表記でアドレス可能です。

<!-- Good practice -->
<div class="cmp-list">
    <ul class="cmp-list__item-group">
        <li class="cmp-list__item">...</li>
    </ul>
</div>

不良 — リスト要素とリスト要素は要素名でのみアドレス可能です。

<!-- Bad practice -->
<div class="cmp-list">
    <ul>
        <li>...</li>
    </ul>
</div>
  • 公開するバックエンド開発を必要とするデータを少なくして公開するよりも、公開するデータを増やして非表示にする方が効果的です。

    • 作成者がHTMLをリーンな状態に保つのに役立つオーサー可能なコンテンツトグルの実装。オーサー可能なコンテンツトグルを使用すると、作成者は、HTMLに書き込むコンテンツ要素を選択できます。 は、特に、すべてのスタイルで使用されるとは限らない、HTMLに画像を書き込む場合に重要になります。

    • このルールの例外は、CSSで非表示のイベント画像は必要なく取得されるので、高価なリソース(画像など)がデフォルトで公開される場合です。

      • 最新の画像コンポーネントでは、多くの場合、JavaScriptを使用して、ユースケース(ビューポート)に最適な画像を選択して読み込みます。

CSSのベストプラクティス

メモ

BEMで指定されたようにBLOCKBLOCK--MODIFIERが同じ要素に適用されない点で、スタイルシステムはBEMとは技術的に多少異なります。

代わりに、製品の制約により、BLOCK--MODIFIERBLOCK要素の親に適用されます。

BEMのその他すべてのテナントは、と整合する必要があります。

  • CSSの定義を明確にし、再利用性を高めるために、 LESS (AEMでネイティブにサポート)やSCSS (カスタムビルドシステムが必要)などのプリプロセッサーを使用します。

  • セレクターの重み/特異性を均一にする。これにより、識別が困難なCSSカスケードの競合を回避し、解決できます。

  • 各スタイルを個別のファイルに編成します。

    • LESS/SCSS @importsを使用して、または生のCSSが必要な場合は、HTMLクライアントライブラリファイルを含めるか、カスタムフロントエンドアセットビルドシステムを使用して、これらのファイルを組み合わせることができます。
  • 多くの複雑なスタイルを混在させないでください。

    • 1つのコンポーネントに一度に適用できるスタイルが多いほど、順列の種類が多くなります。 これは、ブランドの整合性の維持/QA/確保が難しくなる可能性があります。
  • 常にCSSクラス(BEM表記に従う)を使用して、CSSルールを定義します。

    • CSSクラスを持たない要素(つまり、ベア要素)を選択する必要が絶対にある場合は、CSS定義でそれらの要素を上に移動して、選択可能なCSSクラスを持つそのタイプの要素との競合よりも特異性が低いことを明確にします。
  • BLOCK--MODIFIERはレスポンシブグリッドに添付されるので、直接スタイルを設定しないでください。 この要素の表示を変更すると、レスポンシブグリッドのレンダリングと機能に影響を与える可能性があるので、レスポンシブグリッドの動作を変更する目的がある場合にのみ、このレベルのスタイルを設定できます。

  • BLOCK--MODIFIERを使用してスタイル範囲を適用します。 BLOCK__ELEMENT--MODIFIERSはコンポーネントで使用できますが、BLOCKはコンポーネントを表し、コンポーネントはスタイル設定されるので、スタイルはBLOCK--MODIFIERを介して「定義」され、スコープされます。

CSSセレクターの構造の例を次に示します。

第1レベルセレクタ

BLOCK:MODIFIER

第2レベルセレクター

ブロック

第3レベルセレクター

BLOCK__ELEMENT

有効なCSSセレクター
.cmp-list—dark .cmp-list .cmp-list__item

.cmp-list—dark

.cmp-list

.cmp-list__item {

色:青。

}

.cmp-image—hero .cmp-image .cmp-image__caption

.cmp-image—hero

.cmp-image

.cmp-image__caption {

色:赤

}

コンポーネントがネストされている場合、これらのネストされたコンポーネント要素のCSSセレクターの深さは、第3レベルのセレクターを超えます。 ネストされたコンポーネントに対して同じパターンを繰り返しますが、親コンポーネントのBLOCKで範囲が指定されます。 つまり、ネストされたコンポーネントのBLOCKを3番目のレベルで開始し、ネストされたコンポーネントのELEMENTを4番目のセレクターレベルで開始します。

JavaScriptのベストプラクティス

この節で定義するベストプラクティスは、「スタイルJavaScript」、つまり、機能的な目的ではなく、スタイル用にコンポーネントを操作することを目的としたJavaScriptに関係します。

  • Style-JavaScriptは慎重に使用する必要があり、少数派の使用例です。
  • Style-JavaScriptは、主に、CSSによるスタイル設定をサポートするためにコンポーネントのDOMを操作するために使用する必要があります。
  • コンポーネントがページ上に何度も表示される場合にJavaScriptの使用を再評価し、計算/再描画のコストを把握します。
  • コンポーネントがページに複数回表示される場合に、新しいデータ/コンテンツを(AJAXを介して)非同期で取り込む場合にJavaScriptの使用を再評価します。
  • 公開エクスペリエンスとオーサリングエクスペリエンスの両方を処理します。
  • 可能な場合は、style-JavaScriptを再使用します。
    • 例えば、1つのコンポーネントの複数のスタイルで画像を背景画像に移動する必要がある場合、style-JavaScriptを1回実装して複数のBLOCK--MODIFIERsに添付できます。
  • 可能な場合は、style-JavaScriptと機能JavaScriptを区切ります。
  • HTLを介してHTMLでこれらのDOM変更をJavaScriptのコストとマニフェストの両方を直接評価します。
    • スタイルJavaScriptを使用するコンポーネントでサーバー側の変更が必要な場合は、JavaScript操作がその時点で取り込めるかどうか、およびコンポーネントのパフォーマンスとサポートに与える影響と影響を評価します。

パフォーマンスに関する考慮事項

  • Style-JavaScriptは明るく、傾いた状態に保つ必要があります。
  • ちらつきや不要な再描画を避けるために、最初にBLOCK--MODIFIER BLOCKを介してコンポーネントを非表示にし、JavaScriptでのすべてのDOM操作が完了したら表示します。
  • スタイルとJavaScriptの操作のパフォーマンスは、DOMReady上の要素にアタッチして変更する基本的なjQueryプラグインと似ています。
  • リクエストがgzip圧縮され、CSSとJavaScriptが縮小されていることを確認します。

その他のリソース

このページ