20200212のCSSに関する記事は10件です。

Webフロントエンドエンジニアにやさしいデザインファイルの作り方

sketch.png

Sketch - The digital design toolkit

画像はSketch最高っていう顔です。

HTMLやCSSを書くWebフロントエンドエンジニアにとって、Webデザイナーが用意した理想像を現実に落とし込むことは1つの使命であり、費用対効果への葛藤に揺れる中で「技術的に難しいから」という理由でデザインを却下したくないのは誰しも同じだと思います。一方で、技術的に難しくなくとも、デザインファイルの作り方次第ではエンジニアの実装効率も多少なりとも変わってきます。そこで、僕のデザイナー及びエンジニアとしての経験則から、HTML/CSSで実装しやすい(≒Webフロントエンドエンジニアにやさしい)デザインファイルの作り方を、Sketchでの用例も挙げつつまとめてみます。近年はFigmaが注目されつつありますが、基本的な話は共通すると思います。

本来ならばデザイナーにこそ読んでいただきたい記事ではありますが、デザイナーからしたらこれらはエンジニアのエゴであり、エンジニアからすればデザイナーのプロフェッショナル性を問うテーマでもあります。それらを踏まえて、この記事は「エンジニアが先導する形で、デザイナー“”一緒に読んでほしい記事」として、Qiitaに投稿しておきます。

おことわり

  • 記述している内容は、あくまでWebフロントエンドにおける知見であり、ネイティブアプリケーションのUIデザインなどにおいては事情が異なります
  • 本記事では便宜上、HTML及びCSSの記述を主担当とする職種を“エンジニア”、Webページのデザインを主担当とする職種を“デザイナー”と表記しています
  • 納期の関係や開発スタイル、プロダクトの特性などによって、必ずしもエンジニアにとって嬉しい知見になるとは限りません
  • エンジニアから「これを読んでおいて」と一言で済ますような知見の押し付け合いは最悪であり、こういった知見はエンジニア/デザイナー双方合意のもとで効果を発揮するものであるため、必ずコミュニケーションを取って開発スタイルを決めましょう

1. デザインツール

1-1. デザイン関連のサービスやツールを絞る/デザインデータの種類を絞る

至極当たり前のことではありますが、プロダクト開発において依存するサービスやツールは少ないことに越したことはありません。スマートフォンの普及でインターネットがとても身近になった今、デザインの重要性は以前よりも増していることでしょう。それに伴い、プロダクト開発におけるデザインプロセスも多様化し、便利ツールなるものが乱立している状態にあります。10年前にはまだ存在していなかった、プロトタイピングツールやデザインファイルのバージョニングツールが挙げられるでしょう。

これらのツールを使うことは決して悪いことではありませんが、デザイナーだけでなく エンジニアも巻き込む形で“使わなければならない”ツールを増やすことは避けておきたい ところです。UIデザインツールとしてSketch、Figma、Photoshopの3つを同時利用するのではなく、SketchならSketchで1本にしぼり、エンジニアには .sketch のSketchファイルを渡すようにしましょう。Photoshopを写真編集ツールとしてのみ利用するのであれば、 .psd のPhotoshopファイルを渡すのではなく、JPEG(またはPNG)などの“完成した”画像形式でエンジニアに渡すようにしましょう。

2. レイヤーとアートボード

2-1. SketchのPagesを利用するか決める/運用スタイルをエンジニアに伝える

sketch-1.png

SketchのPagesを用いる/用いない場合、その運用スタイルをエンジニアに伝える ようにしましょう。

Pagesの機能を使うデザイナーもいれば、使わないデザイナーもいます。特に『Abstract』のようなデザインファイルのバージョニングツールを利用する事例が増えた今、Pagesを利用せずWebページごとにSketchファイル自体を複製する……といった運用スタイルを採用するチームも目にするようになりました。

エンジニアはどのUIがどのSketchファイルに入っているのかを、Sketchファイル名から推測するかと思いますが、Pagesの中は見落とす傾向にあります。「お問い合わせボタンのスタイルを探すために お問い合わせ.sketch ファイル内をくまなく探したところ、デザイナーに確認すると Page 2 に入っていることが分かった」など、無駄な時間の浪費は避けておくためにも、そもそもPagesを積極的に利用するのか、それとも利用しないのかを話し合っておきたいところです。

もしPagesを利用するのであれば、 それぞれのPageには適切な名前を付けましょう 。自動生成される Page 1Page 2 などの名前は、Sketchファイルが複雑になるほど混乱を招いてしまいます。

2-2. レイヤーのロックを解除してSketchファイルを渡す

sketch-2.png

エンジニアへ渡すSketchファイルには、ロックされた状態のレイヤーをできる限り含めない ようにしましょう。

レイヤーのロック機能はデザイナーにとって便利な機能ですが、アートボードから直接レイヤーを選択することができなくなります。エンジニアは、アートボードからレイヤーを1つ1つ選択し、それぞれのスタイルを確認→コーディングという流れで作業します。この際にレイヤーがロックされていることでレイヤーを選択できないとなると、ロックされているレイヤーをレイヤーパネルから探し、解除するという手間が生じます。エンジニアにとって各レイヤーのスタイルを簡単に見られないことは、想像以上に大変な問題となるわけです。

とはいえデザイナーにとってレイヤーロックを一切使えないことは、作業効率を下げる要因の1つになってしまいます。ロックはできる限り抑えつつも、“兄弟関係のレイヤーを複数ロックする場合は、グループ化した上でグループにロックを掛ける”など、ロック解除の回数を減らす工夫をしておきたいところです。

2-3. ブラー効果は、常にオフにする

skech-3.png

パフォーマンスの観点から、Sketchのブラー効果は常にオフに しておきましょう。

Sketchでは、ブラー効果を簡単かつ非破壊でレイヤーに適用できます。多くのデザイナーは、これを写真に対して用いているでしょう。
残念ながらブラー効果を適用したレイヤーがアートボード内に存在する場合、そのSketchファイルを表示する際の負荷が急激に高くなってしまうのが現状です。これは、Photoshopのスマートフィルターのように、Sketchのグラフィック処理がまだそこまで最適化されていないためです。

エンジニアが操作するコンピュータ性能のリソースは、エンジニアリングに集中させるべきです。デザインファイルを表示したがために、本来のエンジニアリングに支障がでるようでは本末転倒。したがって、Sketchファイル表示時のパフォーマンス低下を防ぐために、ブラー効果をオフにした状態でSketchファイルを渡しましょう。

2-3-1. ブラー効果を適用した画像を取り込む

なにも決して“ブラー効果を使ってはいけない”という意味ではありません。またデザイナーからしてみれば、Sketchファイルを渡すときにブラー効果をオフにするというのも、デザインの俯瞰的なチェックに悪影響を与える要因の1つとなるでしょう。

経験的に、ブラー効果は写真などのラスター画像に対して用いるケースがほとんどです。そのような場合、 Sketch上でブラー効果を用いるのではなく、Photoshopなどでブラー効果を適用した画像をSketchへ取り込む ほうが、ブラー効果を細かく調整できるデザインの観点からも上述のパフォーマンスの観点からもメリットがあると思っています。
また写真以外にも、モーダルの背景に映り込むUIに対してブラー効果を適用させたければ、それこそ背景画像はダミー画像でも問題ないため、こちらもブラー効果を適用したダミー画像を背景画像として取り込んでおきたいところです。

2-4. アートボードは 1x サイズで作る

アートボードは等倍サイズで作成 しましょう。

日本で販売されているほとんどのスマートフォン/タブレットは、iPhoneのRetinaディスプレイを始めとする高精細ディスプレイが搭載されています。特に近年はスマートフォンだけでなく、パソコンも高精細ディスプレイを搭載することが多くなりました。これらのディスプレイは、 2px または 3px 四方を 1px 四方として表示することで、人間の肉眼でドット(ピクセル)を認識することが難しいくらい細かく表示しているわけですね。

Webページでラスター画像を高精細ディスプレイでもキレイに表示するには、等倍時の2倍のサイズで書き出し、等倍時のサイズを指定する必要があります。

高精細ディスプレイ向けに画像サイズをHTMLで調整
<!-- 画像のサイズは 480x80 -->
<img src="/static/logo.png" alt="My Website" width="240" height="40">

