2019年4月16日火曜日
Vue.jsとScoped CSSとz-indexの話

こんにちは、シタテルの茨木です。
突然ですが、scoped cssいいですよね
scoped cssは、特にVue.jsにおいては、css設計のスタンダードと言っていいのではないかと思います。BEM等の学習コストの高い手法を覚える必要がなく、「コンポーネント内でのみcssクラス名の一意性を確保すればいい *1」という、シンプルで管理しやすい設計指針を打ち立てることができ、実に理にかなった手法ですね。
プロジェクト全体でのcss命名規約の統制問題は依然としてありますが、コンポーネントベースでの設計手法自体がコンポーネントを書き捨てる運用と親和性があるため、そこまで大きな問題にはならないのかなと思います。
依然として残る考慮点
一方、scoped cssだけで、コンポーネント内にcss的な関心事を完全に閉じ込められるかというとそうではなく、当然ながら例外もあります。最も代表的な例としては、cssの仕様上継承されてしまう属性ですね。
font-sizeなど、属性自体が子孫要素に継承されるものとして定義されていますので、セレクタレベルでscopedにしたところで、子孫要素への影響を避けることはできません。
まあこの辺は書いていても直感的に理解しやすいのでそこまで問題になりにくいのですが、個人的に危ないなと思うのは「z-index」「重ね合わせコンテキスト」です。
z-indexの管理
cssをざっくり理解したつもりになっているエンジニアが犯しがちな間違いの一つが、z-indexがグローバルだと思いこんでしまうことだと思います。そう考えているエンジニアは、Vueプロジェクト全体で単純にコンポーネントごとのz-indexを管理することをを思いつきます *2。例えば、コンテキストメニューのコンポーネントはz-index1000番台、モーダルダイアログのコンポーネントはz-index500番台といった管理です。(モーダル上でコンテキストメニューを開くかもしれない。その場合はコンテキストメニューがモーダルの下に回り込んでほしくない、なんてことを考えているわけですね)
この方式は重ね合わせコンテキストがページ内で1つであるうちは上手く機能しますし、ルール自体はおそらく間違いでもないです。
ただ、重ね合わせコンテキストに関する考慮を漏らしていると、「z-indexで勝っているはずなのに、なぜか後ろに回り込んでしまう要素」が出てくる可能性があり、「なぜか動かない」という状況に見舞われます。実際には仕様理解が足りていないだけなのですが。
理解すべき仕様「重ね合わせコンテキスト」の詳細についてはMDNを読んでください。
https://developer.mozilla.org/ja/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context
ざっくり言えば、「z-indexは同じ重ね合わせコンテキストの中での比較にしか使われない」「重なる系の属性(potision: absoluteなど)が指定された要素は自身が重ね合わせコンテキストを形成する」ということです。
これもfont-sizeなどと同じで、親要素で指定された属性が(たとえscopedであろうとも)、子孫要素に影響を与えうる、ということですね。
デザインは文脈依存?
scoped cssとコンポーネントベースでの部品化は、確かに今までのcssの不便さや複雑さの大部分を解決しているように見えますが、z-indexの件を一つの例として考えると、「デザイン・見た目・UIは、どこまで部品化しても文脈依存から逃れられない」ということを示している気がします。まさに、重ね合わせ「コンテキスト」ですしね。z-indexをpropsで渡せば…みたいな発想はもちろんあるのですが、結局その先にあるのはinput要素の再発明だったりするわけです。input要素をwrapしてたはずがinput要素を作っていた…みたいな。
どんなコンテキストでもデザイン破綻せず使うことのできるUI部品の実装は、相当な労力を要します。(まあ、実際にUI部品系のnpmパッケージの中を覗いてみると、普通にz-indexがハードコードされていて変更できなかったりすることが多く、みんなほどほどに手を抜いているんだと思いますが)
プロジェクト内でのデザイン統一・再利用を想定してコンポーネントを分割設計する際に、デザイン的な汎用性を求めるのはほどほどにしておくべきなのかな、と思った次第でした。
他コンポと疎結合に作るとか、ステートレスに作るとか、そちらに労力を割いたほうが実りが大きいんじゃないかな。UIの寿命は短いので、捨てやすいように疎結合に書くのが一番大事かな、と個人的には思います。
*1: slot内のスコープが親子共通だったり、コンポーネントroot要素に親からclassが注入できるといった例外はありますが
*2: 私です
2019年1月28日月曜日
WEBエンジニアが知っていてもいいかもしれない出版やデザインの話
私は出版・DTPをかじったことが少しだけあるのですが、デザインや文章校正の基礎知識はエンジニアの仕事でも活用できる機会が時折あったりします。
基本的なキーワードだけ簡単にご紹介します。
興味がでたらぜひ本格的なデザインや文章校正の本などで調べてみてください。
少し気にするだけでも、画面が結構「それっぽく」なりますので、コスパの良い知識だと思います。
ジャンプ率
1画面(1紙面)でのフォントサイズの変化率を指す言葉です。一般に、落ち着いた雰囲気にしたい場合はジャンプ率を小さく、派手な印象を与えたい場合はジャンプ率を高くすべきと言われています。
色の指定方法
RGB
WEBエンジニアがまず思いつくのはこれかと思います。光の三原色ですね。HSB
色相(Hue)、彩度(Saturation)、明度(Brightness)の3要素で色を指定する方法があります。色相は赤系・青系などの色味、彩度は鮮やかさ(小さいほどグレーに近くなる)、明度は明るさ(小さいほど黒に近くなる)を表します。
SBを固定し、Hのみを変動させることで、比較的まとまりのある色のバリエーションが作りやすいです。
例えば、画面上でステータスAとステータスBの表示色を変えて視認性を上げたい、といった場合には、色相のみ違う2色を用いると、比較的おさまりが良かったりします。
CMYK
インクの4色です。基本的に印刷物の色味はCMYKで表現されます。WEBだと気にする機会はあまりないですが、RGBやHSBで表現できる色は、必ずしも同じ見え方のCMYKに変換できない、という点は知っておいてもいいかもしれません。
人物写真の「首切り」
インタビューに添付される人物写真において、人物の顔部分に背景の直線(窓枠等)が被る構図はNGとされています。必ずしも合理的な理由はない(私が知る限りでは)ですが、確かにちゃんとしたサイトや紙面の写真では見ない構図ですから、気にしておくといいかと思います。
文章の書き方
表現したい内容によって正しい日本語の書き方というのは当然変わりますが、かっちりした文章を書く場合には新聞ルールを参考にすると、素人感が出なくていいです。- 「出来る」と「できる」はどちら?
- 「行なう」と「行う」はどちら?
- 「〜です(〜)。」「〜です。(〜)」はどちら?
たとえばこういう疑問に対して、どっちがプロっぽいか、という回答を与えてくれます。
文献としては共同通信社の記者ハンドブックなどがメジャーですが、買うと高いので、新聞社サイトの文章を参考にするなどでもいいかもしれません。
以上です。散文になってしまいましたが、ご参考になれば幸いです。
2018年11月19日月曜日
スネーク?キャメル?ケバブ?命名規則のカオスが発生
こんにちは!
SCSチームのいしづかです。
シタテルでは主にRails + Vue.jsにてシステムを開発しています。
生産管理を行うシタテルコントロールシステム(SCS)もRailsで書かれており、Viewは基本的にhaml + scssです。
SCS全体のAPI + SPA化によるマイクロサービス化計画も進んでいる中、ここ最近作られている画面はhamlの中にVue.jsを埋め込むという方法が取られています。
その埋め込み方法は別の機会に書くとして、そこで出てきた 命名規則のアレコレ についてレポートしたいと思います。
Railsはパスカル + スネーク、Javascriptはキャメル、htmlはケバブ・・・
表題の通り、いろいろ混ざりました。
Railsでは、ネームスペースやクラス名はパスカルケース(ClassName)、それ以外のメソッド名などはスネークケース(method_name)で書きます。
定数などはアッパーケース(CONST_VALUE)で書きますね。いつの間にか3種類使い分けていました。
私自身、前職ではC#.NETでWindowsアプリケーションを作っていたのでパスカルケースを見ると安心します(笑)
Vueを使いだしてから、メソッド名はキャメルケース(methodName)、htmlやcssのidやクラスなどはケバブケース(class-name)が登場してきました。
・・・ついに1つのRailsプロジェクトに、ほぼすべての命名規則が揃ってしまったのです。
RailsとVueで分かれていればまだよかったかもしれませんが、Railsで書いたAPIのjsonがスネークケースで出力されてしまうため、Vue側にもスネークケースが進出してしまいました。
そこで、さすがにルールを設けようということになったのです。
統一ルール発令
Railsで使っているパスカルケース・スネークケースは崩すことができません。これはこのまま。
Vue側は データに関わるもの(data・computed)はスネークケース、処理に関わるもの(methods)はキャメルケース、html・css周りはケバブケース というルールに統一しました。
なんとなく複雑っぽいですが、メソッドとhtml周りはそのままで、データに関わるところだけちょっとRailsに寄せたという形です。
これでRails側はこれまでのソースを流用できますし、Vue側ではJsonをパースしてバインドする際、スネークケースが出てきてもOKです。
Vueが入ってきて発生した命名規則の混乱は、この統一ルール発令によってひとまずしばらくは沈静化するでしょう。。。
API + SPA化計画では、フロントはキャメル統一の予定
とはいえ!Javascriptは基本的にキャメルケース。
現在実装中のSCS APIでは、RailsからJsonを出力する際にキャメルケースに変換するように実装しています。
これでSPA側でデータを受け取る時だけスネークケースにしなくても済みそうです。
まとめ
これまでとは異なる言語やプラットフォームを使う時、既存のものとの整合性が取れなくなるときがありますね。
今回、私たちは「命名規則がカオスになる」という形でそれが表れました。
シタテルではそんなカオスとも仲良くしながら(闘いながら?)、日々新しいものにも取り組みつつシステムを構築しています。