フローティング アクション ボタン(FAB)コンポーネントの作成

色が適応し、レスポンシブで、ユーザー補助に対応した FAB コンポーネントを作成する方法の基本的な概要。

この投稿では、色に適応し、レスポンシブで、ユーザー補助に対応した FAB コンポーネントを作成する方法について説明します。デモを試すソースを表示する

動画で確認したい場合は、YouTube 版の投稿をご覧ください。

概要

FAB はパソコンよりもモバイルで一般的ですが、どちらのシナリオでもよく使用されます。プライマリ アクションが常に表示されるため、便利でどこでもアクセスできます。このユーザー エクスペリエンス スタイルはマテリアル UI で有名になりました。使用方法と配置に関する推奨事項については、こちらをご覧ください。

要素とスタイル

これらのコントロールの HTML には、コンテナ要素と 1 つ以上のボタンのセットが含まれます。コンテナは、FAB をビューポート内に配置し、ボタン間のギャップを管理します。ボタンはミニサイズまたはデフォルトサイズに設定でき、メイン アクションとセカンダリ アクションを使い分けることができます。

FAB コンテナ

この要素は通常の <div> でもかまいませんが、視覚障がいのあるユーザーのために、このコンテナの目的と内容を説明する便利な属性をタグ付けしましょう。

FAB のマークアップ

まず、CSS がスタイルにフックする .fabs クラスから始め、role="group"aria-label を追加して、単なる汎用コンテナではなく、名前が付けられ、目的のあるコンテナにします。

<div class="fabs" role="group" aria-label="Floating action buttons">
  <!-- buttons will go here -->
</div>

FAB のスタイル

FAB を便利に使うには、常にビューポート内に固定します。これは、位置情報 fixed の優れたユースケースです。このビューポートの位置では、inset-blockinset-inline を使用するように選択しました。これにより、右から左や左から右など、ユーザーのドキュメント モードに応じて位置が補完されます。カスタム プロパティは、繰り返しを防ぎ、ビューポートの下端と側端から同じ距離になるようにするためにも使用されます。

.fabs {
  --_viewport-margin: 2.5vmin;

  position: fixed;
  z-index: var(--layer-1);

  inset-block: auto var(--_viewport-margin);
  inset-inline: auto var(--_viewport-margin);
}

次に、コンテナ ディスプレイに flex を指定し、レイアウトの向きを column-reverse に変更します。これにより、子が重ねて(列に)配置され、視覚的な順序が逆になります。これにより、最初のフォーカス可能な要素が、HTML ドキュメントに従って通常フォーカスが移動する上部ではなく、下部要素になります。視覚的な順序を逆にすると、視覚に障がいのあるユーザーとキーボード ユーザーのエクスペリエンスが統一されます。プライマリ アクションのスタイルをミニボタンよりも大きくすると、視覚に障がいのあるユーザーにはプライマリ アクションであることが示され、キーボード ユーザーはソース内の最初の項目としてフォーカスします。

2 つのファビコン ボタンが表示され、DevTools がグリッド レイアウトにオーバーレイされています。ストライプ パターンでそれらの間のギャップが表示され、計算された高さと幅も表示されます。

.fabs {
  

  display: flex;
  flex-direction: column-reverse;
  place-items: center;
  gap: var(--_viewport-margin);
}

中央揃えは place-items で処理され、gap はコンテナに配置された FAB ボタンの間にスペースを追加します。

FAB ボタン

次は、ボタンにスタイルを適用して、すべての要素の上に浮かんでいるように見せます。

デフォルトの FAB

最初にスタイル設定するボタンがデフォルトのボタンです。これは、すべての FAB ボタンのベースとして機能します。後で、これらのベーススタイルをできるだけ変更せずに、別の外観を実現するパターンを作成します。

FAB のマークアップ

<button> 要素が正しい選択です。マウス、タップ、キーボードの優れたユーザー エクスペリエンスが提供されるため、まずこれをベースにします。このマークアップで最も重要な点は、aria-hidden="true" を使用してスクリーン リーダー ユーザーに対してアイコンを非表示にし、必要なラベルテキストを <button> マークアップ自体に追加することです。このような場合にラベルを追加する場合は、title も追加して、マウス ユーザーがアイコンが伝えようとしている内容に関する情報を取得できるようにします。

<button data-icon="plus" class="fab" title="Add new action" aria-label="Add new action">
  <svg aria-hidden="true" width="24" height="24" viewBox="0 0 24 24">...</svg>
</button>

FAB のスタイル

まず、ボタンをパディング付きの丸いボタンに変更し、強いシャドウを追加します。これは、ボタンの最初の特徴です。

.fab {
  --_size: 2rem;

  padding: calc(var(--_size) / 2);
  border-radius: var(--radius-round);
  aspect-ratio: 1;
  box-shadow: var(--shadow-4);
}

次に、色を追加しましょう。ここでは、以前の GUI チャレンジで使用した戦略を使用します。明るい色と暗い色を静的に保持するカスタム プロパティのセットをわかりやすい名前で作成し、ユーザーのシステムの色の設定に応じて明るい変数または暗い変数に設定される適応型カスタム プロパティを作成します。

.fab {
  

  /* light button and button hover */
  --_light-bg: var(--pink-6);
  --_light-bg-hover: var(--pink-7);

  /* dark button and button hover */
  --_dark-bg: var(--pink-4);
  --_dark-bg-hover: var(--pink-3);

  /* adaptive variables set to light by default */
  --_bg: var(--_light-bg);

  /* static icon colors set to the adaptive foreground variable */
  --_light-fg: white;
  --_dark-fg: black;
  --_fg: var(--_light-fg);

  /* use the adaptive properties on some styles */
  background: var(--_bg);
  color: var(--_fg);

  &:is(:active, :hover, :focus-visible) {
    --_bg: var(--_light-bg-hover);

    @media (prefers-color-scheme: dark) {
      --_bg: var(--_dark-bg-hover);
    }
  }

  /* if users prefers dark, set adaptive props to dark */
  @media (prefers-color-scheme: dark) {
    --_bg: var(--_dark-bg);
    --_fg: var(--_dark-fg);
  }
}