このようなこともあって、アートボードのサイズを2倍のサイズで作成するデザイナーもごくたまに見かけますが、 Sketchはベクター画像を扱うツールなので、2倍サイズで作成する必要はありません等倍サイズで作成しましょう 。Photoshopと同様、Sketchも書き出し時に画像サイズの倍率を指定できるため、書き出し時に2倍と指定すれば良いだけです。

また色数が少ない図形に関しては、SVG形式で書き出すのが良いでしょう。SVG画像はWeb上で手軽に扱えるベクター画像で、どのようなサイズで表示してもキレイに表示されます(そのせいか、SketchでSVG形式で書き出す場合は倍率を選択できません)。

余談ではありますが、個人的に、画像の書き出しはエンジニアに任せたほうが良いと思っています。どのような画像で書き出すとコーディングしやすいか、なども直感的に分かるからです。

2-5. 使用しないアートボードは、待避するか削除する

sketch-4.png

使用しないアートボードは、待避するか削除 しておきましょう。

Sketchファイルにおいてのアートボード構造は、デザイナーしか正確に把握できない情報です。使用するアートボードと使用しないアートボードが混在していた場合、それを識別できるのはアートボードを作成/編集したデザイナー本人だけです。
使用しないアートボードが混在していたことで、本来使われないデザインをエンジニアが実装してしまう可能性も考えられます。手戻りやこういった混乱を避けるためにも、使用しないアートボードは待避するか削除するべきです。

2-5-1. デザインファイルのバージョニングツールを用いる

Screen Shot 2020-02-12 at 15.29.57.png

使用しないアートボードを残したいデザイナーの多くは「もしかしたら後々使うかもしれない」という再利用の可能性を考慮していることがほとんどです。

そこで知っておきたいのがデザインファイルの“バージョニング”です。バージョニングとは、自分の任意のタイミングでコメントともにその時点のファイル状態を保持しておく、という概念です。エンジニアは『Git』などのツールを用いてプログラムのバージョニングを行うことが古くから当たり前になっていますが、デザイナーにもこのバージョニングの重要性が浸透しつつあると思います。

エンジニアが用いるバージョニングツール『Git』を用いて、デザインファイルをバージョニングするのも1つの選択肢として挙げられるかもしれませんが、1ファイルあたりの容量を考慮すると決して最善の選択肢とは言えないでしょう。大容量のファイルをGit上でうまく扱うGit LFSを用いたとしても、クローンやプルに膨大な時間がかかってしまいます。

過去に何度か方法を模索しましたが、結局 デザインファイルのバージョニングを行うのであれば、それに特化したツール/サービスを用いるのが現状のベスト でしょう。デザインファイルの本格的なバージョニングツールの先駆けとなった『Abstract』は多くのチームで採用されており、また最近ではSketch純正の『Sketch for Teams』も有力な候補となるでしょう。

2-5-2. アーカイブ用のPagesを追加し待避させる

Screen Shot 2020-02-12 at 15.33.04.png

大企業や一部の企業はツール1つ導入するだけでも稟議のハードルが高かったり、コストの観点から導入を却下されることもあるでしょう。そこで 私が推奨するお手軽かつシンプルな方法は、“待避用のPagesを追加し、待避させたいアートボードをそこへ移動する”という方法 です。この方法は、一度ボツになったデザインを再び採用するような場面でも、すぐにアートボードを探せますし復元も簡単です。

この際に、 oldarchive アーカイブ などといった、使用されないことを示す単語をPagesの名前として採用する必要があります。個人的には、Pagesの接頭辞として _ を追加する管理方法が好きです。 _ が過去のデザインであるということを示すことができれば、Pageの名前を大きく変更せずアーカイブとして扱えるからです。多くのエンジニアは _ のような記号が接頭辞についていると「何らかの意味があるんだな」と推測してくれます。

  • Top … トップページのデザイン
  • About … アバウトページのデザイン
  • _About … 過去のアバウトページのデザイン

ただし念の為にも、上記のような運用スタイルをエンジニアに共有しておきましょう。

2-6. Webページの最低横幅を決める/モバイル向けデザインは、最低横幅で作る

image.png

アートボードのサイズは、チームで決めたWebページの最低横幅で作るべき です。

まず第一に、Webページはモバイル向けネイティブアプリ以上に、多様な横幅で閲覧される媒体です。パソコンのOS上にウィンドウとして表示されるWebページは、ウィンドウをリサイズすれば横幅10pxでも10,000pxでも表示することができるわけです。 多様な横幅での表示に対応するために、Webページの最低横幅を決めておきましょう 。そして、 モバイル向けデザインのアートボードは、その最低横幅で作成 しましょう。

エンジニアはCSSの min-width プロパティを用いることで、最低横幅以下の横幅でWebページを見られたとしても、Webページ内に横スクロールが生じるように制御できます。しかしアートボードが最低横幅より大きいサイズで作られている場合、最低横幅で表示した場合のデザインが考慮されていないため、いざ実装するときにエンジニアから修正依頼が届くかもしれません。

個人的には、最低横幅を 320px にすることを、以下の観点からオススメしています。

  1. 日本においてのiPhoneユーザは非常に多く、また(レンダリング時に) 320px という横幅を採用した『iPhone SE』がそれなりに流通している
  2. 『iPhone SE』で利用可能なiOSがまだサポート中
  3. 横幅 320px 未満の解像度を持ち、なおかつシェアの高いAndroid搭載スマートフォンが存在しない

とはいえ、現代において 320px という狭さはデザインの幅を狭める要因にもなるため、プロダクトのユーザ層の閲覧環境を考慮して決めましょう。 エンジニアリングの観点から、一度決めた最低横幅を広げることは大した問題になりませんが、最低横幅を狭めるのは結構な実装コストがかかってしまいます

2-7. PC向けデザインは、横スクロールが表示され始める最低横幅で作る

image.png

PC向けデザインのアートボードは、ウィンドウの横幅を縮めていったときに、横スクロールが表示される最低横幅で作る ようにしましょう。

2-6と同様、エンジニアがWebページを作成するときは、必ず“どこまでウィンドウを縮めれば横スクロールを出せば良いか”を考えなければいけません。Webページはウィンドウの中で表示されるドキュメントであるため、ユーザがウィンドウサイズを変更しても、レイアウトが崩れることのないデザインを実装する必要があります。

ちなみに、PC用デザインの横幅として、昔は 960〜980px 、数年前までは 1024px で作成されてたWebサイトが多かったものの、最近は 1200〜1280px で作成されているWebサイトをよく目にします。

2-7-1. Smart Guidesを活用する

image.png

エンジニアとしてありがたいのは、Smart Guidesを用いて最低横幅を示したSketchファイル です。最低横幅分をSmart Guidesで引いておき、最低横幅以上のアートボードを作成することにより、最低横幅よりも広い解像度を持つディスプレイでみたときのデザインも実装しやすくなります。

開発環境によっては、Smart Guidesが非表示の状態でSketchファイルが開かれることもあるので、Smart Guidesを使う場合はエンジニアにその旨を伝えて、Smart Guidesを表示するよう意識してもらう必要があります。

2-7-2. 横スクロールバーを表示させない

ネットサーフィンをしていると、横スクロールバーを表示させないレスポンシブなWebページを目にすることがあるでしょう。

レスポンシブ構造は端末の解像度に依存しないため、UXが向上される反面、横幅に応じて柔軟に要素の並べ方を変更させる必要があります。このようなデザインを採用する場合、どこまでウィンドウサイズが縮んだとき、どの部分をどう表示するのかを明確にしておく必要があります。エンジニアの腕だけでなく、デザイナーによるデザインのパターンも多く求められる高度な開発になります。

3. 図形とサイズ

3-1. サブピクセルを使用しない

Screen Shot 2020-02-12 at 16.16.24.png

0.5px3.3px などといった サブピクセル(小数点を含むピクセル)を使用してはいけません

Sketchではサブピクセルがサポートされています。これは、レイヤーサイズだけでなくフォントサイズ・位置などでも同様です。世の中のほとんどのパソコンやタブレット/スマートフォンは、最小単位として px を採用しています。つまり、画面内で表現できる最も小さな値が 1px なので、それを下回る 0.5px という値は本来扱えないはずです。

