設定コンポーネントの作成

スライダーとチェックボックスの設定コンポーネントを作成する方法の基本概要。

この投稿では、アプリ用の設定コンポーネントを構築する方法について ウェブは、応答性に優れ、複数のデバイス入力をサポートし、 できます。デモをお試しください。

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph> デモ

動画をご希望の場合や、開発中の UI/UX のプレビューを確認したい場合は、 YouTube の短いチュートリアル:

概要

このコンポーネントの側面を以下のセクションに分けました。

  1. レイアウト
  2. カスタム範囲の入力
  3. カスタム チェックボックス入力
  4. ユーザー補助に関する考慮事項
  5. JavaScript
で確認できます。

レイアウト

これは、すべての CSS グリッドを対象とした最初の GUI チャレンジのデモです。これが各グリッドと グリッド用 Chrome DevTools でハイライト表示されている:

設定レイアウトを構成するすべてのボックスを表示するのに役立つ、カラフルなアウトラインとギャップ間隔オーバーレイ

ギャップのためだけ

最も一般的なレイアウト:

foo {
  display: grid;
  gap: var(--something);
}

このレイアウトは“隙間を空けて”グリッドを使用してブロック間のギャップを追加するだけです。

この戦略を使用しているレイアウトは 5 つあります。以下にすべてを示します。

枠線でハイライト表示され、ギャップが塗りつぶされた垂直グリッド レイアウト

各入力グループ(.fieldset-item)を含む fieldset 要素は、gap: 1px を使用して以下を行います。 要素間に細長い境界線を作成します。厄介な枠線は必要ない!

ギャップを埋める
.grid {
  display: grid;
  gap: 1px;
  background: var(--bg-surface-1);

  & > .fieldset-item {
    background: var(--bg-surface-2);
  }
}
ボーダー トリック
.grid {
  display: grid;

  & > .fieldset-item {
    background: var(--bg-surface-2);

    &:not(:last-child) {
      border-bottom: 1px solid var(--bg-surface-1);
    }
  }
}

ナチュラル グリッド ラッピング

最も複雑なレイアウトは最終的に、マクロ レイアウト、つまり論理レイアウトです。 <main><form> の間。

ラッピング コンテンツを中央に配置する

Flexbox とグリッドはどちらも、align-itemsまたは align-content。また、要素のラップを処理する場合は content レイアウト 配置は、子間にグループとしてスペースを配分します。

main {
  display: grid;
  gap: var(--space-xl);
  place-content: center;
}

主な要素は place-content: center 配置を使用 です。 1 列レイアウトと 2 列レイアウトの両方で、子が垂直方向と水平方向に中央寄せされます。

上の動画では、「コンテンツ」とテキストが折りたたまれていても中央に 発生します。

自動調整の最小値と最大値を繰り返す

<form> は、セクションごとにアダプティブ グリッド レイアウトを使用します。 このレイアウトでは、使用可能なスペースに応じて列が 1 列から 2 列に切り替わります。

form {
  display: grid;
  gap: var(--space-xl) var(--space-xxl);
  grid-template-columns: repeat(auto-fit, minmax(min(10ch, 100%), 35ch));
  align-items: flex-start;
  max-width: 89vw;
}

このグリッドの row-gap(--space-xl)の値と column-gap(--space-xxl)の値が異なります レスポンシブ レイアウトに調整を加えることができます。列が積み重なると 大画面ならではのギャップは必要ないと 思うかもしれません

grid-template-columns プロパティでは、repeat()minmax()、および 3 つの CSS 関数を使用します。 min()Una Kravetsレイアウトに関するブログ それについて投稿し、 RAM

Una のレイアウトと比較すると、このレイアウトには 3 つの特別な追加要素があります。

  • 追加の min() 関数を渡します。
  • align-items: flex-start を指定します。
  • max-width: 89vw スタイルがあります。

