この記事は Vue.js #3 Advent Calendar 2018 の 3 日目の記事です。
はじめに
無事にフロントエンド研修が終わって、各プロジェクトで働いている1年目の皆様。お元気ですか?
そろそろ、先輩のチェックなしで、一人でお仕事ができるようになってきた頃でしょうか。
実は皆さんに、お伝えしなければならないことがあります。
それは、研修生時代にやらなかった、とある学習内容があります。
この学習内容は、技術研修の内容を、厳選に厳選を重ねた結果、「優先順位の関係」で省かれたものです。
今後、様々なお仕事を経験することで、ある程度は獲得できる知識ではあります。
しかし、どんなプロジェクトにアサインされるのかは、会社の都合によるところが大きく、
この学習内容について、簡潔にまとまったサイトや書籍が見つけられませんでした。。。
そこで今回、この場を借りて出題させていただきますね~
ルール
まずは、CodePenに書かれた「HTML」「CSS」「JS」の内容を見てください。
以下の3点について、いろいろ設定を変えています。
・文字の色
・文字の背景色
・文字の内容
See the Pen VueSample by satoshi hayashi (@satoshi_hayashi) on CodePen.
内容を見たら、自分の頭の中で「出力結果」を想像してみてください。
想像できたら「Result」を押して、「自分が想像した結果」と「出力結果」が一致しているか確認してください。
最後に、必ず「問題の解説」が書かれています。
なぜ、その出力結果になるのか?しっかり解説を読んでから、次の問題にお進みください。
フロントエンドQuiz 全12問 の はじまりはじまり~
See the Pen Vue1 by satoshi hayashi (@satoshi_hayashi) on CodePen. もしかして、初めて見る人もいるかもしれません。 きちんと開発体制が整った現場ですと、まず見ないパターンです。 私の感覚で大変恐縮ですが、実際には「bgcolor」属性よりも「width」属性の方がよく見る気がします。 なぜ、そのような古いコードが現在でも見られるのか? ・システム開発会社などでは、フロントエンド専門のエンジニアがいないことがある ということで、現在でも「古い書き方」が混じったコードを見ることがあります。 もし今のプロジェクトで、GitHubのプルリクエストに、厳しいフィードバック受けている方は、大変ありがたいシチュエーションですので、しっかり学んでくださいませ~第1問
第1問-解説
「bgcolor」によって、背景色が「red」になっています。
もしあっても、コードレビューで指摘されて修正されます。
それには、以下のような「深い理由」があります。
・システム開発会社などでは、バックエンドのエンジニアが作った「汚いフロントエンドの実装」を、納期を優先するために許してしまう(中小企業のお客様は、システムの中身がどう作られているか、よくわからない)
・エンジニアが1つのプロジェクトに長期で所属し、新しい技術を使えないシチュエーションが長く続いたため、勉強意欲がなくなった
・エンジニアの業務歴が長くなってきて、だんだんと指摘してくれる先輩エンジニアがいなくなり、昔のやり方のままコードを書いている
See the Pen Vue2 by satoshi hayashi (@satoshi_hayashi) on CodePen. 第1問で「bgcolor」は「非推奨の属性」ということを書きました。 「非推奨の属性」<「スタイルシート」 というのが今回の答えです。第2問
第2問-解説
しかし、スタイルシート「background-color」によって「blue」に上書きされています。
普段は使用される機会は少ないですが、もし「非推奨属性とスタイルシート」がバッティングした場合、いったいどちらが勝つのか?実際やってみたのがこの問題です。
See the Pen Vue3 by satoshi hayashi (@satoshi_hayashi) on CodePen. ここらへんのスタイルの優先順位について、研修中は 「要素」<「クラス」<「ID」 を覚えて、なぜかスタイルが当たらない場合は「style属性」で直接書いたり「!important」を付けよう これは「簡略化したルール」で、初心者用の書籍やWebスクールでも、このように教えています。 そのため、たまに、なぜかスタイルが適用されないから、「style属性」で直接書いたり「!important」を付けているコードがあります。 業務歴1年目は、それでもかまわないのですが、2年目以降は「詳細なルール」を勉強して、汚いスタイルの上書き合戦を避けなければなりません。 詳細なルールで解説しますと 「0.1.0.0.0」>「0.0.0.0.1」 その結果、詳細度が大きい「background-color: red」が勝ちます。第3問
第3問-解説
しかし、スタイルシート「background-color」によって「blue」を指定しています。
と習ってきたかもしれません。
実は、このルールでも8割くらいは大丈夫なのですが、残りの2割を切り捨てています。
「background-color: red」は「スタイル属性」ですので、詳細度は「0.1.0.0.0」。
「background-color: blue」は「要素セレクタ」ですので、詳細度は「0.0.0.0.1」。
See the Pen Vue4 by satoshi hayashi (@satoshi_hayashi) on CodePen. それでは、詳細度のチェックをしてみましょう。 「0.1.0.0.0」<「1.0.0.0.1」 その結果、詳細度が大きい「background-color: blue」が勝ちます。 このように「!important」は最強の詳細度「1.0.0.0.0」をプラスします。 裏を返せば、安易に「!important」を付けると、その後の改修では常に「!important」を付けて上書きする必要が出てきて、ソースがどんどん汚くなってきます。 「!important」は、最終兵器であり、安易に使用すべきではありません。第4問
第4問-解説
今回は「!important」を付けることによって、「style属性」に勝とうとしています。
「background-color: red」は「スタイル属性」ですので、詳細度は「0.1.0.0.0」。
「background-color: blue」は「要素セレクタ + !important」ですので、詳細度は「1.0.0.0.1」。
そして、ほとんどの場合にスタイルが適用されることになります。
もし「!important」を使用して良いシチュエーションをあえて挙げるとすれば、
自分でソースを変更できない「外部の広告タグ」のスタイルによって、サイト本体のスタイルが崩れた場合に、他に方法がなくて、仕方なく「!important」を使用します。
See the Pen Vue5 by satoshi hayashi (@satoshi_hayashi) on CodePen. それでは、詳細度のチェックをしてみましょう。 「1.1.0.0.0」>「1.0.0.0.1」 その結果、詳細度が大きい「background-color: red」が勝ちます。 このコードは末期状態です。第5問
第5問-解説
今回は「style属性」の方でも「!important」を付けることによって「CSS」側に勝とうとしています。
「background-color: red」は「スタイル属性 + !important」ですので、詳細度は「1.1.0.0.0」。
「background-color: blue」は「要素セレクタ + !important」ですので、詳細度は「1.0.0.0.1」。
もし現場のコードがこんな状態になったら、担当のエンジニアは、改修作業にストレスを感じると思われます。
(ブラウザゲームの現場では、実際にあるのですが。。。)
See the Pen Vue6 by satoshi hayashi (@satoshi_hayashi) on CodePen. CSS側は「!important」は作れても、「style属性」が作れないため、詳細度「1.1.0.0.0」を超えることができません。 万事休すか? 背景色が「red」のまま、何もできないのかというと、実はそうではありません。 そうです、どうしても「red」が勝つなら、勝たせてやればよい。 ※ご参考 「色相」はWebデザイナーの方にとっては「色の基礎知識」として、学生時代に勉強した内容かもしれません。第6問
第6問-解説
今回は、CSS側が反撃した結果になります。
本来「style属性」+「!important」の組み合わせは、詳細度「1.1.0.0.0」と最強に近く、「style属性」+「!important」でないと勝てません。
工夫次第で、CSS側から「blue」にすることができます。
その「red」を生かしつつ、「色相」をずらして「blue」にしてしまえば良いのです。
右側に書いてある「色相スケール」や「色相環」で見ると分かりやすいです。
色相 - Wikipedia
「red」から色相を240度ずらすと「blue」になります。
See the Pen Vue7 by satoshi hayashi (@satoshi_hayashi) on CodePen. ということで、結果は「background-image」が優先されるようです。 本来「background-image」のサンプルを作るなら、赤色の画像を使用するところです。しかし、画像を準備する手間があったため、横着をしてグラテーションで背景を作りました。第7問
第7問-解説
今回は、詳細度の大きさは関係ありません。CSSの仕様としてどちらが優先されるかです。
See the Pen Vue8 by satoshi hayashi (@satoshi_hayashi) on CodePen. ということなので、もしJavaScriptで小数の計算をする場合は、一度「10」や「100」を掛けて整数にしてから、最後に「10」や「100」で割り戻すと、きちんとした計算が出ます。第8問
第8問-解説
一見すると「0.3」で「blue」になりそうですが、実は「0.30000000000000004」が合計となり「red」になります。
また、「BigNumber.js」という便利なライブラリもありますので、こちらを利用することも検討してみてくださいませ。
See the Pen Vue9 by satoshi hayashi (@satoshi_hayashi) on CodePen. もし9行目の内容を、「''」と「""」を入れ替えて書けば、正しいJSONとなります。第9問
第9問-解説
実はJSONは、HTMLみたいに「''」と「""」を両方使用できません。「""」のみ使用できます。
See the Pen Vue10 by satoshi hayashi (@satoshi_hayashi) on CodePen. しかし「getFullYear()」や「getDate()」は「-1」されないため、なぜ「getMonth()」だけそのような動きをするのか、まったく不思議です。第10問
第10問-解説
今回も一見すると、正しいように見えますが、「result_date」の中身は「1999/9/11 12:13:14」となります。
原因は「getMonth()」が「0~11」の値を返すからです。
See the Pen Vue11 by satoshi hayashi (@satoshi_hayashi) on CodePen.第11問
第11問-解説
「age」は単なる数字で、プリミティブ型と呼ばれます。
プリミティブ型は、文字やtrueなどがあり、関数の引数に設定すると、コピーが使用されます。
→「birthday」の内部では「ageのコピー」が使用される。
「boy」は連想配列で、オブジェクト型と呼ばれます。
オブジェクト型は、配列や日付などがあり、関数の引数に設定すると、それ自身が使用されます。
→「birthday」の内部では「boyそのもの」が使用される。
つまり「ageのコピー」に対して「+1」しても「ageそのもの」には影響しません。
その結果「age」が「10」、「boy.age」が「11」となって、背景色は「red」になります。
See the Pen Vue12 by satoshi hayashi (@satoshi_hayashi) on CodePen.第12問
第12問-解説
実は、「setTimeout」で関数を実行すると、関数内で例外が発生しても、catchでは捕らえられなくなります。
これがもし、「setTimeout(this.work, 0);」ではなく「this.work();」という普通の実行だったら、catchが実行されて「red」になります。
最後に
全12問、大変お疲れ様でございました。
「フロントエンドQuiz」の全12問は、
前半は「CSS」寄りの内容、後半は「JS」寄りの内容になっておりました。
これは、私の周りだけかもしれませんが、男子は「JS」が得意で「CSS」が苦手、女子は「CSS」が得意で「JS」が苦手という傾向が見られます。
フロントエンドにおいて「CSS」と「JS」は車の両輪です。
もし今回のQuizを通して、何かしら得るものがありましたら、Quizの作者として大変うれしく思っております。