ではサブピクセルをCSSなどで記述した場合に、画面上にまったく表示されないかと言うとそうでもありません。サブピクセルをWebブラウザで表示した場合、周辺ピクセルを中間色で塗り潰すことによって、 1px 以下のサイズに見せるよう処理されます。しかしその機能はWebブラウザに依存するだけでなくOSやディスプレイにも依存するため、やはりサブピクセルを使うべきではありません。

スマートフォンのネイティブアプリの場合は事情が少し異なり、最近のほとんどのスマートフォンはiPhoneのRetinaディスプレイを始めとする高精細ディスプレイが搭載されています。そのようなディスプレイを搭載しているデバイス向けにデザインする場合は、サブピクセル(またはサブポイント)を指定しても問題ないパターンがほとんどです。
しかしパソコン……高精細でない格安の外部ディスプレイでも表示されることが予想されるWebページにおいては、サブピクセルがどう表示されるかは環境に依存してしまうのです。

これらのことから、 サブピクセルの使用は、Webブラウザやディスプレイの解像度によって表示内容に差異を生じさせるため、使うべきではありません 。よくネイティブアプリのデザイナーがWebデザインをする際に 0.5px のボーダーを多用している場面を見ますが、環境によっては表示されなかったり、または滲んで見えてしまいます。サブピクセルの利用は、要素のサイズだけでなく、フォントサイズや字間も同様に避けておいたほうが良いでしょう。

3-2. 繰り返し表示する画像は、パターンの単体画像も用意する

image.png

背景として 横方向/縦方向、または全方向に繰り返し表示するようなデザインにする場合は、パターン画像も用意 しましょう。

ページ全体の背景画像、見出しの背景画像、罫線のデザインなど、ウィンドウの幅に応じて繰り返し表示される画像は、それ1つで繰り返し表示しても違和感のない“パターン画像”をレイヤー(またはSymbols)かアートボードで用意しておきましょう。パターン画像1つさえあれば、エンジニアはCSSの background-repeat プロパティで簡単に繰り返しを実装できるようになります。

image.png

エンジニアにSketchファイルを渡す前に、作成したパターン画像が繰り返し可能か検証しましょう。例えば格子状の背景をデザインした場合、パターン画像は四辺にボーダーが設定された四角形ではなく、二辺にボーダーが設定された四角形になります。

3-3. Edge to Edgeなデザインは、引き伸ばし/繰り返し可能にする

Edge to Edgeなデザインは、引き伸ばしまたは繰り返しが可能なデザインに しましょう。

画面/ウィンドウの端から端までを覆うEdge to Edgeデザインは、今ではよく見られるデザイン手法の1つではありますが、ウィンドウの可変性を考えると、そこまで柔軟性の高いデザインではありません。

Screen Shot 2020-02-12 at 17.09.31.jpg

写真をEdge to Edgeで表示する場合、その写真を引き伸ばしても成立するようにデザインしましょう。引き伸ばしといっても、CSSの background-size プロパティに cover を指定することで、アスペクト比を固定したまま引き伸ばせますが、写真に映る重要な要素が領域外に出てしまう可能性も考慮しなければいけません。

写真ではなく図形をEdge to Edgeで表示したい場合、その図形は繰り返し表示可能か、もしくは引き伸ばして表示しても問題ないかを確認しましょう。

3-4. Smooth Cornersで角丸にしない

Screen Shot 2020-02-12 at 17.46.39.png

角丸の四角形を作成するとき、Smooth Cornersで角丸にしてはいけません

理由は単純で、技術的に実装するのが難しいからです。単純な角丸はCSSの border-radius プロパティで実装可能ですが、Smooth Cornersを実装するには、それなりの計算が必要になります。

どうしても用いたい場合は、画像として書き出し、そのまま埋め込む形でWebページに掲載されることを許容しましょう。

3-5. ボーダーを中央表示しない

Screen Shot 2020-02-12 at 18.02.04.png

ボーダーを設定する場合は、中央ではなく外側か内側に表示する ようにしましょう。

こちらも理由は単純で、技術的に実装するコストがかかるからです。外側か内側にボーダーを表示するだけならば、CSSの border または box-shadow プロパティを用いれば簡単に実装できます。

borderプロパティを使った外側/内側表示
.outside {
  box-sizing: content-box;
  border: 2px solid red;
}
.inside {
  box-sizing: border-box;
  border: 2px solid red;
}
box-shadowプロパティを使った外側/内側表示
.outside {
  box-shadow: 0 0 0 2px red;
}
.inside {
  box-shadow: 0 0 0 2px red inset;
}

もちろん、外側表示と内側表示を組み合わせることで中央表示を擬似的に実装することは可能ですが、よほどのこだわりがない限り、コード的にも分かりづらい実装方法を強いるデザインを選ぶべきではありません。

3-6. 汎用的なコンポーネントをSymbols化する

Screen Shot 2020-02-12 at 18.16.06.png

よく使い回すコンポーネントは、Symbols化しましょう

Symbolsを簡単に説明すると、レイヤーグループを一元管理し、どこからでも呼び出せるようにするというものです。そして一元管理もとのレイヤーに何らかの変更を加えると、そのSymbolsを呼び出したすべてのレイヤーに変更内容が同期されるといった特徴もあります。

例えば、5枚のWebページのデザインを、5つのアートボードで作成したとします。グローバルヘッダーはすべてのページに含まれるので、先ほどの5つのアートボードすべてにグローバルヘッダーのレイヤーをコピー&ペーストしました。
さて、グローバルヘッダーのデザイン変更が必要な場合、Symbolsを使わないなら何をするべきでしょうか?やるべきことは1つです。最新のグローバルヘッダーのレイヤーを、5つのアートボードすべてに貼り付け直す作業です。ここで、もしも最新のデザインを貼り忘れたアートボードがあったとしたら、エンジニアは混乱してしまうでしょう。

先述したように、Symbolsは元のレイヤーに変更を加えると、呼び出されたSymbolsすべてに変更が適応されます。 アートボード単位でレイヤーが最新かどうかを管理する必要がなくなり、またエンジニアの混乱を防ぐためにも、使い回すコンポーネントは必ずSymbolsで管理 しましょう。

3-6-1. Overrides を活用する

Screen Shot 2020-02-12 at 18.24.24.png

Sketch 3.7から、Symbolsの管理はより便利になりました。大きな特徴として、Overrides(オーバーライド)が挙げられるでしょう。

エンジニアにとって“オーバーライド”という言葉は馴染み深いものかも知れませんが、デザイナーに向けて簡単に説明しておくと“もともとのSymbols内で使用していたテキストや色を、呼び出し元でだけ改変できる機能”です。

例えば“送信”という文言が含まれたボタンをSymbol化します。しかしページによっては、ボタンのスタイルはそのままで“キャンセル”といった文言に変更したいこともあるでしょう。そこで“送信”という文言をオーバーライドすることで、Symbol自体の文言を変更することなく、その呼び出したSymbolレイヤーの文言のみを変更することができます。オーバーライドを使わない場合、“送信”ボタンのSymbolsを解除して文言を変えるか、“キャンセル”という文言のためだけに新たにSymbolsを作らなければいけません。

3-6-2. 背景色に依存しないSymbolsを作る

あらゆるページのあらゆる箇所で使用するコンポーネントはSymbolsとして作成するべきですが、 背景色に依存しないSymbolsとして作っておきましょう

例えば、Symbolsを作成したときのアートボードが白色だった場合、黒色に不透明度を設定することで灰色を表現できますが、背景が赤いアートボードでそのSymbolsを使用すると、灰色として表示されなくなってしまいます。

意図しない色のコンポーネントが生まれてしまうことを避けるために、背景色に依存しない形でSymbolsを作りましょう。もっとも、4-4に準拠していれば、このようなことは起こり得ないはずです。

4. 色

4-1. カラースキームを可視化する/Document Colorsを使う

Screen Shot 2020-02-12 at 17.33.21.png

デザイナーはデザインの作成にあたり、あらかじめカラースキームを定めると思いますが、 カラースキームを何かしらの形で可視化するか、SketchのDocument Colorsを使って管理する ようにしましょう。

カラースキームの可視化はデザイナーとエンジニア双方に良い影響を与えます。デザイナーにとっては使用色数を抑えることに繋がります。エンジニアにとっても、エンジニアは使用する色をコード上の変数で一元管理することが多いため、どの変数を用いれば良いかが分かりやすくなります。