追加の min() 関数については、Evan Minto 氏のブログで post minmax() を使用した本質的なレスポンシブ CSS グリッドと min() を使用します。 ぜひ一読されることをおすすめします。flex-start の配置調整は次のようになります。 デフォルトの伸縮効果を削除して、このレイアウトの子が 同じ高さにする必要がありますが、自然で本質的な高さを持つことができます。「 YouTube 動画では、この調整の追加について簡単に確認できます。

この投稿では、max-width: 89vw について詳しく解説します。 スタイルを適用した場合と適用しない場合のレイアウトを示します。

どういうことですか?max-width を指定すると、コンテキストが提供され、 明示的なサイズ設定または auto-fit のサイズ レイアウト アルゴリズムを使用して、 スペースにあてはまりますおわかりのように、 CSS のグリッド仕様に従い、サイズを確定するか、最大サイズにする必要がある 提供されません。ここに最大サイズを指定しています

では、なぜ 89vw なのでしょうか。「うまくいった」ため選択します なぜもっと妥当な価値なのかを Chrome の仲間数人が調査しています。 100vw などでは不十分で、実際はバグかどうかも確認します。

間隔

このレイアウトの調和の大部分は、限られたスペース、7 厳密に言えません。

:root {
  --space-xxs: .25rem;
  --space-xs:  .5rem;
  --space-sm:  1rem;
  --space-md:  1.5rem;
  --space-lg:  2rem;
  --space-xl:  3rem;
  --space-xxl: 6rem;
}

グリッド、CSS @nestレベル 5 の構文で、これらのフローを適切に使用する できます。スタイルの完全な <main> レイアウト セットの例を以下に示します。

main {
  display: grid;
  gap: var(--space-xl);
  place-content: center;
  padding: var(--space-sm);

  @media (width >= 540px) {
    & {
      padding: var(--space-lg);
    }
  }

  @media (width >= 800px) {
    & {
      padding: var(--space-xl);
    }
  }
}

コンテンツが中央に配置されたグリッド。デフォルトで適度にパディングされます(モバイルと同様)。しかし、 利用可能なビューポートのスペースが増えると、パディングも増加します。 2021 年の CSS はかなりいい内容ですね。

先ほどの「ギャップを埋める」レイアウトを覚えていますか?こちらは、生成 AI の このコンポーネントでの表示:

header {
  display: grid;
  gap: var(--space-xxs);
}

section {
  display: grid;
  gap: var(--space-md);
}

色をコントロールすることで、このデザインは表現力あると同時に存在感を際立たせることができました 最小限に抑える必要があります。次のような操作を行います。

:root {
  --surface1: lch(10 0 0);
  --surface2: lch(15 0 0);
  --surface3: lch(20 0 0);
  --surface4: lch(25 0 0);

  --text1: lch(95 0 0);
  --text2: lch(75 0 0);
}

サーフェスとテキストの色には、数字ではなく数字で名前を付けます。 surface-darksurface-darker という 2 つのプロパティがあります。メディアクエリでは、 光と暗は意味を成しません。

次のように設定メディアクエリで切り替えます。

:root {
  ...

  @media (prefers-color-scheme: light) {
    & {
      --surface1: lch(90 0 0);
      --surface2: lch(100 0 0);
      --surface3: lch(98 0 0);
      --surface4: lch(85 0 0);

      --text1: lch(20 0 0);
      --text2: lch(40 0 0);
    }
  }
}

テストの前に重要なのは、全体像と戦略の概要を 色の構文について詳しく説明しますでも、私は先手を打ったので、 説明します

LCH?

LCH は色理論の分野に深く踏み込みすぎず、人間向けの構文です。 数学で色を測る方法ではなく、色を認識する方法に対応する 255)。これにより、人間がより簡単に記述できるようになり、 調整に適応できます。

<ph type="x-smartling-placeholder">
</ph> 「カラー 2: Perception」のエピソードが表示された pod.link/csspodcast のウェブページのスクリーンショット <ph type="x-smartling-placeholder">
</ph> 知覚色などについて詳しくは、CSS Podcast をご覧ください。

