CSS の発展の歴程:
- ネイティブの CSS ルールの手書き、代表:
BEM
命名規則 - プリプロセッサ
Sass
、Less
、Stylus
など - アフタープロセッサ
PostCSS
、プラグインベース、例:autoprefix
CSS Modules
、webpack
、Gulp
、Parcel
などのビルドツールと組み合わせて使用する必要がありますCSS in JS
、代表:React
ベースのstyled-component
ネイティブの CSS ルールはグローバルに適用されます。スタイルの衝突を避けるために、さまざまな解決策が提案されています。
BEM 命名規則#
開発レベルでの名前の衝突を回避し、クラス名をより意味のあるものにし、より多くの説明とより明確な構造を持たせるために、ブロック、エレメント、修飾子(Yandex チームによって提案された)というフロントエンドの CSS 命名規則が登場しました。
-
ハイフン:連結記号としてのみ使用され、ブロックやサブエレメントの複数の単語をつなぐために使用されます__
ダブルアンダースコア:ブロックとブロックのサブエレメントを接続するために使用されます--
ダブルハイフン:要素の状態や種類などを記述、修飾するために使用されます
/* ブロックは、開発の単一のコンポーネントまたはモジュール(Component)と見なすことができます */
.article-detail {
display: flex;
}
/* エレメントはブロックの構成要素です */
.article-detail__button {
width: 120px;
height: 36px;
}
/* 修飾子は要素の状態や種類などを記述、修飾するために使用されます */
.article-detail__button--primary {
color: #fff;
background-color: #3af;
}
ただし、欠点も明らかです。BEM
の命名方法は手書きが煩雑で、開発効率が低く、メンテナンスが困難です。
CSS Modules#
CSS Modules
は本質的には CSS ファイルであり、単独で使用することはできず、パッケージングビルドツールと組み合わせて使用する必要があります。CSS Modules
はネイティブの CSS に多くの新しい機能を提供します。
- 明示的にローカルとグローバルの CSS ルールを記述することをサポートします
- モジュールとして
JS
ファイルにロードおよび使用することを許可します - パッケージング時にクラス名をハッシュ値に変換し、CSS クラス名の衝突を防ぎます
/* style.css */
.className {
color: green;
background: red;
}
.otherClassName {
/* スタイルの組み合わせ(composes)をサポートします */
composes: className;
color: yellow;
}
.otherClassName {
/* 他のファイルからのインポートをサポートします */
composes: className from './style.css';
}
/* 上記のスタイルはデフォルトでローカルスコープです */
/* ローカルスコープ */
:local(p) {
color: #333;
}
/* グローバルスコープ */
:global(p) {
color: #333;
}
import styles from './style.css'
// import { className } from "./style.css";
element.innerHTML = '<div class="' + styles.className + '">'
// element.innerHTML = '<div class="' + styles['class-name'] + '">';
webpack
と組み合わせて使用する場合、次のように設定します:
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: {
loader: 'css-loader',
options: {
modules: {
// カスタムハッシュ名、変数を使用できます
localIdentName: '[path][name]__[local]--[hash:base64:5]'
}
}
}
}
]
}
}
パッケージング後の効果(クラス名がカスタムハッシュ名の形式に変換されます):
._2DHwuiHWMnKTOYG45T0x34 {
color: red;
}
._10B-buq6_BEOTOl9urIjf8 {
background-color: blue;
}
Sass、Less、Stylus#
フロントエンド開発者が CSS を簡単に記述するために、さまざまなプリプロセッサが登場しました:
これらのプリプロセッサは、一部の構文と機能の違いを除いて、次の特徴を持っています:
- デフォルトのローカルスコープ
- ネストされたルールのサポート
- スタイルの組み合わせ、継承のサポート
- 同じプリプロセッサの外部スタイルファイルのインポート(
@import
)の許可 - 変数、関数(カラー関数など)の使用を許可
- パッケージングコンパイル時にクラス名をハッシュ処理し、衝突の問題を回避します
これら以外にも、異なるプリプロセッサには条件文、ループ文などの異なる特徴があります。詳細は各プリプロセッサのドキュメントを参照してください。
ただし、注意点があります。@import
でインポートするのがネイティブの CSS 形式のファイルの場合、追加のhttp
リクエストが発生します。
一方、プリプロセッサの@import
は、対応するプリプロセッサのファイルをインポートするため、構文の意味レベルでのインポートであり、ネイティブの CSS をインポートするわけではありません。そのため、パッケージングコンパイル時に処理され、最終的には 1 つの CSS ファイルが生成されます。http
リクエストは増えません。
/* ネイティブのCSSをインポートすると、httpリクエストが増えます */
@import 'reset.css';
/* プリプロセッサ形式、lessは対応するプリプロセッサのファイル拡張子です(例:scss、styl) */
/* body.less */
body {
background: #eee;
}
/* style.less */
@import 'body.less';
PostCSS#
フロントエンドのエンジニアリングの発展に伴い、重複する作業をすべてビルドツールに任せることを望むツールが増えてきました。CSS の領域では、PostCSS
が台頭しました。
PostCSS
は CSS の構文木(AST)を分析し、その結果を処理することで、フロントエンド開発者にとって煩雑で複雑な作業を一連の処理で完了します。一般的な使用シナリオには次のものがあります:
- 言語の構文チェックツールと組み合わせて構文エラーの検出を実現する、例:stylelint
- CSS の次世代バージョンの構文ルールをトランスパイル(
Transpilers
)およびポリフィル(polyfill
)処理する - プラグインと組み合わせて特定の機能を実現する、例:
autoprefix
を使用してブラウザの接頭辞を自動的に追加する
CSS パフォーマンスの最適化について#
一般的な CSS パフォーマンスの最適化方法:
- ファイルの分割を減らすことで、複数の CSS ファイルをリクエストする際のネットワークの影響を受けるのを減らす
- CSS のネストを減らし、3 階層を超えないようにすることを推奨します
- 不要な CSS セレクタを削除し、適切な CSS セレクタを選択すること、例:id セレクタの前に他のセレクタを追加する必要はありません
- 同じ種類の要素のスタイルを複数再利用する、例:
button
、input
要素など - ワイルドカードセレクタ(
*
)や属性セレクタ([name=nav]
)の使用を減らすこと。このようなセレクタは通常、すべての要素を走査する必要があります - 無効な、重複したスタイルを削除する、例:一部のプロパティは継承される特性を持っているため、親要素で定義されている場合は子要素で再度設定する必要はありません
- ページ間で共通の CSS ルールを個別の CSS ファイルに分離する、例:
normalize.css
など。ブラウザは 1 回だけ読み込むだけで済みます(次回はキャッシュを使用) - 画像やアイコンのリクエスト回数を減らすために、CSS スプライト(またはスプライト画像、スプライトシートとも呼ばれる)を使用する
- CSS の圧縮最適化ツールやプロジェクトのビルドツールを使用して CSS を圧縮する
@import
の使用を減らすこと。追加のリクエストが発生し、読み込み順序に影響を与えます(CSS プリプロセッサは除外)- 大規模で頻繁なレイアウトの再配置(ウィンドウ、要素、テキストのサイズ変更、レイアウトの切り替え、サイズ計算など)を減らし、レンダリングの負荷を軽減する
JS
を使用して単一の CSS スタイルを変更することを避ける。必要な場合は、まず CSS クラスを定義し、クラス名を変更してスタイルを変更します- 複雑でパフォーマンス要件の高い CSS アニメーションの使用を減らす