4-1-1. Global ColorsとDocument Colors

Global Colorsは、使用者のMac上で開いたSketchファイルすべてから参照できるカラーパレットです。使用するMacによってパレットは異なり、Sketchファイルにはカラーパレット情報が記録されません。

Document Colorsは、そのSketchファイル内からのみ参照できるカラーパレットです。Sketchファイルに直接カラーパレットの情報が記録されるため、同じファイルを開けば同じカラーパレットを参照できるようになります。Document ColorsはLibraries化したSketchファイルからも参照できます。

ロゴなどのプロダクト全体で使うデザインを集めたSketchファイル上で、Document Colorsを用いてカラースキームを管理し、そのファイルをLibraries化するとグッと扱いやすくなります。

4-1-2. 不透明度のバリエーションがある色は、不透明度100%でDocument Colorsに追加する

不透明度のバリエーションがある色は、不透明度を100%にしてからDocument Colorsに追加 しましょう。

例えば #ff9000 という色に対して、不透明度80%・50%・20%を設定した色を適用させたいとき、Document Colorsに追加される色数は #ff9000 の不透明度100%のみに絞りましょう。エンジニアは不透明度100%の色さえ分かれば、簡単にコードで不透明度を変更できます。またデザイナーが管理すべき色数を増やさないためにも、不透明度100%のものだけをDocument Colorsに追加するべきです。

4-2. レイヤー自体に不透明度を設定しない

Screen Shot 2020-02-12 at 17.51.57.png

できる限りレイヤー自体に不透明度を設定してはいけません

実際、レイヤーではなくボーダー色や塗り色に対して不透明度を設定すれば済むケースがほとんどで、上の画像のようにレイヤーにも塗り色にも不透明度が設定されたレイヤーなんて、最も避けておきたい事態です。不透明度の設定数を減らし、また不透明度の設定箇所を統一することは、エンジニアの実装漏れなどを防ぐことにつながります。

上の画像の場合、塗り色に35%の不透明度を持たせることで、不透明度設定が簡潔になりますね。

4-3. レイヤーグループ自体に不透明度を設定しない

できる限りレイヤーグループ自体に不透明度を設定してはいけません

こちらも4-2と同様です。エンジニアがレイヤーのスタイルを目視しつつ実装する流れにおいて、レイヤーグループを選択することはあまりありません。レイヤー1つ1つを選択していくため、レイヤーグループに透明度設定が施されていた場合、透明度の実装漏れに繋がる可能性があります。

Screen Shot 2020-02-12 at 17.58.03.png

上の画像では、青色の円形の塗り色に対して50%の不透明度が設定されています。

Screen Shot 2020-02-12 at 17.59.21.png

この2つの円はとあるレイヤーグループに含まれており、このレイヤーグループ自体には50%の不透明度が設定されています。多くのエンジニアは、レイヤーグループに不透明度が設定されているなんて気付かないでしょう。それならばレイヤーグループではなく、円形に25%の不透明度を設定すれば済む話です。

1つのコンポーネントに対して複数の不透明度設定が混在すると、エンジニアは1つ1つのレイヤーやレイヤーグループを細かく見なければいけません。これは非常に効率が悪くなるので避けておきたいところです。

4-4. 灰色を表現するためだけに、不透明度を設定しない

Screen Shot 2020-02-12 at 18.09.59.png

灰色、または白みがかった色を表現するためだけに、不透明度設定をしてはいけません

意外とよく見かけるのが、アートボードの背景が白色であることを前提に、灰色を表現するためだけに #000000 に対して不透明度を設定するアンチパターンです。あらゆる背景色に対応するために意図的に不透明度を設定する場合はこの限りではありませんが、灰色として表示したければ不透明度100%のまま、灰色を指定しましょう。

Webページにおいて、影 box-shadow や不透明度 opacity 、角丸 border-radius などは、微量ながらもレンダリングパフォーマンスに影響を与えます。パフォーマンスの悪化に怯えて利用を控えるほどのものではありませんが、パフォーマンスに影響を与えるものを無駄に利用する必要はないでしょう。

5. フォント

5-1. 環境に依存しないフォントを用いる

image.png

どのようなフォントでも崩れないスタイルを優先 してください。

Webはデジタル世界で最大のクロスプラットフォームである反面、どのような環境でも崩壊しないレイアウト・デザインを採用しなければいけない難しさがあります。ヒラギノフォントはmacOSのみ、特にHiragino Sansは『OS X El Capitan』以降でのみ採用されているフォントであるため、それを前提にデザインしてしまうと、WindowsやAndroid端末だけでなく旧macOSで閲覧したときに、大きなレイアウト崩壊を招く恐れがあります。

原則として、“明朝体か否か(SerifかSans Serifか)”、“太字か太くないか”のそれぞれ2択から選ぶ粒度にしておく べきです。macOSはデフォルトで様々なフォントがインストールされており、またどれも商用利用可能1です。しかし他の環境では丸ゴシックが搭載されていなかったり、OSデフォルトフォントのウェイト(太さ)も、2種類しか存在しなかったり。

5-1-1. Webフォントという選択肢

image.png

Webフォント TypeSquare [タイプスクウェア] / Webフォント・サービス「FONTPLUS」 | Fontworks

どの環境からでも同じフォントを使用したい場合は、特定のフォントをWebページ自体に埋め込む、通称“Webフォント”という技術を用いることで解決します。Webフォントは、閲覧者の端末に特定のフォントがインストールされている・されていないに関わらず、指定したフォントをページ内で使用できるようになります。

デメリットとしては、ページの表示速度が低下する他、そのフォントがWebフォントに対応しているか、ライセンス的に問題ないかなどの確認作業が必要となる点が挙げられます。特に日本語フォントが有するグリフ(文字)数は相当のもので、1つのフォントだけでも10MBを超えることもザラにあります。

大手フォントメーカーのモリサワフォントワークスなどではWebフォントサービスを開始しており、ページ内で必要なグリフのみを提供することでフォントの通信量を削減するといった工夫2も施されています。とはいえスマートフォンにとってページ表示速度の低下は、UXの低下だけでなくSEOにも多少なりとも影響を与えるため、本当にWebフォントを導入すべきか、じっくり検討しましょう。

5-1-2. 部分的に画像を用いる

一部の見出しなど、部分的に特定のフォントを用いたい場合は、Webフォントではなく画像を用いた方が総合的なコストを抑えられる場合もあります。画像の場合は、Webフォントで挙げられたデメリットを深く考える必要がなくなりますが、誤字脱字などによるテキスト修正時は都度画像を書き出す必要があります。

5-2. 丸ゴシックを使わない

Webフォントを使わない限り、 丸ゴシックをWebページで用いてはいけません

macOSには、欧文和文問わず丸ゴシック体のフォントが標準搭載されていますが、すべてのOSが丸ゴシックを搭載しているとは限らないのが現状です。Webフォントを使用しない限りは、互換性の観点から丸ゴシックを使わないデザインにしなければいけません。

それでも丸ゴシックを採用したい場合は5-1でも述べたとおり、Webフォントか画像を使うと良いでしょう。

5-3. フォントウェイトは、“太い”か“太くない”の2択から選ぶ

フォントウェイトは、“太い”か“太くない”の2択から選ばなければいけません

Sketchは、そのMacにインストールされたすべてのフォントの、すべてのフォントウェイトから書体を選ぶことができます。フォントがOSに依存してしまうことは周知の事実ですが、特に見落としやすい部分がフォントウェイト(文字の太さ)です。

環境によってフォントウェイトの選択肢は大きく異なるため、細かなウェイトの指定はすべきではありません。事実、 同じmacOS上であっても、Sketchで表示したmacOS標準フォントと、Webブラウザで見たときの標準フォントの太さは全く異なります 。Webブラウザでは、Illustratorのレイヤーをアウトライン化したときのように、フォントサイズが大きくなるほど太さも太くなります。一方Sketchは、どれだけフォントサイズを大きくしても、フォントウェイトはそれなりに保ったままです。

またエンジニアの観点からは、CSSの font-weight プロパティでは bold のようなキーワードの他に、 500 といった数値も利用可能です。しかし上述の理由から、あまり利用すべきではないでしょう。
もっとも、プログレッシブ・エンハンスメントのようなアプローチで「様々なフォントウェイトを持つフォントが搭載されたOSでは font-weight: 500 を適用、そうでない場合は normal 相当でいい」というような設計であれば、 font-weight に対して数値を利用するのも選択肢の1つとしてなり得ます。