本日のデモでは、構文と切り替える値に注目しましょう。 明るさと暗さを調整します。1 つのサーフェスと 1 つのテキスト色を見てみましょう。

:root {
  --surface1: lch(10 0 0);
  --text1:    lch(95 0 0);

  @media (prefers-color-scheme: light) {
    & {
      --surface1: lch(90 0 0);
      --text1:    lch(40 0 0);
    }
  }
}

--surface1: lch(10 0 0) は、明度 10%、彩度 0、色相 0 に変換されます。 非常に暗い無色グレーです。次に、ライトモードのメディアクエリで、 --surface1: lch(90 0 0);90% に反転します。これが Chronicle の 説明します。まず、2 つのテーマの明るさを調整し、 コントラスト比やアクセシビリティを維持できる要素を指定します。

ここでの lch() の長所は、明るさが人間向けであり、 % の変更は、それが知覚的にも一貫して % 違います。たとえば、hsl()ではありません 信頼性

やりたいことはほかにもあります 詳しくは、 興味がある場合は、lch() を使用します。もうすぐ!

現時点では、CSS ではこれらの色にアクセスできません。 繰り返しになりますが現代の現代において 提供しますこれらは単なる色ではなく 表示できます。モニター ハードウェアの進化により、ウェブサイトは古くなっている CSS 仕様やブラウザの実装よりも高速です。

Lea Verou 氏

カラーパターンによるアダプティブ フォーム コントロール

多くのブラウザにはダークモードのコントロールが搭載されています。現在 Safari と Chromium では、 デザインで使用することを CSS または HTML で指定する必要があります。

上記は、[スタイル] パネルのプロパティの効果を示しています。 DevTools。このデモでは HTML タグを使用します。 最適な場所:

<meta name="color-scheme" content="dark light">

詳しくは、color-scheme Thomas による記事 Steiner。得られるものはまだたくさんあります ダーク チェックボックス入力より優れているということです。

CSS accent-color

最近の アクティビティです。 フォーム要素に対する accent-color(単一の CSS スタイル)で、 ブラウザの入力要素で使用される色合いです。詳しくはこちら GitHubこちらの 作成します。ブラウザでサポートされているため、チェックボックスは ピンクと紫のカラーでテーマに 重点を置いています

input[type="checkbox"] {
  accent-color: var(--brand);
}

ピンクのチェックボックスが表示されている Linux 版 Chromium のスクリーンショット

固定グラデーションとフォーカスのカラーポップ

色は控えめに使うと引き立ちます さまざまなカスタマイズが可能です

上の動画には、UI のフィードバックとインタラクションが何層にも重なっているので、次の方法でインタラクションに個性を持たせることができます。

  • コンテキストの強調。
  • 「フル充電状況」の UI フィードバックを提供する値が範囲内にあることを確認します。
  • フィールドが入力を受け付けているという UI フィードバックを提供する。

要素が操作されているときにフィードバックを提供するため、CSS では :focus-within 疑似クラスを使用して、さまざまな要素の見た目を変更します。次は、 .fieldset-item、とても興味深いですね。

.fieldset-item {
  ...

  &:focus-within {
    background: var(--surface2);

    & svg {
      fill: white;
    }

    & picture {
      clip-path: circle(50%);
      background: var(--brand-bg-gradient) fixed;
    }
  }
}

この要素の子の 1 つがフォーカス対象内である場合:

  1. .fieldset-item 背景に、よりコントラストの高いサーフェス色が割り当てられます。
  2. ネストされている svg は、コントラストが高くなるように白く塗りつぶされます。
  3. ネストされた <picture> clip-path は 1 つの円に展開され、 背景が明るい固定グラデーションで塗りつぶされます。

期間を指定

以下の HTML 入力要素を想定し、HTML 入力要素をどのようにカスタマイズして 外観:

<input type="range">

この要素はカスタマイズする必要のある 3 つの部分があります。

  1. 範囲要素 / コンテナ
  2. 追跡
  3. つまみ

範囲要素のスタイル

