アクセシビリティを改善するための運動の低減


もともと投稿a11ywithlindsey.com .
ヘイフレンズ!このポストでは、私はあなたに新しいメディア質問(私に)を知らせます.prefers-reduced-motion .
クイック告白:私はCSSの基礎を知っているが、私はかなり出ているすべての新しいものにかなり遅れている.私の焦点は通常アクセシビリティの上にあるので、私はHTMLとJavaScriptにはるかに集中しています.私がCSSに集中するとき、それは適当な色コントラストまたはカスタム焦点状態を確実にしています.時々私はCSSを使用するcheckboxes keyboard accessible . 私はいつも応答のデザインとメディアのクエリを関連付けられた.私はアクセシビリティの向上としてメディアクエリを考えたことがない.
このポストでは、ブログを更新しています.
  • 追加prefers-reduced-motion クエリ
  • 運動を減らすためのユーザ制御設定の追加
  • 理解は減少運動を好む


    アニメーション、ズーム、パンの前庭障害を持っている人々のための問題があります.これらの障害は、動揺病とめまいを引き起こすことができます.これらは、あなたがこれまでに対処したくない不快な感情です、単独でウェブサイトで聞かせてください.私の理解からvestibular system あなたの内耳にあり、バランスを制御するのに役立ちます.
    によるとvestibular.org , 米国で40歳以上の成人の最大35 %は前庭機能障害の何らかの形態を経験した.したがって、これは小さな問題ではありません.
    Webアクセシビリティ展望からの主要な取材
  • あなたのアニメーションに注意してください.
  • GIFに注意してください.
  • 用途prefers-reduced-motion .
  • ユーザーが縮小モーションを制御することができます.
  • どうやって


    クエリの実装はとても簡単です.
    @media screen and (prefers-reduced-motion: reduce) {
      /* Reduced Motion Code */
    }
    
    私のリンクのいくつかのアニメーションを持っているいくつかの場所があります.
    第一に、私のリンクは、私はそれが上にホバーを移動するときにダウンボーダーの底を持っています.

    それから、私たちがそれを乗り越えるとき、スケールが1.1 xより大きい行動リンクへの私の呼び出しが、あります.

    私は話していた、彼は私を与えたsome suggestions 実装.
    @media screen and (prefers-reduced-motion: reduce) {
      * {
        animation-play-state: paused !important;
        transition: none !important;
        scroll-behavior: auto !important;
      }
    }
    
    変更を実装した後、ホバーの効果がありますが、遷移はありません.


    この戦略は技術的によく働く.しかし、ホバー効果を取り除き、リンクをアンダーラインとしたい.私もスケールで遊ぶかもしれません.
    @media screen and (prefers-reduced-motion: reduce) {
      * {
        animation-play-state: paused !important;
        transition: none !important;
        scroll-behavior: auto !important;
      }
    
      a {
        padding-bottom: 0;
        border-bottom: none;
        text-decoration: underline;
      }
    }
    
    その変化で、今私のすべてのリンクは単純な下線です.

    移行アニメーションなしでは、アクションリンクへの呼び出しはscale(1) to scale(1.1) ホバーについてそこで変更しましたscale(1.05) .
    @media screen and (prefers-reduced-motion: reduce) {
      * {
        animation-play-state: paused !important;
        transition: none !important;
        scroll-behavior: auto !important;
      }
    
      a {
        padding-bottom: 0;
        border-bottom: none;
        text-decoration: underline;
      }
    
      .blog__more-link a {
        text-decoration: none;
      }
    
      .blog__more-link a:hover {
        transform: scale(1.05);
      }
    
      .hero__cta a {
        text-decoration: none;
      }
    
      .hero__cta a:hover {
        transform: scale(1.05);
      }
    }
    

    Macでテストする方法


    この設定は主にMacOSで利用可能です.
  • システム設定に移動
  • アクセシビリティ
  • 表示する
  • チェック"
  • 簡単なpeasy!このポストが公開されるとすぐに、あなたは私のブログでこれをテストすることができなければなりません!

    運動を減らすユーザ制御オプションの作成


    Andy Bell's dark mode post 私はユーザーコントロールのオプションを追加するように促した.我々は、優先順位を取るユーザーの好みを持っている.また、これらの設定を使用していない人々のアカウントをしたい.
    次のようにします.
  • ラベルを「縮小運動」でチェックボックスを作成します
  • 加えるchecked 状態と私のギャツビーのアプリでその状態を切り替える方法.
  • その状態を使用してdata-user-reduced-motion 属性.
  • 上記の属性を使用してCSSを適用します.
  • 保存するlocalStorage , したがって、ユーザー設定を保存します.
  • コンポーネントの作成


    このコンポーネントは、ラベルを持つHTMLチェックボックスです.免責事項として、私はclass コンポーネントとフック.私はまだ授業を書くのが好きです.フックバージョンの目を離さない!
    import React from 'react'
    
    class ReduceToggle extends React.Component {
      render() {
        return (
          <div className="toggle">
            <input id="reduce-motion" type="checkbox" />
            <label htmlFor="reduce-motion">Reduce Motion</label>
          </div>
        )
      }
    }
    
    export default ReduceToggle
    
    私がここでした唯一のことは、チェックボックス入力をassociated form label . あなたが気づいたかもしれないことは、代わりに、反応を使用することですhtmlFor .
    その後、私は私の中にそれを置きます<Header /> メニューの上のコンポーネント.後でスタイリングのフィネスを心配します私は、それが私のレイアウトを壊すということを知っています、そして、それはOKです.我々は今、機能だけを心配している.

    州に加える


    我々は先に行きたいとAを追加したいchecked コンストラクタへの状態.
    import React from 'react'
    
    class ReduceToggle extends React.Component {
      constructor(props) {
        super(props)
    
        this.state = {
          checked: false,
        }
      }
    
      render() {
        return (
          <div className="toggle">
            <input id="reduce-motion" type="checkbox" />
            <label htmlFor="reduce-motion">Reduce Motion</label>
          </div>
        )
      }
    }
    
    export default ReduceToggle
    
    今、我々はチェックボックスそのものにその状態を加えるつもりです.
    import React from 'react'
    
    class ReduceToggle extends React.Component {
      constructor(props) {
        super(props)
    
        this.state = {
          checked: false,
        }
      }
    
      render() {
        const { checked } = this.state
    
        return (
          <div className="toggle">
            <input
              id="reduce-motion"
              type="checkbox"
              checked={checked}
            />
            <label htmlFor="reduce-motion">Reduce Motion</label>
          </div>
        )
      }
    }
    
    export default ReduceToggle
    
    次に、私たちはtoggleChecked メソッドonChange イベント.
    import React from 'react'
    
    class ReduceToggle extends React.Component {
      constructor(props) {
        super(props)
    
        this.state = {
          checked: false,
        }
      }
    
      toggleChecked = event => {
        this.setState({ checked: event.target.checked })
      }
    
      render() {
        const { checked } = this.state
    
        return (
          <div className="toggle">
            <input
              id="reduce-motion"
              type="checkbox"
              checked={checked}
              onChange={this.toggleChecked}
            />
            <label htmlFor="reduce-motion">Reduce Motion</label>
          </div>
        )
      }
    }
    
    export default ReduceToggle
    
    私はいつも、状態が使用していることをダブルチェックするのが好きですReact Developer Tools . 以下のようにします.
  • 元素検査
  • 反応タブへ
  • を見つけるReduceToggle コンポーネント
  • 状態が正しく動作していることを確認してください!

  • 現在、我々は国家が働いているということを知っています.トグルをしましょうdata-user-reduced-motion 属性値documentElement . 私は、それを加えるつもりですcomponentDidUpdate ライフサイクル法.
    import React from 'react'
    
    class ReduceToggle extends React.Component {
      constructor(props) {
        super(props)
    
        this.state = {
          checked: false,
        }
      }
    
      componentDidUpdate() {
        const { checked } = this.state
    
        if (checked) {
          document.documentElement
            .setAttribute('data-user-reduced-motion', true)
        } else {
          document.documentElement
            .setAttribute('data-user-reduced-motion', false)
        }
      }
    
      toggleChecked = event => {
        this.setState({ checked: event.target.checked })
      }
    
      render() {
        const { checked } = this.state
    
        return (
          <div className="toggle">
            <input
              id="reduce-motion"
              type="checkbox"
              checked={checked}
              onChange={this.toggleChecked}
            />
            <label htmlFor="reduce-motion">Reduce Motion</label>
          </div>
        )
      }
    }
    
    export default ReduceToggle
    

    データユーザの縮小運動へのCSSの追加


    警告の言葉.それはCSSに飛び込んで、すべてのものをコピーして、ペーストすることを誘惑しています.私は一度にこの一歩を行うことをお勧めします.私はすぐにそれをしようとするというミスをして、私が欲しかったより多くの時間デバッグを費やしました.だからまず最初に私たちが望むもののゴールに戻りましょう.

    We want user preference to rule over system preferences. We'll add the system preferences as a progressive enhancement.


    Gatsbyは静的サイトジェネレータです、したがって、JavaScriptがロードされないならば、私の静的サイトの大部分はロードしなければなりません.しかし、JavaScriptがロードされていない場合、私たちは、システムの設定にdata-user-reduced-motion 属性が存在しません.それで、私たちがメディア質問自体について最初のセクションでした質問に少し加えます.だから私たちは:not() それをするCSS擬似クラス.
    @media screen and (prefers-reduced-motion: reduce) {
      * {
      :root:not([data-user-reduced-motion]) * {
        animation-play-state: paused !important;
        transition: none !important;
        scroll-behavior: auto !important;
      }
    
      a {
      :root:not([data-user-reduced-motion]) a {
        padding-bottom: 0;
        border-bottom: none;
        text-decoration: underline;
      }
    
      .blog__more-link a {
      :root:not([data-user-reduced-motion]) .blog__more-link a {
        text-decoration: none;
      }
    
      .blog__more-link a:hover {
      :root:not([data-user-reduced-motion]) .blog__more-link a:hover {
        transform: scale(1.05);
      }
    
      .hero__cta a {
      :root:not([data-user-reduced-motion]) .hero__cta a {
        text-decoration: none;
      }
    
      .hero__cta a:hover {
      :root:not([data-user-reduced-motion]) .hero__cta a:hover {
        transform: scale(1.05);
      }
    }
    
    それから、私たちはdata-user-reduced-motion="true" .
    :root[data-user-reduced-motion='true'] * {
      animation-play-state: paused !important;
      transition: none !important;
      scroll-behavior: auto !important;
    }
    
    :root[data-user-reduced-motion='true'] a {
      padding-bottom: 0;
      border-bottom: none;
      text-decoration: underline;
    }
    
    :root[data-user-reduced-motion='true'] .blog__more-link {
      text-decoration: none;
      padding: 12px 14px;
      border: 2px solid;
    }
    
    :root[data-user-reduced-motion='true'] .blog__more-link:hover {
      transform: scale(1.05);
    }
    
    :root[data-user-reduced-motion='true'] .hero__cta__link {
      text-decoration: none;
      padding: 12px 14px;
      border: 2px solid;
    }
    
    :root[data-user-reduced-motion='true'] .hero__cta__link:hover {
      transform: scale(1.05);
    }
    
    テストするには次のようにしました.
  • オフの任意の動きの設定を無効にするMacOS
  • 縮小トグルをオフにすると、すべてのアニメーションがまだそこにあることを確認します.
  • 縮小トグルチェックボックスをチェックし、すべてのCSSの変更を減らすために動きが動作していることを確認します.
  • 要素検査官で<html> ドキュメントと検索data-user-reduced-motion . 属性を削除します.ここでは、その属性がロードされないことをシミュレートします.
  • システムの設定に移動し、動きを減らすチェックします.私たちは縮小運動のためのCSSの変更を持っている必要があります!
  • LocalStorageの追加


    今、私たちは、その作業を持って、我々はlocalStorage . 我々は将来のユーザーの好みを維持したい.あなたの設定を選択するたびに、最高のユーザーエクスペリエンスされていません.あなたが何を知らないならばlocalStorage 私はここを一時停止し、その上をちらっと見るdocs . 閉じるこの動画はお気に入りから削除されています.
    まず最初にやることはlocalStoragecomponentDidMount .
    import React from 'react'
    
    class ReduceToggle extends React.Component {
      constructor(props) {
        super(props)
    
        this.state = {
          checked: false,
        }
      }
    
      componentDidMount() {
        let reduceMotionOn = localStorage.getItem('reduceMotionOn')
        console.log(reduceMotionOn)
        // if we haven't been to the site before
        // this will return null
      }
    
      // All other code stuff
    
      render() {
        return (
          <div className="toggle">
            <input id="reduce-motion" type="checkbox" />
            <label htmlFor="reduce-motion">Reduce Motion</label>
          </div>
        )
      }
    }
    
    export default ReduceToggle
    
    今私たちがしたいことは、ユーザーのためのデフォルトのLocalStorage状態を作成する場合reduceMotionOn はNULLです.私はそれを設定するつもりですfalse .
    import React from 'react'
    
    class ReduceToggle extends React.Component {
      constructor(props) {
        super(props)
    
        this.state = {
          checked: false,
        }
      }
    
      componentDidMount() {
        let reduceMotionOn = localStorage.getItem('reduceMotionOn')
    
        // Just a way to get around localStorage being
        // stored as a string and not a bool
        if (typeof reduceMotionOn === 'string') {
          reduceMotionOn = JSON.parse(reduceMotionOn)
        }
    
        if (reduceMotionOn === null) {
          localStorage.setItem('reduceMotionOn', false)
        }
      }
    
      // All other code stuff
    
      render() {
        return (
          <div className="toggle">
            <input id="reduce-motion" type="checkbox" />
            <label htmlFor="reduce-motion">Reduce Motion</label>
          </div>
        )
      }
    }
    
    export default ReduceToggle
    
    最後に私はコンポーネントをマウントするときにはアプリの状態に設定されます.私は私のアプリのものを保証したいと思いますlocalStorage .
    import React from 'react'
    
    class ReduceToggle extends React.Component {
      constructor(props) {
        super(props)
    
        this.state = {
          checked: false,
        }
      }
    
      componentDidMount() {
        let reduceMotionOn = localStorage.getItem('reduceMotionOn')
    
        if (typeof reduceMotionOn === 'string') {
          reduceMotionOn = JSON.parse(reduceMotionOn)
        }
    
        if (reduceMotionOn === null) {
          localStorage.setItem('reduceMotionOn', false)
        }
        this.setState({ checked: reduceMotionOn })
      }
    
      // All other code stuff
    
      render() {
        return (
          <div className="toggle">
            <input id="reduce-motion" type="checkbox" />
            <label htmlFor="reduce-motion">Reduce Motion</label>
          </div>
        )
      }
    }
    
    export default ReduceToggle
    
    Chromeのツールのローカルストレージを保存します.その後、クリアreduceMotionOn ストレージ.更新時にはreduceMotionOn が偽です.あなたがdevツールに反応して<ReduceToggle /> コンポーネントは、チェックされた状態がReasemotionOn LocalStorage項目と一致することがわかります.
    それはすべてではない!我々は、ローカルストレージをトグルする必要がありますtoggleChecked 反応成分中の方法.
    import React from 'react'
    
    class ReduceToggle extends React.Component {
      constructor(props) {
        super(props)
    
        this.state = {
          checked: false,
        }
      }
    
      // All other code stuff
    
      toggleChecked = event => {
        localStorage.setItem('reduceMotionOn', event.target.checked)
        this.setState({ checked: event.target.checked })
      }
    
      render() {
        return (
          <div className="toggle">
            <input id="reduce-motion" type="checkbox" />
            <label htmlFor="reduce-motion">Reduce Motion</label>
          </div>
        )
      }
    }
    
    export default ReduceToggle
    
    今、私は運動を減らして、サイトを去るならば、私のユーザー支配のセッティングは保存されます!

    結論


    私は私のブログに徐々に強化アクセシビリティ機能を追加しながら私に参加してくれてありがとう!あなたが道に沿って何かを学んだことを願っています.この記事を書くためにアンディに叫んでください!
    これらは、あなたが使用するフレームワークに関係なく、このポストからのキーの取出しです.
  • あなたがアニメーション化し、前庭疾患を持っている人のためのオプションを提供するものに注意してください.
  • ユーザ制御方式
  • プログレッシブ強化のためのシステム設定
  • 用途localStorage ユーザー設定が保存されるようにあなたの利益に!
  • あなたがこれで遊ぶことを望むならば、私はあなたのためにCodesandboxを作りました!
    タッチで滞在!この記事が好きなら
  • 私に知っているし、お友達とこの記事を共有する!また、任意のフォローアップの質問や考えをつぶやくために自由に感じてください.
  • サポート・オンpatreon ! あなたが私の仕事が好きなら、1ドルの毎月の誓約をすることを考えてください.あなたが\5ドル誓約またはより高いならば、あなたは将来のブログ記事に投票することができます!私も、すべての後援者のために私に何かセッションを尋ねます!

  • Be the first to learn about my posts より多くのアクセシビリティFunsiesのために!
  • 乾杯!良い一週間を!