最後に

Webフロントエンドエンジニアは、Webフロントエンドを実装する以上、デザインから逃れることはできません。一方Webデザイナーは、Webという世界にデザインを落とし込まなければ完成しない以上、エンジニアと協力しなければいけません。どちらかが傲慢な態度ではチームもプロダクトもうまく回りませんし、お互いの仕事を尊重しつつ、お互いが気持ちよく働ける環境を築くことが重要です。

Webフロントエンドの技術的な要素はもちろん、デザインツールやデザインに対する思想/あり方などは日々変化しています。お互いが利用するツールを熟知する必要はありませんが、必要に応じてお互いが求めるツールを導入するなどして、お互い高め合っていけると良いですね。

おひたしおひたし。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

初心者によるプログラミング学習ログ 237日目

100日チャレンジの237日目

twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。

100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。

237日目は

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

CSSで要素を配置する基本テクニック8種類をサンプル付きで紹介します

概要

MDNのCSS レイアウト入門を参考に、CSSレイアウトの基本のテクニックの概要を自分なりにまとめました。それぞれの項目について詳しく知りたい場合は、各項目の冒頭に記載してあるリンク(MDNのCSS レイアウトの各章)を参照してください。

「CSSレイアウト」とは

ビューポートや互いを基準にしてボックスを適切な場所に配置する方法

CSS レイアウトより

例えば、「赤い四角を画面の右半分に、青い四角を画面の左半分に配置する」「画像の右側に文章を配置し、それを1セットとして縦並びに配置する」などがCSSレイアウトということになります。四角を赤くしたり、画像や文字のサイズを整えるのは、「レイアウト」の範囲外です。

通常フロー

https://developer.mozilla.org/ja/docs/Learn/CSS/CSS_layout/Normal_Flow
ブラウザがデフォルトでHTMLページをレイアウトする方法です。
特にスタイルを設定していない状態を指します。


See the Pen
KKpKaaZ
by mmkcoins (@mmkcoins)
on CodePen.


displayプロパティ

https://developer.mozilla.org/ja/docs/Web/CSS/display
要素が通常フローでどのように振る舞うかを変更するプロパティです(block, inlineなど)。
またはdisplay値によってオンにされるレイアウト方法全体を指します(flexなど)。
任意の要素に設定できます。

  • ブロック要素(block): 縦並び
  • インライン要素(inline): 横並び

See the Pen mdJdRmV by mmkcoins (@mmkcoins) on CodePen.

フレックスボックス

https://developer.mozilla.org/ja/docs/Learn/CSS/CSS_layout/Flexbox
Flexible Box Layout Moduleの略です。
子項目にflexプロパティ(向き、要素の大きさなど)を追加できます。

See the Pen eYNYgRL by mmkcoins (@mmkcoins) on CodePen.

グリッド

https://developer.mozilla.org/ja/docs/Learn/CSS/CSS_layout/Grids
行と列に物を並べる(2次元)用に設計されています。
子項目にプロパティを設定しなくても自動で配置されます。開始ラインや終了ラインを設定することで柔軟に配置できます。


See the Pen
eYNYgjb
by mmkcoins (@mmkcoins)
on CodePen.


フロート

https://developer.mozilla.org/ja/docs/Learn/CSS/CSS_layout/Floats
設定すると、要素が左または右に移動し、通常フローから除かれます。
また、フロート項目を囲んでいるコンテンツが周囲に浮き(回り込み)ます。


See the Pen
zYGYNVg
by mmkcoins (@mmkcoins)
on CodePen.


位置指定(positionプロパティ)

https://developer.mozilla.org/ja/docs/Learn/CSS/CSS_layout/Positioning
通常フローの時に要素が配置されていた場所から、別の場所に移動できます。

静的位置指定 (Static Positioning)

デフォルトです。特別な位置指定がありません。

相対位置指定 (Relative Positioning)

通常フロー内の位置に相対的に移動できます。

絶対位置指定 (Absolute Positioning)

ページの通常のレイアウトフローから完全に外れます。
<html>の端に相対的な位置に固定できます。

固定位置指定 (Fixed Positioning)

ブラウザのビューポート基準で要素を固定します。

粘着位置指定 (Sticky Positioning)

ビューポートからオフセットにぶつかるまではstaticの、それ以降はfixedの挙動をします。
割と最近できたプロパティです。

See the Pen RwPwpbp by mmkcoins (@mmkcoins) on CodePen.

表レイアウト

表をスタイルするための機能です。
display: table-cell;のような書き方をすると表レイアウトになります。
表以外のレイアウトにも使えるようです(表レイアウトでページレイアウトを行っていた時代もあった、らしい)。


See the Pen
rNVNyaE
by mmkcoins (@mmkcoins)
on CodePen.


段組みレイアウト

https://developer.mozilla.org/ja/docs/Learn/CSS/CSS_layout/Multiple-column_Layout
新聞のように複数列にレイアウトする方法です。


See the Pen
RwPwpWg
by mmkcoins (@mmkcoins)
on CodePen.


  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

CSS : アイコンのタップ範囲を表示に影響なく広げる

  • 16x16のアイコンをスマホ、タブレットでタップさせるのは厳しい
  • でも不格好なのでアイコンを大きくしたくない

以上の要件から生まれたのがコレ↓

See the Pen アイコンのタップ範囲を広げるスタイル by Kazuyoshi Goto (@KazuyoshiGoto) on CodePen.

従来のアイコン要素に一つクラスを加えるのみで実現させている。

HTML

<i class="fas fa-question-circle taparea"></i>

Font Awesome標準のアイコン表示にtapareaクラスを付与しているだけ。

CSS

.taparea {
  position: relative;
}
.taparea:after {
  display: block;
  content: '';
  position: absolute;
  width: 40px;
  height: 40px;
  top: -12px;
  left: -12px;
  border-radius: 50%;
  background: rgba(255, 0, 0, 0.2); /* 分かりやすくするための色付け。実装時は外す */
}

40x40の:after要素がアイコンの中央に来るように生成しています。
absolute配置なのでアイコン以外の要素を邪魔しません。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Wordpressの管理画面にオリジナルのCSS・JavaScriptを適用させる

フォルダ構成

qiita.png

必要な記述

functions.php
<?php
/**
 * エディタースタイル適用
 * */

    add_editor_style(get_template_directory_uri()."/css/admin/editor-style.css");

/**
 * 管理画面スタイル適用
 * */

function my_admin_stylesheet()
{
    wp_enqueue_style('custom-admin-style', get_stylesheet_directory_uri().'/css/admin/admin-style.css');
    wp_enqueue_script('admin-script', get_stylesheet_directory_uri() . '/js/admin/admin-style.js', array(), '1.0.0', true);
}
add_action('admin_enqueue_scripts', 'my_admin_stylesheet');

/**
 * 管理画面にもfaviconをつける
 * */
function admin_favicon()
{
    echo '<link rel="shortcut icon" type="image/x-icon" href="'.get_stylesheet_directory_uri().'/img/favicon.ico" />';
}
add_action('admin_head', 'admin_favicon');

/**
 * ログイン画面CSS変更
* */

function my_login_stylesheet()
{
    wp_enqueue_style('custom-login', get_stylesheet_directory_uri().'/css/admin/login-style.css');
}
add_action('login_enqueue_scripts', 'my_login_stylesheet');
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

楽天商品ページにハンバーガーメニューをつける

はじめに

例のごとく、実装は自己責任でお願いします笑
また、今回も最小の構成から徐々にカスタマイズする方針で作っていきます。

最後にソースコードの最終形を載せていますので、内容を十分理解できる方はそこまで飛ばして構いません。

説明しないこと

  • 楽天GOLDの契約手順
  • FTPへのアップロード方法
  • HTMLやCSSの基礎

前回と同じですね。

前提

今回も、以下の前提の上に説明を進めます。

  • ショップURL & GOLDアカウント名: myshop

手順

RMS側の設定

まずは商品ページにいろいろとパーツを追加します。

店舗設定 > 2 デザイン設定 > スマートフォンデザイン設定 > 商品ページ共通パーツ設定