input[type="range"] {
  /* style setting variables */
  --track-height: .5ex;
  --track-fill: 0%;
  --thumb-size: 3ex;
  --thumb-offset: -1.25ex;
  --thumb-highlight-size: 0px;

  appearance: none;         /* clear styles, make way for mine */
  display: block;
  inline-size: 100%;        /* fill container */
  margin: 1ex 0;            /* ensure thumb isn't colliding with sibling content */
  background: transparent;  /* bg is in the track */
  outline-offset: 5px;      /* focus styles have space */
}

CSS の最初の数行はスタイルのカスタム部分です。 明確なラベルを付けましょう残りのスタイルはほぼすべて 複雑な部分を作成するための一貫した基盤を提供します。

トラックのスタイル

input[type="range"]::-webkit-slider-runnable-track {
  appearance: none; /* clear styles, make way for mine */
  block-size: var(--track-height);
  border-radius: 5ex;
  background:
    /* hard stop gradient:
        - half transparent (where colorful fill we be)
        - half dark track fill
        - 1st background image is on top
    */
    linear-gradient(
      to right,
      transparent var(--track-fill),
      var(--surface1) 0%
    ),
    /* colorful fill effect, behind track surface fill */
    var(--brand-bg-gradient) fixed;
}

コツは、鮮やかな塗りつぶしの色にします。これは ハードストップのグラデーションですグラデーションは塗りつぶし率まで透明で、塗りつぶし率の上限までは透明です。 塗りつぶされていないトラック サーフェス色を使用します。その不充填面の背後には 透明度が現れるまで待機します。

塗りつぶしのスタイル

塗りつぶしスタイルを維持するために JavaScript が必要なデザインです。そこで、 CSS のみの戦略だが、つまみ要素の高さを同じにする必要がある 限界内でハーモニーを見つけられませんでした

/* grab sliders on page */
const sliders = document.querySelectorAll('input[type="range"]')

/* take a slider element, return a percentage string for use in CSS */
const rangeToPercent = slider => {
  const max = slider.getAttribute('max') || 10;
  const percent = slider.value / max * 100;

  return `${parseInt(percent)}%`;
};

/* on page load, set the fill amount */
sliders.forEach(slider => {
  slider.style.setProperty('--track-fill', rangeToPercent(slider));

  /* when a slider changes, update the fill prop */
  slider.addEventListener('input', e => {
    e.target.style.setProperty('--track-fill', rangeToPercent(e.target));
  })
})

これにより、見た目が良くなると思います。このスライダーは JavaScript の場合、--track-fill プロパティは必須ではありません。単に 塗りつぶしスタイルが存在しない場合は、塗りつぶしスタイル。JavaScript を使用できる場合は、 ユーザーの変更を監視しながら、カスタム プロパティを あります。

Google Pixel 8 と 投稿 Ana による CSS-Tricks Tudor のような、CSS のみのソリューションである トラックフィルを設定しますこちらも見つかりました range 要素は非常に魅力的です。

サムネイルのスタイル

input[type="range"]::-webkit-slider-thumb {
  appearance: none; /* clear styles, make way for mine */
  cursor: ew-resize; /* cursor style to support drag direction */
  border: 3px solid var(--surface3);
  block-size: var(--thumb-size);
  inline-size: var(--thumb-size);
  margin-top: var(--thumb-offset);
  border-radius: 50%;
  background: var(--brand-bg-gradient) fixed;
}

これらのスタイルの大部分は、適切な円を描くためのものです。 固定された背景グラデーションで サム、トラック、関連する SVG 要素のダイナミック カラー。 box-shadow を分離できるように、インタラクションのスタイルを分離しました マウスオーバーによるハイライト表示に使用されている手法は次のとおりです。

@custom-media --motionOK (prefers-reduced-motion: no-preference);

