CSSフレームワークからみる、フォーカス・インジケータの違いを考察
フォーカスってなに?
「フォーカス」とは、パソコン画面上でウインドウや入力ボックス、アイコンやボタン、画像といった対象物が「次の操作」を受けられる(アクティブな、選択された)状態のことです。
引用:weblio辞書「フォーカス」(別窓でリンク)
上記の動作サンプルを例にすると、テキストフォーム、セレクトフォーム、ラジオボタン、チェックボックス、送信ボタンなど、選択時に色付きの枠(※Google Chrome上での場合)など、「選択中」ということが可視化できるよう装飾されます。
この装飾を「フォーカス・インジケータ」といいます。
フォーカスの可視化について
ユーザーの中には、運動障害のある人、盲目の人、手を持たない人、何らかの理由でマウスやトラックパッドを使用できない人もいます。
このようなユーザーは、キーボードのTabキーや、操作補助ツールなどでフォーカス・インジケータを頼りにWebサイトを閲覧、操作することがあります。
WCAG2.1では、Webサイトをキーボードで操作できるようにすること、キーボード フォーカスを持っている要素をユーザーが認識しやすくすること、などの達成基準の項目が存在します。
フォーカス・インジケータについては、[達成基準 2.4.7 フォーカスの可視化] で上げられています。
キーボード操作が可能なあらゆるユーザインタフェースには、フォーカスインジケータが見える操作モードがある。
(レベル AA)
引用: Web Content Accessibility Guidelines (WCAG) 2.1の達成基準 2.4.7 フォーカスの可視化(別窓でリンク)
フォーカスのスタイル
ここで問題なのは、ブラウザごとにフォーカス・インジケータのスタイルが異なることです。
この場合、ブラウザ間の差異を無くすために、CSSの:focus
の擬似クラスでスタイルを変更することが可能です。
よく上げられる問題として、このフォーカス・インジケータがWebサイトのトンマナに合わない、視覚的に美しくない、などの理由で消されてしまうケースです。
:focus { outline: none; // DON’T DO IT! }
この指定をしてしまうと、キーボードユーザーが要素にアクセスできなくなるために、絶対にやめましょう。
CSSフレームワークはどのような対応をしているのか?
業務でBULMAや、Bootstrapを使用することがあり、フォーカス・インジケータのスタイルが細かく設定されていてとても助かったことがあります。
フォーカススタイルをどう当てているのか気になったので、以下5つのフレームワークを比較してみたいと思います。
※各フレームワークの特徴はここでは省きます。
※formで使われる代表的な要素(input
や button
など)で比較します。
BULMA
BULMAの例をCode Penのレイアウトビューで見る(別窓でリンク)
特徴
// 一部抜粋 .input:focus { border-color: #3273dc; box-shadow: 0 0 0 0.125em rgba(50,115,220,.25); outline: none; }
input[type="text"]
,selectbox
,button
の:focus
のスタイルはoutline: none;
をしてbox-shadow
プロパティで別でスタイル付与。- フォーカスリングは色がやや薄め。
input[type=checkbox]
,input[type=radio]
は、ブラウザデフォルトのスタイル。
Bootstrap
Bootstrapの例をCode Penのレイアウトビューで見る(別窓でリンク)
特徴
// 一部抜粋 .form-control:focus { color: #495057; background-color: #fff; border-color: #80bdff; outline: 0; box-shadow: 0 0 0 0.2rem rgba(0,123,255,.25); }
input[type="text"]
,selectbox
,button
,input[type=checkbox]
,input[type=radio]
の:focus
のスタイルはoutline: none;
をしてbox-shadow
とborder-color
プロパティで別でスタイル付与。- 上記の要素はフォーカス・インジケータを全て独自スタイルで担保している。
- フォーカスリングはやや太め。
Materialize
Materializeの例をCode Penのレイアウトビューで見る(別窓でリンク)
特徴
// 一部抜粋 input:not([type]) { outline: none; } input[type=タイプ別の記述]:not(.browser-default):focus:not([readonly]){ border-bottom: 1px solid #26a69a; -webkit-box-shadow: 0 1px 0 0 #26a69a; box-shadow: 0 1px 0 0 #26a69a; }
select:focus { outline: 1px solid #c9f3ef; }
input[type="text"]
, は独自スタイルでborder-bottom
が変わるのみ。selectbox
は独自スタイルでborder-bottomの色が変わるパターン(JavaScriptが使われている)と、ブラウザデフォルトスタイルでoutline
で色が変わる2パターン用意されている。button
類のスタイルは全てbackground-color
が変わるのみ。outline: 0;
されている。input[type=checkbox]
,input[type=radio]
は独自スタイルで、:checked
の擬似クラスでフォーカス・インジケータが担保されている。
Pure.css
Pure.cssの例をCode Penのレイアウトビューで見る(別窓でリンク)
特徴
// 一部抜粋 .pure-form input[type=タイプ別の記述]:focus { outline: 0; border-color: #129fea; } .pure-form input:focus:invalid { color: #b94a48; border-color: #e9322d; }
input[type="text"]
,selectbox
の:focus
のスタイルはoutline: none;
をしてborder-color
プロパティを別でスタイル付与。required
属性がある時は強制的に赤色。button
類のスタイルは全てbackground-color
が変わるだけ。outline: 0;
されている。input[type=checkbox]
,input[type=radio]
はoutline
プロパティで独自の色を指定している。
skeleton
Skeletonの例をCode Penのレイアウトビューで見る(別窓でリンク)
特徴
// 一部抜粋 input[type=タイプ別の記述]:focus { border: 1px solid #33C3F0; outline: 0; } .button:focus { background-color: #1EAEDB; border-color: #1EAEDB; outline: 0; }
input[type="text"]
,selectbox
の:focus
のスタイルはoutline: none;
をしてborder-color
プロパティで別でスタイルを付与。button
類のスタイルは全てbackground-color
とborder-color
が変わるだけ。outline: 0;
されている。input[type=checkbox]
,input[type=radio]
はブラウザデフォルトのスタイル。
CSSフレームワークの総評
検証の結果、WCAG2.1 [達成基準 2.4.7 フォーカスの可視化] の配慮ができているであろうフレームワークの順位は以下のようになりました。
※あくまで個人の主観のもと、順位づけさせていただきました。
- Bootstrap
- BULMA
- Pure.css
- Skeleton
- Materialize
1. Bootstrap
フォーカス・インジケーターがつく要素はほぼ独自スタイルで賄えており、且つ太めで見やすい。
ブラウザデフォルトの青枠に寄せているので、ユーザーも困惑しにくいと思われる。
2. BULMA
フォーカス・インジケーターのスタイルは控えめだが、視覚的な美しさは担保できている。
フォーカスリングの付け方はBootstrapと大差ないが、独自スタイルとブラウザデフォルトの混在が気になる。
3. Pure.css
button
のフォーカスリングを消してしまっているのが残念。
input
のrequired
属性がある時に勝手に赤色にしてしまうのは、ちょっとお節介かも?色だけで判断させるのは良くないので、補足のラベルを付ければベストかもしれない。
4. Skeleton
最低限のスタイル付与と軽さが売りのフレームワークなので、:focus
スタイルも最低限。
Pure.css同様button
のフォーカスリングを消してしまっているのが残念。
5. Materialize
独自スタイルが多く、UX重視な印象。
フォーカス・インジケータのスタイルに統一感がないのと、目立ちにくいため、認識のしやすさに欠ける。
Pure.css同様button
のフォーカスリングを消してしまっているのが残念。
まとめ
Bootstrapはコンポーネントごとに細かい配慮が施されており、至れり尽くせりな感じでした。
スクラッチで書く場合は、:focus
スタイルはbox-shadow
プロパティでスタイル付与するのが良さそうです。
色はブラウザデフォルトの色に合わせるのがUX的にも無難ですが、Webサイトやサービス全体のトンマナに合わせるのでも良さそう。
フォーカスがどこにあるのかを見つけることができるようになることが目的なのでスタイルは付与は自由だけれども、塩梅は大事にしたいと思います。
Webアクセシビリティの中でも、フォーカスの可視化を100%担保することは難しく実装ではよく苦戦するため、今回のテーマを取り上げてみました。 是非、皆さんが日頃フォーカスのために行なっていること教えていただけると嬉しいです!
(Pug)繰り返すのはイヤだ!!! listで使えるmixinコード
Pugを使いこなしたい!
「もっとPugを使いこなしたい!」
と思っている方いませんか??
私は業務ではPugを使ってマークアップをしています。
最初のうちは変数を使ったりするだけで、ほとんどPugを使いこなせていませんでした。
そんな私でも導入できたmixinのコードを紹介します。
内容
リスト形式のニュース一覧を例に、
<ul>
や<ol>
のリストで役に立ちそうな書き方をmixinを使って実装してみます。
記述例(Pug)
ul.news__list mixin news-list(...newsLists) each news, index in newsLists li.news__item a.news__link-post(href=news.linkHref,target=news.linkTarget,rel=news.linkTarget === '_blank' ? 'noopener noreferrer' : '') .news__number #{index + 1} .news__category= news.category .news__date= news.date .news__title= news.title if news.iconNew == true span.icon--new NEW +news-list( { linkHref: '/news-20190521/', linkTarget: '_blank', category: 'カテゴリー名', date: '2019.05.21', title: 'タイトル2', iconNew: true, }, { linkHref: '/news-20190520/', category: 'カテゴリー名', date: '2019.05.20', title: 'タイトル1', iconNew: false, } )
コンパイル後(html)
<ul class="news__list"> <li class="news__item"> <a class="news__link-post" href="/news-20190521/" target="_blank" rel="noopener noreferrer"> <div class="news__number">1</div> <div class="news__category">カテゴリー名</div> <div class="news__date">2019.05.21</div> <div class="news__title">タイトル2<span class="icon--new">NEW</span></div> </a> </li> <li class="news__item"> <a class="news__link-post" href="/news-20190520/" rel=""> <div class="news__number">2</div> <div class="news__category">カテゴリー名</div> <div class="news__date">2019.05.20</div> <div class="news__title">タイトル1</div> </a> </li> </ul>
パーツごとに解説
1. 定義
mixin news-list(...newsLists)
まずnews-list
という名前で、mixinを定義します。(この例ではli
全体を対象としています)
Rest引数を利用し、...
でnewsLists
の配列全てを受け取ります。
参考: 分割代入や引数の「残り全部」を持ってくるやつ……。(現代的JavaScriptおれおれアドベントカレンダー2017 – 17日目) | Ginpen.com
2. 繰り返しの指定
each news, index in newsLists
each in文を使います。
news
はnewsLists
の値を、
index
はnewsLists
のインデックス番号が格納されています。
3. 要素の中に引数を指定
li.news__item a.news__link-post(href=news.linkHref,target=news.linkTarget,rel=news.linkTarget === '_blank' ? 'noopener noreferrer' : '') .news__number #{index + 1} .news__category= news.category .news__date= news.date .news__title= news.title if news.iconNew == true span.icon--new NEW
この例では、引数のnewsLists
をオブジェクトで返すため、変数名.プロパティ名
でそれぞれ記述していきます。
以下の通りです。
- news.linkHref
- news.linkTarget
- news.category
- news.date
- news.title
※オブジェクトの内容は追って説明します。
a.news__link-post(href=news.linkHref,target=news.linkTarget,rel=news.linkTarget === '_blank' ? 'noopener noreferrer' : '')
rel
属性の値を、三項演算子で出し分けしています。
traget
属性に_blank
(別窓ウィンドウでリンクを開く)の値が入っているときは、rel
属性にnoopener noreferrer
を代入します。
rel="noopener noreferrer"
については、以下を参考にして下さい。ここでは省略します。
.news__number #{index + 1}
#{index + 1}
で配列のインデックス番号を取得していますが、プログラミング言語のインデックス番号は0から始まるため、+1
をして強制的に1から始まるようにしました。
ここで悩ましいのは#{index++}
とインクリメント演算子で記述すればよくない?
と思いましたが、、結果、どうやらできないらしい・・・!!
あくまで配列のインデックス番号を取得するのみということなのか・・・。
うまく説明できないので、お分かりの方お力添えをお願いします!
.news__title= news.title if news.iconNew == true span.icon--new NEW
if
文を使って、NEWの表示を出すか出さないかの判定をしています。
true
であればspan.icon--new NEW
が出力されます。
※ここではtrue
以外の値を指定すれば出力されませんが、有無がわかるようにtrue
かfalse
のどちらかを指定します。
4. 出力結果の指定
+news-list( { linkHref: '/news-20190521/', linkTarget: '_blank', category: 'カテゴリー名', date: '2019.05.21', title: 'タイトル2', iconNew: true, }, { ~~ 省略 ~~ }, )
mixinで定義したnews-list
を呼び出します。
呼び出し方法は、+
とmixin名を指定します。
オブジェクトのプロパティ名と内容は、以下の通りです。
プロパティ名 | 内容 |
---|---|
linkHref | リンクパスの記述 |
linkTarget | 別窓リンクの場合_blank を記述 |
category | カテゴリー名の記述 |
date | 日付の記述 |
title | タイトルの記述 |
iconNew | NEWの表記が必要な場合true を、不必要であればfalse を記述 |
補足
この例では、mixinの定義と呼び出しを1ファイル内で行いましたが、mixinの要素だけ別ファイル化し、include
して使うことも可能です。
まとめ
同じ記述を何度も繰り返すのイヤですよね??
それに、同じ記述を手作業で増やすことで、思わぬミスが発生することもあります。
変更箇所を必要最低限に抑えることで、作業の手間とミスを減らすことが可能です!
なんてHAPPYなんだ〜!
今回紹介した記述例の中には、mixin以外にもPugのちょっとした小技を盛り込んだので是非他のところでも応用してみて下さい。
Pug公式ドキュメント
- Mixins – Pug
- Mixins | Pug - にほんご。
↑Pugのドキュメントを日本語に翻訳している素晴らしいサイトです!
デザイナー経験の価値について思ったこと
初LT登壇!
先日参加したイベントで、初LTで発表させてもらいました。
【Hedge #2】「デザイナー × エンジニア = ∞」を実現するために僕らがやれること - connpass
私はデザイナーからマークアップエンジニアになったのですが、そんな立場の人間から何か伝えられたらなと前々から思っていたので、エイヤー!といつの間にかLT枠で申し込んでいました。
以下がLT発表時のスライドです
スライドの一部内容は当日公開したものから変更しています。
1. デザインから実装までノンストップ
優先度を意識して伝えるべきことを形にするためにデザインし、文書構造を意識してマークアップをする。
両者の共通点は情報設計で、根本でやっていることは同じだと思っています。
だとすれば、デザイン時にはすでに頭の中でアウトライン化が始まっていて、脳内マークアップが同時並行で開催中ということになります。
デザインと実装どちらも担当した時は、私はそんな感じでした。
その代わり、型破りで革新的なデザインは意識しないと生まれなくなってしまうんです。なぜならマークアップは型通りにしないといけないですからね…。
時には型から外れないといけない時もある!
2. デザイナーと意見しあえる
以前エンジニアさんと話をしていて、「デザインは全くわからないから。。」「デザイナー怖いじゃん。。」という発言を耳にして、驚いた経験があります。
お陰様で私はそんな風に思ったことがないし、むしろ上がってきたデザインについて、あーだこーだ聞きまくる・確認しまくる・時に意見しちゃうタイプです。
特に分業だとここはすごい大事なポイントのはずです。
デザイナーとエンジニアのコミュニケーション不足のために後々あれが違う、この場合はどうなる、なんて揉めること皆さん日常茶飯事でしょう?(そんな記事を見た覚えがある)
私はそういう厄介ものは真っ先に潰しにいきます!
その点ではデザインの知見があるからこそできるコミュニケーションもあるんですよね。
経験がこういうところで役に立つものなんですね。
3. デザイナーめっちゃ尊い!
デザインって正解がないじゃないですか?
特に受託で制作をやっていると、求められるデザインって案件によって全く違うし、その数こなすのって本当に大変なんですよ。
0から1をひたすら生み続ける素晴らしさ、尊敬しかないです!
あと、私たちエンジニアはその見た目をコンピューターに伝えるためにコード化したり、パフォーマンスを良くしたりしていますが、極論それって裏方…。
ユーザーにダイレクトに何か物事を伝えられる役目はデザイナーだと思っています。
今日は見た目が9割的なことを言ってしまったけど、そもそもWebサイトを見てない(見れない)方もいます。視覚だけで解決はできない面を技術で補うお仕事を私はしています。情報伝達の方法は様々です。
— りーりー (@saimari02) 2019年3月20日
「見た目が9割」と、スライドの内容で誤解を生みそうなことを書いてしまったので、Twitterで補足しました。
もちろんエンジニアだって技術で救えることがあるってこと、忘れちゃないですよ!
LTまとめ
LTで話した3つのことについて書いてきました。
デザイナーもエンジニアもお互いが少しでも知ろうとすることで、円滑に物事が進んだり、結果的に出来上がるもののクオリティーがぐっと上がると思っています。
皆さん、お互いの壁をぶち壊す勢いで仲良くやっていきましょう!
あと、何事も無駄な経験はないよねってことが大まかな感想です。
デザイナー経験の価値って?
ここからはLTの発表とは話が逸れるのですが、私が現在転職活動中でしてその中のお話です。
エンジニアとして応募をして話を聞きに行ったりすると、ありがたいことにどこの企業もデザイナーの経験について食いついてくれます。
「なんでデザイナーからエンジニアになったの??」
「デザインの経験は十分にあるから、その経験も是非活かして欲しい」
私はむしろ、デザインナーとしてもエンジニアとしても、経歴が中途半端なんじゃないか、とネガティブに捉えていました。
もちろんそう感じられた企業もあるかと思いますし、それが要因で選考落ちた経験もしました。
それよりも、エンジニアにもデザイン力を必要とするケースが増えている(企業による)、という事実を知ったのは大きな収穫です。
デザイナーが経営に関わるべきだ、と言われている昨今、デザイナーの需要が高まっているのは確かなのかもしれませんね。
デザイナー経験の価値はこれから上がってくると思っています。
迷っていたけど腑に落ちたこと
私は欲張り者です。
3年前エンジニアに転身しようと思った時、デザイナーの経験を捨てられずに、まぁどっちもやっていけばいっか!てへぺろ。ぐらいな生半可な気持ちでいました。
3年間そのつもりでやってみてわかったことは、どちらも名乗るには相当な努力が必要だということです。
- どちらかに集中しすぎて、片方の手を少しでも止めたらその分どちらかの手が鈍る
- 求められることの領域がフロントエンド全般で、ひ、広すぎ...(泣
- からの〜フロントエンド界隈の知識の幅広さについていくのが大変...(泣
デザイナーとしても、エンジニアとしても完璧にやっていこうとすると、睡眠時間0になりそうな勢いでした。
それは無理だなと気づき、それでもどちらか一方を捨てることができない私はやっぱり欲張り者です。(2回目)
仕方ないので、どちらもゆっくりやっていけば良いかと。
1年で100はできないけど、1年で10やって10年後に100になればいいかなと思うようになりました。
続けていれば、そのうちできていることもあるんです!ははは(そんな甘くないというご意見もびしばしどうぞ)
胸を張って「デザイナーもエンジニアもやっています」と言えるように、これからもエンジニアの傍で細々とデザインは続けていくつもりです。