<!-- navigation bar -->
<iframe class="sp-navbar" frameborder="0" scrolling="no" src="https://www.rakuten.ne.jp/gold/myshop/iframe/sp-navbar.html" width="100%" frameborder="0" =""></iframe ="">

<!-- hamburger button -->
<label class="ham-btn" for="navcheck" ="">OPEN</label ="">
<input id="navcheck" type="checkbox" ="">
<link rel="stylesheet" href="https://www.rakuten.ne.jp/gold/myshop/iframe/css/navbar.css" ="">

<!-- navigation drawer -->
<div class="sp-drawer" ="">
  <iframe frameborder="0" src="https://www.rakuten.ne.jp/gold/myshop/iframe/navigation-drawer.html" width="100%" frameborder="0" =""></iframe ="">
</div ="">

<!-- close button [x] -->
<label class="close-btn" for="navcheck" =""><span =""></span =""><span =""></span =""></label ="">
<link rel="stylesheet" href="https://www.rakuten.ne.jp/gold/myshop/iframe/css/drawer.css" ="">

これについて上から順番に説明しますと、こうなります。

要素 説明
.sp-navbar ハンバーガーの三本線ボタンあたりにいる帯です。こいつの上に「OPEN」ボタンを載せます。自由にデザインできますが、今回はいじりません。
.ham-btm よく見る三本線ボタンです。今回は面倒なので三本線ではなく「OPEN」というテキストにしておきます。for属性を指定することで、タップした時にチェックボックスをON/OFFします。
#navcheck チェックボックスです。「OPEN」をタップしたらチェックのON/OFFが切り替わります。CSSセレクタ~の関係で、.sp-drawerより前に無いとダメだし、divとかで囲むのもNGです。
.sp-drawer 左からニョキっと出てくるアレ(ナビゲーションドロワー)です。
.sp-drawer>iframe ドロワーの中身です。
.close-btn ドロワーが出ている時に表示する x の形をした閉じるボタンです。ちなみに、こいつの疑似要素で背景のグレーを作ります。このxボタンとグレー背景をタップした時にチェックボックスをON/OFFします。

FTPサーバ内のファイル構成

それでは中身を作っていきましょうね~

myshop/
└── iframe/
    ├── sp-navbar.html ← 画面上部に表示する帯状のナビゲーション
    ├── navigation-drawer.html ← ハンバーガーメニューをタップした時に左から出てくるやつ
    └── css/
        ├── drawer.css ← navigation-drawer.html のスタイル
        └── navbar.css ← sp-navbar.html と、label, input のスタイル

/で終わるものはディレクトリ名(=フォルダ名)です
myshop/はFTPのroot(一番上のフォルダ)で、新規作成の必要はありません

とりあえずそれっぽいのを作ってみる

ナビゲーションドロワーnavigation-drawer.htmlは、オーソドックスにリンクの箇条書きにします。
とりあえずこんな風にしました。

この記事内では使いませんが、いろいろと便利なのでfontawesomeとbootstrap4を読み込ませました。

htmlbodyにクラスを付けたのは理由がありますが、それは後述します。

navigation-drawer.html
<!DOCTYPE html>
<html class="navbar-html">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>sp navigation drawer</title>

  <!-- Fontawesome -->
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.3.1/css/all.css" integrity="sha384-mzrmE5qonljUremFsqc01SB46JvROS7bZs3IO2EmfFsd15uHvIt+Y8vEf7N7fWAU" crossorigin="anonymous">
  <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" >

  <!-- bootstrap4 css -->
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

  <!-- my style -->
  <link rel="stylesheet" href="css/drawer.css">

</head>
<body class="navbar-body">

<ul class="menu">
  <li><a href="#">link</a></li>
  <li><a href="#">link</a></li>
  (繰り返し)
  <li><a href="#">LAST</a></li>
</ul>

<!-- bootstrap4 js -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>

</body>
</html>
drawer.css
@charset "utf-8";

.sp-navbar {
  position: fixed;
  width: 70vw;
  height: 100vh;
  top: 0;
  left: -70vw;
}
sp-navbar.html
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>sp navigation drawer</title>

  <!-- Fontawesome -->
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.3.1/css/all.css" integrity="sha384-mzrmE5qonljUremFsqc01SB46JvROS7bZs3IO2EmfFsd15uHvIt+Y8vEf7N7fWAU" crossorigin="anonymous">
  <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" >

  <!-- bootstrap4 css -->
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

  <!-- my style -->
  <link rel="stylesheet" href="css/drawer.css">

</head>
<body>

<p>マイショップ</p>

<!-- bootstrap4 js -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>

</body>
</html>
navbar.css
@charset "utf-8";

.sp-navbar {
  position: absolute;
  height: 60px;
  top: 150px;
  left: 0;
  right: 0;
}

ここまではパーツの配置だけなので、やっていることは前回記事「楽天スマホ商品ページにiframeを入れる」と同様です。では、この段階でどんな見た目になるか見てみます。

000.jpg

iframe.sp-header前回記事で作ったものです。
前回から引き続き参考にしていただいてる方は、このiframe.sp-header関係のCSSを調整してください。でないと、パーツが重なってしまいますので。

さて、この状態から足りないものを書き出してみます。

要素 足りないもの
iframe.sp-navbar 特になし。好きにデザインしてよし。ただし右端は「OPEN」の文字が重なる予定。
.ham-btn iframe.sp-navbarの右端に位置を持っていく。
#navcheck チェックボックス。デザイン上必要ないので非表示にする。
.close-btn 2つのspanタグでxの形を作る。あと、位置を固定する。
.close-btn::after 疑似要素のグレー背景をCSSで実装する。
.sp-drawer チェックボックスがONの時だけニョキッと画面に出す(アニメーション)。
.sp-drawer>iframe .sp-drawerの最大までサイズを引き伸ばす。

では、順番に実装してみましょう。.sp-navbarは飛ばして、.ham-btnから。
これから書くことは、CSSのファイルに追記していってください。

z-indexについては今まで言及しませんでしたが、つまり要素の重なり順です。
ざっくり言うと、値が大きいほど手前に表示されます。

楽天スマホパーツのうち、画面下「かごに入れる」等のボタンがz-index: 900000;なので、とりあえず1万付近でデザインしています。

.ham-btnを配置する

navbar.css
label.ham-btn {
  position: absolute;
  top: 160px;
  right: 10px;
}

チェックボックスを非表示にする

navbar.css
#navcheck {
  display: none;
}

.close-btnx の形を作り、位置を固定する

drawer.css
.close-btn {
  display: none;
  width: 30px;
  height: 30px;
  position: fixed;
  top: 50px;
  left: calc(70vw + 15px);
  z-index: 9999;
}

#navcheck:checked~.close-btn {
  display: block;
}

.close-btn span {
  display: block;
  position: absolute;
  left: 0;
  top: 25px;
  height: 2px;
  width: 30px;
  background-color: white;
  z-index: 9999;
}

.close-btn span:first-child {
  transform: translate(0, -10px) rotate(45deg);
}

.close-btn span:last-child {
  transform: translate(0, -10px) rotate(-45deg);
}

ドロワーが出ている時だけの暗い背景を作る

drawer.css
.close-btn::after {
  display: none;
  content: '';
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  background-color: rgba(0, 0, 0, .5);
}

#navcheck:checked~.close-btn::after {
  display: block;
}

チェックボックスがONの時だけニョキッと画面に出す

drawer.css
.sp-drawer {
  z-index: 10000;
  transition: all .4s ease; /* 0.4秒かけてぬるっと移動する指定 */
}

#navcheck:checked~.sp-drawer {
  left: 0;
}

iframeのサイズを指定する

drawer.css
.sp-drawer>iframe {
  width: 100%;
  height: 100%;
}

結果を見てみる

お疲れさまでした。どうなったか見てみましょう。

2020-02-12-13-57-40.gif

概ねOKですね。画面下のボタンにも影響ないみたいです。

しかし、実は細かいところがまだカバーできていません。それは以下の点です。

  • ドロワーが長くなった場合にスクロールできない
  • 一番下までスクロールしたとして、「かごに追加」パーツの高さ分、ドロワーの下部が隠れてしまう

スクロール問題をなんとかする

前述した、htmlbodyにクラスを付けた理由がここにあります。
この辺の問題を解決するためです。以下を追加することでなんとかなります。