::-webkit-slider-thumb {
  

  /* shadow spread is initally 0 */
  box-shadow: 0 0 0 var(--thumb-highlight-size) var(--thumb-highlight-color);

  /* if motion is OK, transition the box-shadow change */
  @media (--motionOK) {
    & {
      transition: box-shadow .1s ease;
    }
  }

  /* on hover/active state of parent, increase size prop */
  @nest input[type="range"]:is(:hover,:active) & {
    --thumb-highlight-size: 10px;
  }
}

目標は、管理しやすいように、ユーザー フィードバック用のアニメーションで視覚的に目立たせることでした。 ボックス シャドウを使用することで、トリガーの発生や、 必要があります。実行する ぼかしが入らず 円形の形状に thumb 要素を使用します。次に、カーソルを合わせるとスプレッド サイズの変更と移行を行います。

チェックボックスのハイライト効果が簡単だったら...

ブラウザをまたいだセレクタ

クロスブラウザを実現するには、これらの -webkit--moz- セレクタが必要だった 一貫性:

input[type="range"] {
  &::-webkit-slider-runnable-track {}
  &::-moz-range-track {}
  &::-webkit-slider-thumb {}
  &::-moz-range-thumb {}
}

カスタム チェックボックス

以下の HTML 入力要素を想定し、HTML 入力要素をどのようにカスタマイズして 外観:

<input type="checkbox">

この要素はカスタマイズする必要のある 3 つの部分があります。

  1. チェックボックス要素
  2. 関連付けられているラベル
  3. ハイライト効果

チェックボックス要素

input[type="checkbox"] {
  inline-size: var(--space-sm);   /* increase width */
  block-size: var(--space-sm);    /* increase height */
  outline-offset: 5px;            /* focus style enhancement */
  accent-color: var(--brand);     /* tint the input */
  position: relative;             /* prepare for an absolute pseudo element */
  transform-style: preserve-3d;   /* create a 3d z-space stacking context */
  margin: 0;
  cursor: pointer;
}

transform-style スタイルと position スタイルは、後で紹介する疑似要素用に準備します。 ハイライトのスタイルを設定しますそれ以外のほとんどの 私の意見は大好きですカーソルがポインタになるのが好きです。 枠線のオフセット、デフォルトのチェックボックスが小さすぎる、accent-colorサポートされているため、 チェックボックスをブランドのカラーパターンに 反映させることができます

チェックボックスのラベル

チェックボックスにラベルを付けることが重要な理由は 2 つあります。1 つ目は、 チェックボックスの値の用途を表し、「オン / オフの対象」と回答します。 2 つ目は UX です。ウェブユーザーは チェックボックスを オン/オフできます

入力
<input
  type="checkbox"
  id="text-notifications"
  name="text-notifications"
>
ラベル
<label for="text-notifications">
  <h3>Text Messages</h3>
  <small>Get notified about all text messages sent to your device</small>
</label>

ラベルに、ID でチェックボックスを参照する for 属性を設定します(<label for="text-notifications">)。チェックボックスで、名前と ID を 2 倍にして、 マウスやスクリーンリーダーなど、さまざまなツールやテクノロジーで見つかります。 <input type="checkbox" id="text-notifications" name="text-notifications">。 接続すると :hover:active などが無料で利用でき、 いくつかご紹介します。

チェックボックスのハイライト表示

インターフェースの一貫性を保ちたいので、 チェックボックスで使用するサムネイルのハイライトを選択しますサムネイル: box-shadow とその spread プロパティを使用してシャドウを拡大し、 できます。しかし、チェックボックスは有効で、 あります。

疑似要素でも同じ視覚効果を得ることができました。 CSS:

@custom-media --motionOK (prefers-reduced-motion: no-preference);

