F/EチームでモブプロしてMarkuplintを導入した
この記事はYAMAPアドベントカレンダー4日目の記事です。
はじめに
株式会社ヤマップでフロントエンドエンジニアをしています。t-yngです。
ヤマップのフロントエンドチームではアクセシビリティの改善に取り組んでおり、その一環としてチームで定期的にモブプロを実施してMarkuplintの導入を行いました。
最初にMarkuplintを実行した所、エラーが30個ほど検出されました。誰か1人がまとめて修正してしても良かったですが、チーム内でのスキルアップやレビューコストのことを意識してチームでモブプロ数回に分けて実施して導入を進めました。
今回は検出されたエラーと対応した内容をまとめていきます。
導入までの流れ
- Markuplintのエラーを整理
- モブプロでエラー対応
Markuplintのエラー整理
最初にMarkuplintを実行して、どれだけエラーが発生するか確認します。
ここでほとんどエラーが発生しない場合は、そのままちょっと修正して導入完了でOKだと思います。
この時点で検出されたエラーをカテゴリーごとに分類して、修正計画を立てました。
エラーのカテゴリー分類は、例えば次のようなエラーを要素「yyy」には属性「xxx」が必要です (required-attr)
というカテゴリーにまとめていきます。
- error: 要素「img」には属性「width」が必要です (required-attr)
- error: 要素「img」には属性「height」が必要です (required-attr)
- error: 要素「img」には属性「decoding」が必要です (required-attr)
- error: 要素「iframe」には属性「title」が必要です (required-attr)
Markuplintエラーの一覧
整理したエラーのカテゴリーです。
idの重複やidの未指定など、思ったよりも気づいてないエラーが多く存在していました。
- ロール「generic」では、ARIAプロパティ「aria-label」は許可されていません (wai-aria)
- 属性「〇〇」は非推奨です (deprecated-attr)
- アクセシブルな名前が必要です (require-accessible-name)
- 要素「yyy」には属性「xxx」が必要です (required-attr)
- 不正な文字は文字参照でエスケープするべきです (character-reference)
- 属性「autofocus」は禁止されています (invalid-attr)
- 属性「width」は正の整数である必要があります (invalid-attr)
- 属性「id」の値が重複しています (id-duplication)
- IDがありません
エラーの対応
ロール「generic」では、ARIAプロパティ「aria-label」は許可されていません (wai-aria)
generic ロールとは?
genericロールは名前を持たないコンテナ要素としての役割であり、ブラウザによって暗黙的に付与されるロールです。div
タグなどが暗黙的なロールとしてgenericロールが付与されます。
原因
generic ロールは名無しなので、aria-labelledby属性とaria-label属性は禁止されています。役割が一般的であるため、aria-roledescription及びaria-brailleroledescription属性(点字向けの属性)も禁止されている。
対応した内容
- 視覚的に見ても情報として重要でないのでaria-labelを削除した
属性「enable-background」は非推奨です (deprecated-attr)
enable-backgroundとは?
svg要素で背景の再描画領域を指定するために使われる属性。この属性は主にフィルタ効果を適用する際に重要となり、SVG 内のフィルタが適用されるエリアの外側の描画を参照する必要がある場合に使用される。
原因
enable-background はすでにWeb標準から削除されている過程で非推奨になっている
対応した内容
- 「enable-background」を削除
アクセシブルな名前が必要です (require-accessible-name)
原因
- 外部ライブラリSwiperのナビゲーションボタンに使われているsvgにアクセシブルな名前が指定されていなかった
対応内容
- button要素 + img要素で実装を修正
- Swiperのa11yオプションでボタンの
aria-label
の値が指定できるが、他の実装と相性が悪く挙動に問題が発生したので断念した
https://qiita.com/a_Iwahashi/items/d544ad077946073373a8
要素「yyy」には属性「xxx」が必要です (required-attr)
原因
- img要素にwidth,height属性が付与されていない
- img要素にdecoding属性が付与されていない
- iframe要素にtitle,loading属性が付与されていない
対応内容
- img要素にwidth,height属性を付与する
- decoding属性には基本的にasyncを設定する
- iframe要素にtitle,loading属性を付与する
不正な文字は文字参照でエスケープするべきです (character-reference)
原因
特殊な意味を持つ文字をエスケープしていない
このルールは文字を厳密に評価しません。文字が有効な場所にありエスケープする必要がない場合でも、変更を促されることに注意してください。
対応内容
- エスケープして文字を表示する
属性「autofocus」は禁止されています (invalid-attr)
原因
- Chakra UIのFocusLockコンポーネントのautoFocusプロパティがネイティブのautofocus属性と誤検知されていた
対応内容
- markuplintの設定ファイルでChakra UIのFocusLockコンポーネントでinvalid-attrのエラーを無効にする
nodeRules: [
{
selector: 'FocusLock',
rules: {
'invalid-attr': {
options: {
ignoreAttrNamePrefix: ['autofocus'], // FocusLockコンポーネントのpropsなのでチェックを無視する
},
},
},
},
]
属性「width」は正の整数である必要があります (invalid-attr)
原因
- img要素のwidth属性に"auto"が指定されていた
対応内容
- width属性に適切な値を記述する
属性「id」の値が重複しています (id-duplication)
原因
- id属性の値が重複していた
対応内容
- id属性が不要だったので重複した値を削除
IDがありません
原因
- label要素のfor属性に紐づくid属性を持つ要素が存在しない
対応内容
- id属性に適切な値を設定
さいごに
皆でワイワイ進めたことでチームでのHTMLのセマンティックな実装の意識の醸成などが出来てとても良かったです。導入後はCIにも組み込んで基本的にMarkuplintで検出されるエラーや警告はレビューなどでも指摘されなくなりました。
- 設定ファイルの書き方などMarkuplintに関しての知識をチーム内で共有できた
- HTMLの仕様について知らないことを多く知れた
- 自然とセマンティックやアクセシビリティに配慮したマークアップができるようになった
- 最初からセマンティックなコーディングを心がけるようになった
- 仕様を読みに行く習慣がより身についた
- Live Share を使ったモブプロがこなれてきた
さいごに
今回はF/Eチームでモブプロ体制でMarklintの導入を進めてみました。スキル向上や知識の共通化を目的をした場合にモブプロは非常に有効的だなと実感しました!
We are hiring
現在、株式会社ヤマップではアウトドア好きなエンジニアを絶賛募集中です。
Discussion