drawer.css
.sp-navbar {
  -webkit-overflow-scrolling: touch;
  overflow: auto;
}

html.navbar-html::-webkit-scrollbar {
  display: none;
}

body.navbar-body {
  overflow-y: scroll;
  padding-bottom: 71px; /* 「かごに入れる」ボタンの高さ */
}

早速確かめてみます。ドロワー内の最後の要素「LAST」が無事見えればOKとなります。
なお確認にあたり、高さを稼ぐため下記を追加していますが、ドロワー内部のデザインは自由なので必須ではありません。

drawer.css
body.navbar-body {
  background-color: lightgray;
}

.menu {
  line-height: 60px;
}

2020-02-12-14-16-03.gif

さいごに

これで本当に終わりです。今度こそお疲れさまでした。

「OPEN」の文字の部分は、アイコン画像を作るなり、CSSでボタンを作るなりしてください。
(正直、疲れてしまってそこまでの内容をカバーする気力が無い……)

最後に4つのソースコードが最終的にどうなったかを見せて終わりにします。お付き合いいただきありがとうございました。

ソースコード最終形

sp-navbar.html については最初から変化ないです。

sp-navbar.html
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>sp navigation drawer</title>

  <!-- Fontawesome -->
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.3.1/css/all.css" integrity="sha384-mzrmE5qonljUremFsqc01SB46JvROS7bZs3IO2EmfFsd15uHvIt+Y8vEf7N7fWAU" crossorigin="anonymous">
  <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" >

  <!-- bootstrap4 css -->
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

  <!-- my style -->
  <link rel="stylesheet" href="css/drawer.css">

</head>
<body>

<p>マイショップ</p>

<!-- bootstrap4 js -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>

</body>
</html>
navigation-drawer.html
<!DOCTYPE html>
<html class="navbar-html">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>sp navigation drawer</title>

  <!-- Fontawesome -->
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.3.1/css/all.css" integrity="sha384-mzrmE5qonljUremFsqc01SB46JvROS7bZs3IO2EmfFsd15uHvIt+Y8vEf7N7fWAU" crossorigin="anonymous">
  <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" >

  <!-- bootstrap4 css -->
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

  <!-- my style -->
  <link rel="stylesheet" href="css/drawer.css">

</head>
<body class="navbar-body">

<ul class="menu">
  <li><a href="#">link</a></li>
  <li><a href="#">link</a></li>
  (省略)
  <li><a href="#">link</a></li>
  <li><a href="#">LAST</a></li>
</ul>

<!-- bootstrap4 js -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>

</body>
</html>
navbar.css
@charset "utf-8";

.sp-navbar {
  position: absolute;
  height: 60px;
  top: 150px;
  left: 0;
  right: 0;
}

label.ham-btn {
  position: absolute;
  top: 160px;
  right: 10px;
}

#navcheck {
  display: none;
}
drawer.css
@charset "utf-8";

.sp-drawer {
  position: fixed;
  -webkit-overflow-scrolling: touch;
  overflow: auto;
  width: 70vw;
  height: 100vh;
  top: 0;
  left: -70vw;
  z-index: 10000;
  transition: all .4s ease;
}

.close-btn {
  display: none;
  width: 30px;
  height: 30px;
  position: fixed;
  top: 50px;
  left: calc(70vw + 15px);
  z-index: 9999;
}

#navcheck:checked~.close-btn {
  display: block;
}

.close-btn span {
  display: block;
  position: absolute;
  left: 0;
  top: 25px;
  height: 2px;
  width: 30px;
  background-color: white;
  z-index: 9999;
}

.close-btn span:first-child {
  transform: translate(0, -10px) rotate(45deg);
}

.close-btn span:last-child {
  transform: translate(0, -10px) rotate(-45deg);
}

.close-btn::after {
  display: none;
  content: '';
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  background-color: rgba(0,0,0,.5);
}

#navcheck:checked~.close-btn::after {
  display: block;
}

#navcheck:checked~.sp-drawer {
  left: 0;
}

.sp-drawer>iframe {
  width: 100%;
  height: 100%;
}

/* -------------------------------------
inner iframe
------------------------------------- */
html.navbar-html::-webkit-scrollbar {
  display: none;
}

body.navbar-body {
  background-color: lightgray;
  overflow-y: scroll;
  padding-bottom: 71px;
}