input[type="checkbox"]::before {
  --thumb-scale: .01;                        /* initial scale of highlight */
  --thumb-highlight-size: var(--space-xl);

  content: "";
  inline-size: var(--thumb-highlight-size);
  block-size: var(--thumb-highlight-size);
  clip-path: circle(50%);                     /* circle shape */
  position: absolute;                         /* this is why position relative on parent */
  top: 50%;                                   /* pop and plop technique (https://web.dev/centering-in-css#5-pop-and-plop) */
  left: 50%;
  background: var(--thumb-highlight-color);
  transform-origin: center center;            /* goal is a centered scaling circle */
  transform:                                  /* order here matters!! */
    translateX(-50%)                          /* counter balances left: 50% */
    translateY(-50%)                          /* counter balances top: 50% */
    translateZ(-1px)                          /* PUTS IT BEHIND THE CHECKBOX */
    scale(var(--thumb-scale))                 /* value we toggle for animation */
  ;
  will-change: transform;

  @media (--motionOK) {                       /* transition only if motion is OK */
    & {
      transition: transform .2s ease;
    }
  }
}

/* on hover, set scale custom property to "in" state */
input[type="checkbox"]:hover::before {
  --thumb-scale: 1;
}

円の疑似要素を作成するのは簡単な作業ですが、 処理が難しくなりますこれが事前トレーニングと 修正後:

確かにマイクロインタラクションですが、ビジュアルを維持することも重要です。 実現します。アニメーションの拡大縮小の手法は、 できます。カスタム プロパティに新しい値を設定し、CSS にその値を移行させる 自動的に作成されます。ここでの主な機能は translateZ(-1px) です。「 親が 3D 空間を作成し、この疑似要素の子が z 空間に少し戻ります。

ユーザー補助

YouTube の動画では、マウス、キーボード、マウスの使い方のデモンストレーションが この設定コンポーネントのスクリーンリーダー操作です。ここでは、Chronicle の こちらで詳細をご覧いただけます。

HTML 要素の選択

<form>
<header>
<fieldset>
<picture>
<label>
<input>

それぞれに、ユーザーのブラウジング ツールに対するヒントとヒントが含まれています。一部の要素 インタラクションのヒントを提供するほか、インタラクティビティ機能をつなげる、 ユーザー補助ツリーの 一例です

HTML 属性

スクリーンリーダーで不要な要素は非表示にできます スライダーの隣のアイコン:

<picture aria-hidden="true">

上の動画は、Mac OS でのスクリーンリーダーのフローを示しています。入力シーケンスの あるスライダーから次のスライダーにフォーカスが直接移動します。これは、名前が非表示になっているため アイコンが下がったときに停止した可能性があります。これなし 属性では、ユーザーは立ち止まって耳を傾け、その絵を通り過ぎてしまうため、 見えなくなる可能性があります

SVG は数学的な要素です。<title> 要素を追加して、マウスで自由にカーソルを合わせてみましょう タイトルと、数学が生成する内容についての人が読めるコメントを付加します。

<svg viewBox="0 0 24 24">
  <title>A note icon</title>
  <path d="M12 3v10.55c-.59-.34-1.27-.55-2-.55-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4V7h4V3h-6z"/>
</svg>

それ以外は、明確にマークされた HTML を使用しており、フォームでテストできます。 マウス、キーボード、ビデオゲームコントローラ、 スクリーンリーダーに対応しています

JavaScript

JavaScript からトラックの塗りつぶしの色を管理する方法はすでに説明しました<form> 関連の JavaScript を見てみましょう。

const form = document.querySelector('form');

form.addEventListener('input', event => {
  const formData = Object.fromEntries(new FormData(form));
  console.table(formData);
})

フォームが操作または変更されるたびに、フォームが サーバーに送信する前に簡単に確認できるように、オブジェクトをテーブルに変換できます。

console.table() の結果のスクリーンショット。フォームデータがテーブルに表示されている

まとめ

私のやり方わかったな、どうやって?!楽しい時間をお過ごしください 説明します。誰が最初のバージョンを フレームワーク🙂

アプローチを多様化して、ウェブで構築するすべての方法を学びましょう。 デモを作成し、ツイートしてリンクを送ってください 下のコミュニティのリミックスのセクションをご覧ください。

コミュニティ リミックス

  • @tomayac に、 チェックボックスのラベルにカーソルを合わせますこのバージョンの間にカーソルを合わせるギャップはありません 要素: demo出典