次に、SVG アイコンがスペースに収まるようにスタイルを追加します。

.fab {
  

  & > svg {
    inline-size: var(--_size);
    block-size: var(--_size);
    stroke-width: 3px;
  }
}

最後に、インタラクション用の独自の視覚的なフィードバックを追加したので、ボタンのタップ ハイライトを削除します。

.fab {
  -webkit-tap-highlight-color: transparent;
}

ミニ FAB

このセクションでは、FAB ボタンのバリエーションを作成します。一部の FAB をデフォルトのアクションよりも小さくすることで、ユーザーが最も頻繁に行うアクションを宣伝できます。

ミニ FAB のマークアップ

HTML は FAB と同じですが、「.mini」クラスを追加して、CSS がパターンにフックできるようにします。

<button data-icon="heart" class="fab mini" title="Like action" aria-label="Like action">
  <svg aria-hidden="true" width="24" height="24" viewBox="0 0 24 24">...</svg>
</button>
ミニ FAB スタイル

カスタム プロパティを使用すると、必要な変更は --_size 変数の調整のみです。

.fab.mini {
  --_size: 1.25rem;
}

2 つのファブボタンが重ねて表示され、上部のボタンが下部のボタンよりも小さいスクリーンショット。

ユーザー補助

FAB のユーザー補助機能で最も重要なのは、ページのキーボード フロー内の配置です。このデモには FAB のみがあり、キーボードの順序とフローに関して競合するものがないため、有意なキーボード フローを示す機会がありません。フォーカスの競合要素があるシナリオでは、ユーザーが FAB ボタンフローに移動するフロー内の場所をよく検討することをおすすめします。

キーボード操作のデモ

ユーザーが FAB コンテナにフォーカスすると、role="group"aria-label="floating action buttons" がすでに追加されており、スクリーン リーダーのユーザーにフォーカスされている内容を通知します。ユーザーが最初に主要なアクションを見つけられるように、デフォルトの FAB を最初に配置しました。次に、flex-direction: column-reverse; を使用して、メインボタンを下部に配置し、ユーザーの指に近づけて簡単にアクセスできるようにします。これは、デフォルトのボタンが視覚的に目立つため、キーボード ユーザーにとっても最初に表示され、非常に類似したエクスペリエンスを提供できるという点で、大きなメリットです。

最後に、スクリーン リーダーを使用するユーザーに対してアイコンを非表示にし、ボタンのラベルを指定することを忘れないでください。これは、<svg>aria-hidden="true"<button>aria-label="Some action" で HTML ですでに行われています。

アニメーション

さまざまな種類のアニメーションを追加して、ユーザー エクスペリエンスを向上させることができます。他の GUI チャレンジと同様に、モーションの少ないエクスペリエンスとモーションの多いエクスペリエンスの意図を保持するカスタム プロパティをいくつか設定します。デフォルトでは、ユーザーがモーションを抑制することを前提としてスタイルが設定され、prefers-reduced-motion メディアクエリを使用して、遷移値がフルモーションに切り替わります。

カスタム プロパティを使用したモーション抑制戦略

次の CSS では、--_motion-reduced--_motion-ok--_transition の 3 つのカスタム プロパティが作成されます。最初の 2 つは、ユーザーの設定に応じて適切な遷移を保持し、最後の変数 --_transition はそれぞれ --_motion-reduced または --_motion-ok に設定されます。

.fab {
  /* box-shadow and background-color can safely be transitioned for reduced motion users */
  --_motion-reduced:
    box-shadow .2s var(--ease-3),
    background-color .3s var(--ease-3);

  /* add transform and outline-offset for users ok with motion */
  --_motion-ok:
    var(--_motion-reduced),
    transform .2s var(--ease-3),
    outline-offset 145ms var(--ease-2);

  /* default the transition styles to reduced motion */
  --_transition: var(--_motion-reduced);

  /* set the transition to our adaptive transition custom property*/
  transition: var(--_transition);

  /* if motion is ok, update the adaptive prop to the respective transition prop */
  @media (prefers-reduced-motion: no-preference) {
    --_transition: var(--_motion-ok);
  }
}

上記を設定すると、box-shadowbackground-colortransformoutline-offset の変更を移行して、操作が受信されたことをユーザーにわかりやすく UI でフィードバックできます。

次に、translateY を少し調整して :active 状態に少し華やかさを追加します。これにより、ボタンに押された効果が付加されます。

.fab {
  

  &:active {
    @media (prefers-reduced-motion: no-preference) {
      transform: translateY(2%);
    }
  }
}

最後に、ボタンの SVG アイコンに変更を適用します。

.fab {
  

  &[data-icon="plus"]:hover > svg {
    transform: rotateZ(.25turn);
  }

  & > svg {
    @media (prefers-reduced-motion: no-preference) {
      will-change: transform;
      transition: transform .5s var(--ease-squish-3);
    }
  }
}

まとめ

私の方法をご覧になったところで、あなたならどうしますか?

アプローチを多様化し、ウェブで構築するすべての方法を学びましょう。

デモを作成して、ツイートしてください。リンクを送信していただければ、下のコミュニティ リミックスのセクションに追加します。

コミュニティ リミックス

表示する項目はありません。

リソース