.menu {
  line-height: 60px;
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Vue.jsでドロワーメニュー(スライドメニュー)を実装

codesandboxに書いてみたので、動きはこれを見ていただけると!(App.vue参照)
https://codesandbox.io/embed/objective-flower-kuov7?fontsize=14&hidenavigation=1&theme=dark

以下、ざっくり内容をざっくりメモ程度に。

template
<template>
  <div id="app">
    <div>
      <button @click="openDrawerMenu">ボタン</button>
    </div>
    <transition name="right">
      <div v-if="drawerFlg" class="drawer-menu-wrapper">
        <div class="drawer-menu">
          <!-- ここにメニューの内容を書いていく -->
        </div>
      </div>
    </transition>
  </div>
</template>
script
<script>
export default {
  name: "App",
  data() {
    return {
      drawerFlg: false
    };
  },
  methods: {
    openDrawerMenu() {
      this.drawerFlg = true;
    }
  }
};
</script>
style
<style>
//右から出したい場合
.right-enter-active, .right-leave-active {
  transform: translate(0px, 0px);
  transition: transform 225ms cubic-bezier(0, 0, 0.2, 1) 0ms;
}
.right-enter, .right-leave-to {
  transform: translateX(100vw) translateX(0px);
}

//左から出したい場合
.left-enter-active, .left-leave-active {
  transform: translate(0px, 0px);
  transition: transform 225ms cubic-bezier(0, 0, 0.2, 1) 0ms;
}
.left-enter, .left-leave-to {
  transform: translateX(-100vw) translateX(0px);
}

//以下、メニューの形に合わせて良い具合に変更してください
.drawer-menu-wrapper {
  position: absolute;
  z-index: 10;
  top: 0;
  right: 0; //右に出す場合
  left: 0 //左に出す場合
  width: 50%;
  height: 100%;
  background-color: white;
}
.drawer-menu {
  padding: 24px;
}
</style>

参考: https://qiita.com/Nexus0831/items/9dbbac367a653fbd8ba4

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

HTML5プロフェッショナル認定試験レベル1を受験してみた

HTML5プロフェッショナル認定試験レベル1 受験レポート

2020/2にHTML5プロフェッショナル認定資格Level1を受験しました。

資格を受験するのはかれこれ2年ぶりくらい?ぶりで学習方法も忘れているような状態でしたが、
ちょっと新鮮な気持ちだったので忘れないうちに備忘録として残しておこうと思います。

業務経歴

受験時点での私の業務経歴を簡単にまとめました。

・基本的にサーバーサイドを担当
・Javaで2.5年ほど開発案件に携わってきた
・FWとしてはStruts1・Seasar2 → Springのマイグレーションで触れるもののみ

といったフロント系の知識とは疎遠の仕事をしてきたサーバーサイドエンジニアです。

受験経緯

2018年秋・冬頃に社内でHTML5の勉強会を開催いただいて、そのときに受験をオススメしてもらいました。
当時は業務についていくのがやっとで全く余裕がなかったため、勉強会から約1年後に受験となってしまいましたが、
「せっかく学習したのでなにか形に残るものがほしい」、「体系的なHTML・CSSの知識を身に付けたい」と思った次第です。

また、基本的に業務ではサーバーサイドを担当していますが、
少なからずHTMLの内容を修正したりする場面もあったので役立つのでは?と考えていました。

学習方法

合格者の方の記事を読んだりしながらいろいろ参考にさせていただきました。
私は主に以下のような順番で学習に取り組んでいました。

1. HTML5プロフェッショナル認定試験 レベル1 対策テキスト&問題集 Ver2.0対応版

https://www.amazon.co.jp/exec/obidos/ASIN/B07485SSV3/neos21-22/

まずはじめは全般的に単語や文法を覚えるところからでした。
社内の勉強会でもこの本に沿ってカリキュラム化されていたので、それを復習しつつ頭に叩き込んでいきました。

CSSは覚えるプロパティが結構多いので、時々くじけながら頑張っていました。

2. Ping-t

会社で勉強用にアカウントを用意してもらいました。

問題としては約500問ほど収録されていて、
はじめは銅だったものが1回正解で銀・2回正解で金と学習の進捗が非常にわかりやすいのが良いところです。
(逆に間違えると銀や銅に戻る仕組みになっています)
覚えた要素やプロパティの知識を定着させるのに抜群の効果を発揮するのでオススメできます。
※Ping-tのまわしものではないです

ping-t.png

これを通勤中や夜寝る前に20問程度ずつ解いていました。

3. HTML教科書 HTML5プロフェッショナル認定試験 レベル1 スピードマスター問題集 Ver2.0対応

https://www.amazon.co.jp/HTML%E6%95%99%E7%A7%91%E6%9B%B8-HTML5%E3%83%97%E3%83%AD%E3%83%95%E3%82%A7%E3%83%83%E3%82%B7%E3%83%A7%E3%83%8A%E3%83%AB%E8%AA%8D%E5%AE%9A%E8%A9%A6%E9%A8%93-%E3%83%AC%E3%83%99%E3%83%AB1-%E3%82%B9%E3%83%94%E3%83%BC%E3%83%89%E3%83%9E%E3%82%B9%E3%82%BF%E3%83%BC%E5%95%8F%E9%A1%8C%E9%9B%86-Ver2-0%E5%AF%BE%E5%BF%9C-ebook/dp/B079PMR94Q/

以前受験していた方からも評判もよかったので、こちらを使っていました。
Ping-tとは少し違ったテイストの問題が収録されていたりするので、問題慣れするために効果的だったと思います。

本番の試験では予習してた問題と少し雰囲気が違う出題がされたりするという声もあったので…

試験概要

試験時間:80分
問題数:60問
受験料:15,000円(税別)
試験方式:コンピュータベーストテスト(CBT)
認定の有意性期限:5年間

時間としては十分すぎるくらいあるので、見直しも丸々できると思います。
口コミから予想はできていましたが、問題的にはPing-tなどよりも難しかったです。
2問程度記述式のものがあったり、見たことないような内容の問題も数問出題されます。

試験結果

結果:合格
得点:80点
※合格ラインは70点

実際に受験してみた感想

事前情報通り見たことない問題もあったので、はじめは面食らってしまいました。
記述式の問題に関しては全くこれといった準備はしていませんでしたが、難なく解けるようなレベルだと思います。

一旦回答が終わって見直しする前の時点では「もしかしたらやばいかも…?」と思ってしまいましたが、
問題自体を振り返るとPing-tの内容的に近いものも時々あったので、段々情緒が安定しました。
なにはともあれ無事合格できて今はホッとしています。

一旦資格学習からはなれてアマゾンプライムでアニメを見まくっているところですが、
これを機に定期的に資格受験は継続していきたいなと思っています。
また、会社から資格奨励金も出るのでそれで焼肉でも食べにいこうと思います。

おしまい

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

フロントエンドエンジニアとして6ヶ月働いてコードレビューで指摘されたこと3つ

1. クラス名を統一する

どういうコードを書いたか...

同じ意味を持つクラス名が、コンポーネント1ごとに異なる名称になっていた。
「小さい」バリエーションクラス:is-small, is-minimum
「強調する」バリエーションクラス:is-active, is-on
など...

どういう指摘をされたか

クラス名がバラバラでわかりにくいので統一したほうが良い。名称の違いに意味はあるのか?

それはなぜか

単純に英語翻訳で調べたそれっぽい名前や他のサイトで使われていた名前などをつぎはぎして使ってしまい、自分の作っているWEBサイト内でのルールの統一を意識できていなかったため。
意味のない名称のばらつきがあると、保守の際にコードを見る相手への負担を増やしてしまう可能性がある。

どのように直したか

どの名称がより適切・わかりやすいかを再度考え、同じ意味を持つクラス名は統一するようにした。
また、似たようなバリエーションはコンポーネントごとにバラバラに考えるのではなく、共通した名称を使えないか検討するようにした。

2. コンポーネント単位を意識する。

どういうコードを書いたか...

以下の図のような構成を持つデザインに対し、
サンプル1.png
このようなコードを書きました。

index.html
<ul class="service-list">
  <li class="service-list-item">
    <div class="service-heading-bg">
      <h3 class="service-heading"></h3>
    </div>
    <img class="icon" />
    <div class="service-textbox">
      <p class="service-title"></p>
      <p></p>
    </div>
  </li>
  <!-- <li></li>が複数続く -->
</ul>

どういう指摘をされたか

どこまでが1つのコンポーネントなのか分からない。

それはなぜか

見た目的なHTML構造の切り分けばかりを考え、コンポーネント単位での切り分けを意識できていなかったため。
コンポーネントを「見た目的に近い塊」くらいのふんわりしたものとして捉えていた。
特にこのコードではservice-で続くクラス名が多々あるにも関わらず、そのコンポーネントの基準となるserviceというクラス名がなかったため、より一層「どこまでが1つの...」と思わせてしまった。

どのように直したか

コンポーネントの意味を考え直し、クラス名の命名や構造の切り分けを行った。(実際は例を出してもらったのだが...。)特に今回の場合、以下のような意味付けを再認識しクラスの切り分けを改めて行った。

service-list:serviceが複数ある場合のリスト全体
service-list-item:serviceのリストの中の1つの要素(リストとして並ぶ際の余白などを決める)
service:serviceというコンポーネント本体。serviceで囲まれたHTML構造があればこのコンポーネントが成り立つ。

修正結果

index.html
<ul class="service-list">
  <li class="service-list-item">
    <div class="service">
      <div class="service-heading-bg">
        <h3 class="service-heading"></h3>
      </div>
      <img class="service-image" />
      <div class="service-textbox">
        <p class="service-title"></p>
        <p></p>
      </div>
    </div>
  </li>
  <!-- <li></li>が複数続く -->
</ul>

今だったらこう直すかな...。

index.html
<ul class="service-list">
  <li class="service-list-item">
    <div class="service">
      <div class="service-heading"></div>
      <div class="service-body">
        <img class="service-image" />
        <div class="service-textbox">
          <p class="service-title"></p>
          <p></p>
        </div>
      </div>
    </div>
  </li>
  <!-- <li></li>が複数続く -->
</ul>

3. コンポーネント間に依存関係を持たせない

これはscssについてのレビューです。

どういうコードを書いたか...

aというコンポーネントの中にbというコンポーネントが入る際に、bに余白を持たせたい。
という状況で、以下のような記述を行っていました。

.a {
  // aのスタイルを指定する記述

  .b {
    margin-left: 8px;
  }
}

どういう指摘をされたか

コンポーネントに関するスタイルの指定が分散してしまっており、保守性が下がる。
別のコンポーネントクラスで指定を重ねるのではなく、aのクラス内にバリエーションを持たせる方が良い。

それはなぜか

今のコーディングにしか目が行っていなかったため。
bのスタイルの指定は基本的には近しい場所に書いてあるはずなのに、aというコンポーネント内にbの記述を混ぜることで、bに関わるスタイルの記述をまとめて把握しづらくなる。また、指定を重ねることで、スタイルがどんどん複雑化してしまう。

どのように直したか

複数のコンポーネントを組み合わせてスタイルを指定しない、ことを念頭に置くようにした。
改めて、コンポーネントの間の切り分けを意識するようになった。

修正結果

.a {
  // aのスタイルを指定する記述

  .a-item {
    margin-left: 8px;
  }
}

まとめ

今回「指摘されたこと」を振り返っていて思ったのは「正解」の書き方をしようとして
逆に表面的な部分に捉われていることが多いかな、ということでした。
そういうときほど、レビューできれいにメスが入ります。

しっかり考えつつも、考え込まない!が大事ですね。


  1. (コンポーネント:再利用可能な要素の塊。部品。コンポーネントの単位はBootstrapなどのCSSフレームワークが参考となる。) 

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

cssのfilterプロパティのプレイグラウンドを作ってみた

サイト

https://playcss.dev/filter
image.png

作った所感

filterプロパティには、10の関数があって、実質10個分のプレイグラウンドを合わせたような形になっているので、作るのが非常に面倒くさかった。
10個の関数をならべるとごちゃごちゃしてるので、空白とか大きさの強弱をつけてUIをもう少し見やすくしたほうがいいかもしれない。

あと、画像とSVG版のプレイグラウンドも作るべきかどうか...

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む