代表的な面接トピック

フロントエンド面接:CSS @function はどのようにデザイントークンを再利用するか?

フロントエンド難しい
Offer.cc 編集チーム公開日 更新日

質問

スペーシングトークンをレスポンシブな長さに変換する CSS @function を実装し、カスタムプロパティ、Sass関数、ブラウザフォールバックとの境界について説明してください。

1. 課題とスコープ

あるデザインシステムにスペーシングトークンが存在し、各コンポーネントは密度とコンテナ幅から padding を計算しています。チームは、プレーンなCSS、テーマの上書き、古いブラウザの挙動を維持しつつ、重複する calc() 式を減らしたいと考えています。CSS @function を使用したソリューションを設計し、安全なフォールバックを説明してください。

2. 面接官がテストしていること

  • @function-- で始まる dashed-ident を名前とする CSS カスタム関数を定義することを理解しているか。
  • 引数、デフォルト値、オプションの型、result を宣言しつつ、その本体が JavaScript のように最初の宣言で return するわけではないことを把握しているか。
  • カスタム関数、カスタムプロパティ、Sass のビルド時関数、ランタイムのカスケードの違いを区別できるか。
  • 機能検知、テーマの継承、循環参照、互換性、アクセシブルなプログレッシブエンハンスメントを適切に扱えるか。

3. 最初に明確にすべき質問

  1. CSS Functions に未対応の対象ブラウザは何であり、ポリフィルは許可されていますか?
  2. トークンは固定の長さですか、パーセンテージですか、それとも calc() やコンテナ単位を含む可能性のある値ですか?
  3. 無効な引数が渡された場合、デフォルト値を使用すべきですか、宣言を無効化すべきですか、それともコンポーネントのフォールバックを使用すべきですか?
  4. テーマはトークンを :root、コンポーネントスコープ、それとも Shadow DOM 境界のどこで定義していますか?

4. 30秒の簡潔な回答

拡張された宣言の前に動作する静的な padding を配置し、その後 @supports の内部でそれを上書きします。関数は型指定されデフォルト値を持つ引数を使用し、result を通じて長さを返します。カスタムプロパティがテーマの入力を提供し、関数が計算を実行します。未対応のブラウザは未知の関数を無視し、前のフォールバックを維持します。

5. ステップ別の詳細解説

ステップ 1: パラメータと結果の定義

css
@function --space(--step <integer>: 2, --base <length>: 4px) {
  result: calc(var(--base) * var(--step));
}

パラメータはローカルのカスタムプロパティであり、CSSの型とデフォルト値を宣言できます。result は最終的な値を提供します。これは JavaScript の早期 return ではないため、関数は CSS の宣言処理ルールに従います。

ステップ 2: 関数をトークンに接続する

css
:root {
  --space-base: 4px;
}

.card {
  padding: 16px;
  padding: --space(3, var(--space-base));
}

最初の宣言は古いブラウザ向けのフォールバックであり、2番目の宣言はカスタム関数がパースされた際に適用されます。トークンはカスタムプロパティを介してカスケードし続けるため、テーマやコンポーネントスコープで --space-base を上書きできます。

ステップ 3: 型と無効な値の処理

型制約は、文法に一致しない値を拒否します。デフォルト値は省略された引数をカバーするものであり、長さになるべき任意の文字列を処理するものではありません。負の値、不正な単位、欠落しているトークンをテストし、ユーザー制御の文字列を CSS 関数の引数に決して連結しないでください。

ステップ 4: スコープと依存関係の理解

関数パラメータは本体内部でローカルカスタムプロパティとして機能しますが、呼び出し側は依然としてカスケード、継承、レイヤーの順序に従います。関数で使用されるトークンは、関数の結果に逆依存してはなりません。循環が発生すると、計算された宣言が無効になります。

ステップ 5: 機能検知とプログレッシブエンハンスメント

css
.card {
  padding: 16px;
}

@supports (padding: --space(3, 4px)) {
  .card {
    padding: --space(3, var(--space-base, 4px));
  }
}

@supports はパース能力をテストするものであり、すべてのビジネスブランチを網羅するわけではありません。安定したフォールバックを維持し、計算されたレイアウトを検証して、未対応のブラウザでも読みやすいテキスト、フォーカスインジケータ、タッチターゲットのサイズが維持されることを確認してください。

6. 質の高い模範解答

私は静的な padding を提供し、その後 @supports 内で @function を使用して拡張された値を計算します。カスタムプロパティがテーマの値を保持し、型指定された引数と result が計算を実行します。省略された引数、誤った単位、負の値、および循環参照をテストします。サポート状況は依然としてブラウザごとに異なるため、フォールバックは単独で成立する必要があり、ブラウザ検証によって計算されたスタイルとアクセシブルな寸法を確認する必要があります。

7. よくある間違い

  • CSS @function を Sass のビルド時関数として扱う → 本番環境のブラウザがそれを無視する → ランタイムフォールバックを維持し、機能検知を行う。
  • 単位のない数値を <length> パラメータに渡す → 宣言が無効になる → 型とデフォルト値を明確に指定する。
  • 関数がカスタムプロパティを変更すると想定する → テーマの上書きに失敗する → トークン入力と result 出力を分離する。
  • ベース宣言なしで @supports のみを記述する → 未対応ブラウザでスペーシングが失われる → 最初にフォールバックを記述する。
  • 関数同士を相互参照させる → 循環依存により値が無効になる → トークンの依存関係を一方向に保つ。

8. フォローアップの質問

フォローアップ 1: カスタムプロパティと何が違うのですか?

カスタムプロパティはカスケードする値を保持します。カスタム関数は引数を受け取り、結果を計算します。関数は継承されたトークン入力を読み取りながら、計算ロジックを再利用できます。

フォローアップ 2: Sass 関数と何が違うのですか?

Sass 関数はビルド時に CSS を出力し、ランタイムのテーマやコンテナの状態を監視できません。CSS カスタム関数はブラウザのカスケードおよび計算中に実行されるため動的ですが、互換性の処理が必要です。

フォローアップ 3: サポートをどのように検知しますか?

先行するフォールバックを保持しつつ、@supports (padding: --space(1, 4px)) を使用してパースを検知します。テストでは、実際のブラウザで計算された値も検証する必要があります。

フォローアップ 4: 循環をどのように回避しますか?

ベーストークンを生の値に依存させ、関数がトークンを読み取って派生値を出力するようにし、トークンが関数の結果を含むプロパティを参照することを禁止します。DevTools で無効な計算値を確認してください。

公開情報ソース

関連する質問