- 投稿日:2020-03-29T21:16:31+09:00
読みやすいコードを書きたい!
この記事の趣旨
自分の学習のメモとして残します。
どなたかのお役に立てたら光栄です。こんな方におすすめです
・コードが見づらいと言われる
・初心に返りたい
このような方には何か発見があると思います。読みやすいコードとは?
ズバリ『良いコード』のこと。
良いコードは、他人がそのコードを見た時に短時間で理解できるコードのことを言います。逆に、分かりづらい・理解しづらいコードは解読に時間がかかります。それだけ開発の工数もかかってしまい、効率が良くありません。
では、良いコードの条件・要素を紐解いていきましょう!
●コードの命名に規則を
変数やメソッドは好きなように命名ができます。
ルールがありませんので、個人の好きなようにできます。
特に共同開発の現場などでは、「他人が見てわかる」を意識する必要があります。◎命名のポイント
【目的がわかる単語を使う】
例)new → new_account【汎用的な名前は避ける】
・一時的な変数などは避ける
・可読性を意識して【名前に情報を含める】
大文字、小文字をルールに沿って活用
【誤解されない名前を使う】
・何がしたいかが明確な名前
・説明的に長くなっても良いので、可読性重視
例)read_books → already_read_books●コードレイアウト
プログラムの挙動に影響はないが、可読性を大幅にあげることができる
◎レイアウトのポイント
・整列 :縦列を揃える。イコールの位置など縦が揃うと見やすい
・一貫性 :似たような構造は同じフォーマットに統一できないか検討
・ブロック化 :同じ系統の変数などをまとめてグループ化すること●コメント
・プログラムの動作を説明
・他の開発者がコードを読む際の理解を助ける
※多すぎても読むのに時間がかかるため、簡潔に◎コメントのポイント
・理由をコメントする :なぜそのコードを書いたか
・他の開発者へメモを残す:開発中のメモとして
・実際の例を記入する :コメントでは伝わりづらい時は、コメントとしてコードを記載まとめ
結局大事なことは
「人に対する思いやり」だなぁと。複数人で仕事をする以上、「自分だけ良ければそれで良い」という考えはNG。
誰もが見やすく、仕事をしやすい状況を自分が作り出す意識が大切。そのための知識や技術であると思う。
これからしっかり学んでいきましょう。
- 投稿日:2020-03-29T18:23:16+09:00
Sassでfor文を使ったページローダーのようなものを作る方法
はじめに
Sass記法にはなんとfor文も存在するということで、どういう使い方をするのか一例としてページローダーのようなものをCSSで表現してみたいと思います。
Sassでは他にもif文なんかも使えます。Sassと言ってますが、基本的にはscss記法で書いていきます。そちらの方が個人的には見やすいので。
この記事ではSassについての詳しい解説は行いません。
ちなみに
SassMeisterというサイトで、CSSにコンパイルされた記述も同時に見ながらコードを書くことができるので、サクッと書いてみたい場合はこちらが便利です。
左のSassのスペースにSassまたはscss記法で書いていくと、CSSのスペースに表示されます。Sassのfor文の記載方法
基本的な書き方
scss@for $i from 1 through 5 { nth-child(#{$i}) { animation-delay: -0.3s / $i ; } }
@for
でfor文の宣言をし、$i
で可変する数字部分の変数宣言を行います。ここまでは一般的なfor文とほぼ変わりません。
from 1
through 5
で1〜5までをループするという意味になります。
で、そのnth-child()のカッコ内に変数宣言をした$i
を入れてあげます。
セレクター内や、文字列内に変数を使う場合は#{}
で変数を囲む必要があります。
プロパティの値にその変数を使用する場合はそのまま使えます。scss@for $i from 1 to 5 { nth-child(#{$i}) { animation-delay: -0.3s / $i ; } }ちなみに
from 1
to 5
という書き方をすることもでき、こちらは5を抜いた1〜4までという意味になります。ページローダーっぽいやつの作り方
Sassのfor文と、animationプロパティを用いて作っていきます。
さっそくですが、こんな感じのやつです。
See the Pen oNXJRPr by fumu (@fumu238) on CodePen.
以下、簡単な解説。
html<div class="three-dot"> <div></div> <div></div> <div></div> <div></div> </div>htmlは特になんてことないですね。ローダー部分の要素となるdivを4つ作り、親要素の中に入れておきます。
scss.three-dot { text-align: center; & div{ display: inline-block; width: 18px; height: 18px; background-color: black; border-radius: 50%; animation-name: delay; animation-duration: 1.4s; animation-iteration-count: infinite; } }まず4つの子要素を
display:inline-block
で横並びにし、黒い●状にします。
これにあとは動きをつけるためにscss@keyframes delay { 0% { transform: scale(0); } 40% { transform: scale(1); } 80% { transform: scale(0); } 100% { transform: scale(0); } }
@keyframes
を使用して指定をしていきます。0%〜100%までの中でどような変化をするか%を指定して細かく指定できます。
ここではtransform:scale()
を用いて0%~40%で開いて、あとは閉じる。みたいな動きにします。
animation-name
で@keyframes
の名前を指定し、animatino-duration
で何秒かけてその動作を行うか指定し、animation-iteration-count: infinite;
でそれを無限に行うように指定します。See the Pen eYNbwvX by fumu (@fumu238) on CodePen.
そうすると、この段階では4つの●が同時にちっちゃくなったり大きくなったりします。
ここでfor文の出番です。scss.three-dot { text-align: center; & div{ display: inline-block; width: 18px; height: 18px; background-color: black; border-radius: 50%; animation-name: delay; animation-duration: 1.4s; animation-iteration-count: infinite; @for $i from 1 through 3 { &:nth-child(#{$i}) { animation-delay: -0.4s + $i * 0.1; } } } }子要素のdivのn番目にそれぞれCSSを追加するための
:nth-child
でfor文を作ります。
今回は4つdivがあるので、その1〜3つめにanimation-delay
をマイナスの値で設定します。マイナスでdelayを設定すると、delayせずむしろ早く変化を始めることになります。
そしてその設定した値を変数を使って計算するとループの1回目は
-0.4s + 1 * 0.1 = -0.3s
ループの2回目は-0.4s + 2 * 0.1 = -0.2s ...
となり、数が増えるたびに値が変わっていくことになります。
CSSにコンパイルされるとこう。
cssnth-child(1) { animation-delay: -0.3s; } nth-child(2) { animation-delay: -0.2s; } nth-child(3) { animation-delay: -0.1s; }これで0.1秒ごとに変化をつけることができるようになり、見本のような動きになります。
ちなみに。for文の中で計算を行いましたが、Sassで四則演算を行うときには単位を気にせず計算することができます。
px
なんかも単位をつけたまま計算することができるので、余計な事を考えなくて済みますね。おわりに
以上、Saasでfor文を使ったページローダーっぽいものの作り方でした。
他にもtransformを使って回転させたり、丸ではなく四角で作ったり、要素を重ねたりと、いろんなパターンが作れそうです。
- 投稿日:2020-03-29T18:13:22+09:00
親要素の中で子要素をそれぞれ左寄せと右寄せに
親要素に対して
display: flex;
justify-content: space-between;
- 投稿日:2020-03-29T17:59:19+09:00
CSSのプロパティを自動で並べ替える方法
複数人で開発をしていると
- marginとpaddingってどちらを先に書けば良いだろう?
- position指定ってtop -> right -> bottom -> leftの順が良いのかな?
などの話が出ることはありませんか?
自分は結構質問されるのですが、個人的にはカスケーディングがスタイルに影響を与えない場面ではどんな順番でも良いと思っています。
しかし、ルールがあればミスが減り、レビューがしやすくなるのも事実。
というわけで自動でプロパティの並び順を変更できる設定を作っていきましょう。
Prettierのインストール
yarn add prettier -Dまず初めにPrettierをインストールします。
Prettierはコードフォーマッターで、予め指定したルールに沿ってコードを整形してくれます。stylelintのインストール
yarn add stylelint -D次にstylelintをインストールします。
stylelintはリンターで、CSSやSCSSなどのエラー回避や書式の統一に役立ちます。stylelint-config-prettierのインストールと設定
yarn add stylelint-config-prettier -D.stylelintrc{ "extends": ["stylelint-config-prettier"] }stylelint-config-prettierはPrettierと競合するルールをオフにしてくれます。
ルールが競合するとお互いがお互いをエラー/書式のミスとして認識しておかしなことになってしまうためインストールが必要です。stylelint-prettierのインストールと設定
yarn add stylelint-prettier -D.stylelintrc{ "extends": ["stylelint-config-prettier"], "plugins": ["stylelint-prettier"], "rules": { "prettier/prettier": true } }stylelint-prettierはPrettierをstylelintのルールとして実行し、エラーを教えてくれたり修正したりに使います。
.stylelintrc
の中でプラグインの有効化とルールの追加をします。なお、stylelint-prettierをインストールしたからとPrettierやstylelintが自動でインストールされるわけではありません。
そのため前の項で手動でインストールを行っています。また、上記の
.stylelintrc
は実は次のように短く書けます。.stylelintrc{ "extends": ["stylelint-prettier/recommended"] }
stylelint-prettier/recommended
が
stylelint-config-prettier
をextendstylelint-prettier
プラグインを有効化prettier/prettier
ルールを有効化してくれるためです。
stylelint-orderのインストールと設定
yarn add stylelint-order -D.stylelintrc{ "extends": ["stylelint-prettier/recommended"], "plugins": ["stylelint-order"], "rules": { "order/properties-alphabetical-order": true } }stylelint-orderはその名の通りプロパティの並び順ルールについてのパッケージです。
並び順は色々なルールがあるようですが、自分は一番明快だろうとアルファベット順を選択しました。準備完了、あとはコマンドを叩くだけ
yarn run stylelint '**/*.css' --fix上記のようなコマンドを叩くとCSSの並び順を修正してくれます。
'**/*.css'
の部分はこの書き方だと全てのCSSファイルへの修正が走りますが、具体的に'src/style/somepage.css'
のようにしてもOKです。補足
実際にstylelintを使う場面ではほぼ間違いなくstylelint-config-standardなど土台となるルールセットも一緒に使うと思いますが今回は割愛しています。
リンク一覧
- 投稿日:2020-03-29T16:58:06+09:00
【曖昧さ回避】ブラウザレンダリングにおける「ファイルの読み込み」が意味するものとは
「ファイルの読み込み」とは
ブラウザレンダリングの仕組みを解説するサイトや書籍には、「ファイルを読み込んで〜」のような説明が多くあります。
自分がレンダリング工程を勉強しているときに、この「読み込み」という言葉がファイルのDownload(転送)を指すのか、ファイルのParse(解析)を指すのか、はたまたレンダリング全体のことを言っているのか、説明する場面によって意味が変わる曖昧な言葉だなーと感じていました。ここではブラウザレンダリングの仕組みについて、1.HTMLのみ、2.HTMLとCSS、3.HTMLとJavaScript、4.HTMLとCSSとJavaScriptの4パターンに分けて、レンダリングフローに定義された言葉に当てはめながら説明していきたいと思います。
(検証環境:Google Chrome バージョン: 80.0.3987.87)
ブラウザレンダリングの仕組みの大枠
ブラウザレンダリングのフローは大きく4つの工程に分けられ、それぞれの工程は更にいくつかの細かい工程に分けられます。
(参考:Webフロントエンド ハイパフォーマンス チューニング -久保田 光則 (著) )
- Loading(データのダウンロード・解析)
- Download
- Parse
- Scripting(JSの実行)
- Rendering(スタイルの計算、当て込み)
- Calculate Style
- Layout
- Painting(描画)
- Paint
- Rasterize
- Composite Layers
図を見ていると全ての工程がシリアル(直列)に進んでいくように誤解しやすいのですが、実際はそうではありません。
レンダリングエンジンがページ表示を最適化する中で、部分的にでも準備ができた段階で、都度次の工程に進むこともあります。本記事では主にLoading(Download、Parse)とScriptingの工程に関して、ファイルごとにどのように影響を及ぼし合い、レンダリングの処理順が決まっているかについて説明します。
RenderingやPaintingの工程を含むブラウザレンダリング全体の仕組みについては以下記事が詳しいです。
フロントエンジニアなら知っておきたいブラウザレンダリングの仕組みをわかりやすく解説! | LeapIn1.HTMLのみ
はじめに外部ファイル「読み込み」記述が一切ない純粋なHTMLファイルについて、
ブラウザ検索バーにURLを入力し、HTTPプロトコルで通信してページを表示する場合を考えます。
(参考:ネットワークやTCP/IPやHTTPの基本(初学者向け) - Qiita)レンダリングの工程としては、まずHTMLのDownloadが始まりますが、
ここでのポイントは、サーバからHTMLファイルなどのリソースが転送される手法は0か1の転送ではなく、
セグメントに分割しながら転送されるということです。
(どのくらいまとめて送るのかについてはサーバサイドで制御するようです)前提として、ブラウザはUX向上のため画面に何も表示されていない時間を短くするように動きます。
よって全てのHTMLDownloadが完了していなくても、転送されたHTMLセグメントを元にParse(DOMツリー構築)や後続の処理が進み、準備ができたDOMから画面描画が始まります。
上記はChrome DevToolsのNetworkパネルであり、一つのHTMLファイルをダウンロード完了するまでの解析図です。(テスト用にサーバサイド(PHP)でファイルの転送や解析速度を調整しています)Waiting(TTFB:Time To First Byte)とはファイル転送リクエストを送ってからクライアント側で最初のデータを受け取るまでにかかる時間(主にサーバサイドの処理時間)であり、Content Downloadとは最初のデータを受け取ってから全てのデータを受け取りきるまでにかかる時間です。
解析グラフによるとContent Downloadに合計2sかかっていますが、その間も転送されてきているデータを元に別の処理(Parse、Rendering、Painting)が都度進んで描画が始まっており、それは同Performanceパネルで解析することができます。↓
データを受け取る(Receive Data)たびに、HTMLParse(DOM構築)のフェーズを経て、Composite Layersまでの描画工程を完了していることが分かります。このように準備ができたところから都度描画が行われることで、First Paint(画面に最初になにかしらが描画されタイミング)や、First Meaningful Paint(画面に最初にユーザーに意味のある表示がされたタイミング)などの表示タイミング差が存在します。
参考:Ace the Lighthouse Audit: Best Practices for Consistent Interactivity | Lumavate
2.HTMLとCSS
head要素
の中のlink要素
に外部CSS「読み込み」記述がある場合を考えます。HTML<!DOCTYPE html> <html> <head> <link rel="stylesheet" href="style.css" /> </head> <body> <!-- bodyの中身 --> </body> </html>CSSのDownload
この場合も、まずHTMLのDownload、Parseが始まり、解析途中で
link要素
を見つけた段階でCSSのDownloadが始まります。↓
CSSのDownloadはHTMLのParseをブロックしないので、CSSDownload中もHTMLParseが並行して進みます。
そしてその先に再び外部CSS「読み込み」記述ががあれば、同時に複数のCSSDownloadが始まります。ただし、モダンブラウザでは(同じドメインの)TCP接続は同時に6本までという制限があるため、7本目以降の接続は前の接続の終了を待ってからとなります。
見ての通りこれではダウンロードしたいファイルが多いほどページ表示速度が遅くなってしまいます。そのため、対応策としてファイルを可能な限りまとめてリクエスト必要数を抑えたり、CDNなどを利用してあえて別ドメインから接続することでスループットを上げたり、一つのTCP接続で同時に複数のリクエスト/レスポンスを処理できるhttp/2プロトコルで通信するなどの手法が存在します。
参考:そろそろ知っておきたいHTTP/2の話 - Qiita
CSSのParse
CSSもHTMLと同様にDownloadの次の工程として、Parse(CSSOMの構築)の工程があります。
考慮すべき注意点は以下です。
- CSSParseは見かけ上はHTMLParseと並行して行われる。
- HTMLは描画工程に進もうとするDOMの、直前までに記載されているCSSのLoading(Download、Parse)が完了しない限り、Renderingフローに進まない。(描画処理が行われない)
HTMLParseとCSSParseはどちらもレンダリングエンジンのmainスレッドで行われますが、mainスレッドでは同時に一つの処理しか行えないため、それぞれの処理が同時に走ることはありません。
ですが、HTMLParseのアイドル時間などにCSSParseが進むため、見かけ上は2つが並行して行われているように見えます。
(そもそもCSSParseにかかる時間はブラウザレンダリング全体の時間からすると極めて短く、議論に上がりにくい部分のようです。)また、CSSのLoadingが進行中の場合は、たとえHTMLParseが先に完了していてもRenderingなどの次の工程に進まず、結果として画面描画が行われません。
これはブラウザがFOUC(Flash of Unstyled Contentの略。スタイルがついていないコンテンツが一瞬表示されること)を防ぐために、CSSParseの完了を待ってスタイルが適応された画面描画を行おうとするためです。
上記Performanceパネル解析図を見ても、Finish Loading(CSSParseの完了)まで、Calculate StyleなどのRendering工程に進んでいない(画面描画が行われていない)ことが分かります。3.HTMLとJavaScript
以下のように
head要素
の中にscript要素
を記述して、外部JavaScriptファイルを「読み込む」場合を考えます。HTML<!DOCTYPE html> <html> <head> <script src="main.js"></script> </head> <body> <!-- bodyの中身 --> </body> </html>JSのDownloadとScripting
HTMLParseが始まって
script要素
に到達するとJSのDownloadが始まります。
その時に重要なポイントが、JSのDownloadとScripting(実行)はHTMLParseをブロックするということです。一度JSのDownloadが始まると、ダウンロードしたJSのScripting工程が完了しない限り、それ以降のHTMLParseが行われません。
これが、JSの記述はbodyの最後に記述するべきと言われる理由の一つです。
上記図より、Send RequestでJSDownloadが始まると、Evaluate Script工程が完了するまでHTMLParseが行われていないことが分かります。async属性とdefer属性
script要素
によるJSの「読み込み」記述はそれ以降のHTMLParseをブロックしますが、script要素
にasync
やdefer
の属性をつけることによってJSのDownloadを非同期に行い、HTMLParseと同時に処理することができます。HTML<script src="main.js" async ></script> <!-- もしくは --> <script src="main.js" defer ></script>以下は先程と同じ記述で、
defer属性
を使用したときのPerformanceパネルの解析結果です。
JSのDownloadが開始(send Request)しても、HTMLParseがブロックされずに先の工程に進み、最終的にComposite Layersまで完了して画面描画が行われているのが分かります。
その後JSのDownloadが完了した段階で、Scripting(Evaluate Script)処理が行われています。参考:scriptタグに async / defer を付けた場合のタイミング - Qiita
4.HTMLとCSSとJavaScript
CSSとJavaScriptの両方の「読み込み」記述を書く場合です。
以下のようにlink要素
の直下にscript要素
を入れてみます。HTML<!DOCTYPE html> <html> <head> <link rel="stylesheet" href="style.css" /> <script src="main.js"></script> </head> <body> <!-- bodyの中身 --> </body> </html>CSSDownloadはHTMLParseをブロックしないため、HTMLParseは
script要素
の記述に到達しJSのDownloadが始まります。
先程「HTMLは直前までのCSSLoading(Download、Parse)が完了していない限り、Renderingフローに進まない」と説明しましたが、実は同様にJSも直前までのCSSLoading(Download、Parse)が完了していない限り、Scriptingの工程に進まない性質があります。つまりこの場合、CSSよりもJSのほうが速くDownloadが完了したとしても、CSSParseが完了するまでScriptingが待機状態になるということです。
↑JSのほうがCSSよりも1s速くDownloadが完了していますが、
↑CSSのLoading(Download、Parse)完了を待ってから、Scripting(Evaluate Script)処理が実行されていることが分かります。参考:DOMContentLoaded周りの処理を詳しく調べてみました - Qiita
ブラウザのプリロード機能
以下のようにJSの「読み込み」記述をCSSよりも前に書いた場合を考えます。
HTML<!DOCTYPE html> <html> <head> <script src="main.js"></script> <link rel="stylesheet" href="style.css" /> </head> <body> <!-- bodyの中身 --> </body> </html>
defer属性
やasync属性
がついていないscript要素
による外部JSファイルの「読み込み」なので、JSのDownload、Scriptingが完了するまでそれ以下のHTMLParseが進まない、つまりCSSDownloadも進まないはずです。しかし、モダンブラウザではその限りではありません。
NetWorkパネルを見てみると、JSとCSSのDownloadが同時に行われていることが分かります。
実はChromeなどのモダンブラウザには、HTMLParseが進んでいない部分についてもDownloadが必要な記述がないか確認し、もしあれば事前にそのファイルのDownloadを開始する機能があります。(Preload Scanner)よってこの場合も、ブラウザはJSのDownload中にその先にあるCSSの「読み込み」記述を読み取り、CSSDownloadも同時に進めることでレンダリングを高速化しているのです。
※Preload Scanner機能で事前処理できるのはDownloadの工程だけです。ParseやScriptingの工程は本来のレンダリングフローに沿って行われます。
参考:rel="preload"を極めるために必要な2種類のプリロード機能 | Raccoon Tech Blog
まとめ
- HTMLはセグメントごとにDownloadが行われ、都度Parseなどの先の工程に進む
- CSSのDownloadはHTMLのParseをブロックしない
- CSSのParseは見かけ上はHTMLParseと並行して行われる
- HTMLは直前までのCSSLoading(Download、Parse)が完了していない限り、Renderingの工程に進まない
- JSのDownloadとScripting(実行)はHTMLのParseをブロックする
- JSも直前までのCSSLoading(Download、Parse)が完了しない限り、Scriptingの工程に進まない
誤った解釈等ございましたら、ご教授お願いいたします。。
参考
- Webフロントエンド ハイパフォーマンス チューニング -久保田 光則 (著)
- フロントエンジニアなら知っておきたいブラウザレンダリングの仕組みをわかりやすく解説! | LeapIn
- ネットワークやTCP/IPやHTTPの基本(初学者向け) - Qiita
- Ace the Lighthouse Audit: Best Practices for Consistent Interactivity | Lumavate
- そろそろ知っておきたいHTTP/2の話 - Qiita
- scriptタグに async / defer を付けた場合のタイミング - Qiita
- DOMContentLoaded周りの処理を詳しく調べてみました - Qiita
- rel="preload"を極めるために必要な2種類のプリロード機能 | Raccoon Tech Blog
- フロントエンドのパフォーマンスを徹底解説!ブラウザの気持ちで理解するHTML/Javascript/CSSの話 | Raccoon Tech Blog
- 投稿日:2020-03-29T16:22:09+09:00
【CSS & JS】超簡単。ハンバーガーをクリックで×に変える&メニューをスライドアウトさせる方法
備忘録です。
ハンバーガーメニューをクリックすると、×印に変えるのってどうやるんだろう〜CSSでつくる方法もあるらしいけど、どうやるんだろう。密かにずっと気になっていたので調べてみました。
JavaScriptも使いますが、決してややこしいことはしなくていい方法を見つけました。
ここでは二つのことをします。
❶ハンバーガーにクリックすることで×印に変える
❷メニューを画面の右側からスライドアウトさせる。まずはHTMLから。
HTML
<!DOCTYPE html> <html lang="en"> <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" /> <link rel="stylesheet" href="css/styles.css" /> <script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous" ></script> <title>Slide Out Menu</title> </head> <body> <header> <nav> <div class="burger-menu-icon">//①ハンバーガーのdivをつくる <input type="checkbox" id="burger" />//②Toggleするためにはcheckboxを書く!ここがカギ! <label for="burger">//③label forはinputのidとそろえる。 <div class="burger-icon"> <span></span> <span></span> <span></span> </div>//④labelのなかにハンバーガーアイコンを入れましょう。 </label> <div class="slideoutMenu">//⑤スライドアウトさせるメニューは、burger-menu-iconのdiv内におさめます。 <div class="opacity"></div> <div class="menu"> <ul> <li><a href="#">Home</a></li> <li><a href="#">About</a></li> <li><a href="#">Contact</a></li> <li><a href="#">Design</a></li> <li><a href="#">Style</a></li> <li><a href="#">Reviews</a></li> </ul> </div> </div> </div> </nav> </header> <script src="script.js"></script> </body> </html>ポイント❶
toggleするにはinput type="checkbox"
を使うポイント❷
今回はハンバーガーアイコンをクリックすることで、メニューを引っ張り出したいです。なのでハンバーガーアイコンは、<label for="burger"></label>
のなかに入れましょう。通常であればcheckboxをチェックしなければ、checkboxにチェックはつきませんが、label forというものを付け加えると、label forの中身をクリックするだけでcheckboxにcheckがつけられます。ただし一点。label for="burger"
と、input id="burger"
labelをinputと紐づけるには、この二つをそろえる必要があります。inputは必ずidで指定します。ポイント❸
ハンバーガーアイコンと隠しているメニューは、同じdiv内に入れる。(この場合は.burger-menu-icon
)SCSS
.burger-icon { display: block; z-index: 11; } .burger-icon span { //ここでburger-iconをつくる display: block; background: #000; //background-colorではなく、backgroundで指定 width: 50px; height: 5px; margin-bottom: 10px; margin-left: 90%; cursor: pointer; position: relative; top: 0; } input#burger { //labelここでcheckboxを消す display: none; } .burger-icon.open span:nth-child(2) { //クリックすると'open'というクラスがtoggleされるよう、JSに記述しています。つまり、これはハンバーガーをクリックするとハンバーガーの2本目の線が消えるという記述です。 width: 0; opacity: 0; } .burger-icon.open span:nth-child(1) { //これはハンバーガーをクリックするとハンバーガーの1本目の線が45度回転し、上から15px下方向にずらすという記述です。 transform: rotate(45deg); top: 15px; } .burger-icon.open span:nth-child(3) {//これはハンバーガーをクリックするとハンバーガーの3本目の線が-45度回転し、15px上方向にずらすという記述です。 transform: rotate(-45deg); top: -15px; } .slideoutMenu { transform: translateX(100%); //メニューを右に100%ずらすことで、画面から消す。 z-index: -1; position: fixed; top: 0; left: 0; width: 100%; height: 100%; display: flex; transition: 0.3s; animation: slideOut 0.3s; .opacity, .menu { width: 50%; background-color: #5d348c; ul { list-style: none; li { padding-bottom: 3rem; } li a { text-decoration: none; font-size: 3rem; color: #ea5c5d; text-transform: uppercase; } } } .opacity { background-color: #ea5c5d; opacity: 0.7; } } @keyframes slideOut { //ここでスライドの動作をつくります。(slideIn、のほうがふさわしかったかも T_T ) 0% { transform: translateX(100%); } 50% { transform: translatex(50%); } 50% { transform: translatex(0%); } } input:checked ~ .slideoutMenu { //これがツワモノ!!!詳細は【覚えておきたいポイント3】で。 transform: translateX(0%); }覚えておきたいポイント❶
<input>
タグのあとに<label for="burger">
を付け足しておけば、label
タグ内の要素をクリックすることでcheckboxをチェックできるようになります。覚えたいおきたいポイント❷
.burger-icon.open span:nth-child(3), .burger-icon.open span:nth-child(1)
ではハンバーガーの上の線と下の線を回転させ、top:〜
で位置をずらしています。topの位置をずらすには、.burger-icon span
にposition: relative; top: 0;
と書かないと効かないので注意です。覚えたいおきたいポイント❸
最後にあるinput:checked ~ .slideoutMenu
を書くことで、メニューが右側から画面にスライドインしてくれます。
input:checked
は、「チェックボックスがcheckされていたら……」という意味です。~
は、兄弟要素を取得したいよ〜という意味合いを持つ記号です。input
と.slideoutMenu
はどちらともburger-menu-icon
の子要素なので、兄弟要素に値します。~
がないと効かないので注意です。JS
$(".burger-icon").click(function() { $(this).toggleClass("open"); });JSではシンプルに、「
.burger-icon
のクリックで、open
というclassをtoggleしてね」と伝えているだけです。地味に時間がかかりますが、、一番わかりやすいかなと感じました。こんなに簡単に実装できるとは!animationがわかると、CSSは一層おもしろみが増す気がします。
- 投稿日:2020-03-29T16:22:09+09:00
【CSS & JS】超簡単。ハンバーガーアイコンをクリックして×に変える&メニューをスライドアウトさせる方法
備忘録です。
ハンバーガーメニューをクリックすると、×印に変えるには……CSSでつくる方法もあるらしいけど、どうやるんだろう。密かにずっと気になっていたので調べてみました。
JavaScriptも使いますが、決してややこしいことはしなくていい方法を見つけました。
ここでは二つのことをします。
❶ハンバーガーにクリックすることで×印に変える
❷メニューを画面の右側からスライドアウトさせるまずはHTMLから。
HTML
<!DOCTYPE html> <html lang="en"> <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" /> <link rel="stylesheet" href="css/styles.css" /> <script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous" ></script> <title>Slide Out Menu</title> </head> <body> <header> <nav> <div class="burger-menu-icon">//①ハンバーガーのdivをつくる <input type="checkbox" id="burger" />//②Toggleするためにはcheckboxを書く!ここがカギ! <label for="burger">//③label forはinputのidとそろえる。 <div class="burger-icon"> <span></span> <span></span> <span></span> </div>//④labelのなかにハンバーガーアイコンを入れましょう。 </label> <div class="slideoutMenu">//⑤スライドアウトさせるメニューは、.burger-menu-iconのdiv内におさめます。 <div class="opacity"></div> <div class="menu"> <ul> <li><a href="#">Home</a></li> <li><a href="#">About</a></li> <li><a href="#">Contact</a></li> <li><a href="#">Design</a></li> <li><a href="#">Style</a></li> <li><a href="#">Reviews</a></li> </ul> </div> </div> </div> </nav> </header> <script src="script.js"></script> </body> </html>ポイント❶
toggleするには
input type="checkbox"
を使うポイント❷
今回はハンバーガーアイコンをクリックすることで、メニューを引っ張り出したいです。なのでハンバーガーアイコンは、
<label for="burger"></label>
のなかに入れましょう。通常であればcheckboxをチェックしなければ、checkboxにチェックはつきませんが、label forというものを付け加えると、label forの中身をクリックするだけでcheckboxにcheckがつけられます。ただしlabel for="burger"
と、input id="burger"
labelをinputと紐づけるには、この二つをそろえる必要があります。inputは必ずidで指定します。ポイント❸
ハンバーガーアイコンと隠しているメニューは、同じdiv内に入れる。(この場合は
.burger-menu-icon
)SCSS
.burger-icon { display: block; z-index: 11; } .burger-icon span { //ここでburger-iconをつくる display: block; background: #000; //background-colorではなく、backgroundで指定 width: 50px; height: 5px; margin-bottom: 10px; margin-left: 90%; cursor: pointer; position: relative; top: 0; } input#burger { //labelここでcheckboxを消す display: none; } .burger-icon.open span:nth-child(2) { //クリックすると'open'というクラスがtoggleされるよう、JSに記述しています。つまり、これはハンバーガーをクリックするとハンバーガーの2本目の線が消えるという記述です。 width: 0; opacity: 0; } .burger-icon.open span:nth-child(1) { //これはハンバーガーをクリックするとハンバーガーの1本目の線が45度回転し、上から15px下方向にずらすという記述です。 transform: rotate(45deg); top: 15px; } .burger-icon.open span:nth-child(3) {//これはハンバーガーをクリックするとハンバーガーの3本目の線が-45度回転し、15px上方向にずらすという記述です。 transform: rotate(-45deg); top: -15px; } .slideoutMenu { transform: translateX(100%); //メニューを右に100%ずらすことで、画面から消す。 z-index: -1; position: fixed; top: 0; left: 0; width: 100%; height: 100%; display: flex; transition: 0.3s; animation: slideOut 0.3s; .opacity, .menu { width: 50%; background-color: #5d348c; ul { list-style: none; li { padding-bottom: 3rem; } li a { text-decoration: none; font-size: 3rem; color: #ea5c5d; text-transform: uppercase; } } } .opacity { background-color: #ea5c5d; opacity: 0.7; } } @keyframes slideOut { //ここでスライドの動作をつくります。(slideIn、のほうがふさわしかったかも T_T ) 0% { transform: translateX(100%); } 50% { transform: translatex(50%); } 50% { transform: translatex(0%); } } input:checked ~ .slideoutMenu { //これがツワモノ!!!詳細は【覚えておきたいポイント3】で。 transform: translateX(0%); }覚えておきたいポイント❶
<input>
タグのあとに<label for="burger">
を付け足しておけば、label
タグ内の要素をクリックすることでcheckboxをチェックできるようになります。覚えたいおきたいポイント❷
.burger-icon.open span:nth-child(3), .burger-icon.open span:nth-child(1)
ではハンバーガーの上の線と下の線を回転させ、top:〜
で位置をずらしています。topの位置をずらすには、.burger-icon span
にposition: relative; top: 0;
と書かないと効かないので注意です。覚えたいおきたいポイント❸
最後にある
input:checked ~ .slideoutMenu
を書くことで、メニューが右側から画面にスライドインしてくれます。
input:checked
は、「チェックボックスがcheckされていたら……」という意味です。~
は、兄弟要素を取得したいよ〜という意味合いを持つ記号です。input
と.slideoutMenu
はどちらともburger-menu-icon
の子要素なので、兄弟要素に値します。~
がないと効かないので注意です。JS
$(".burger-icon").click(function() { $(this).toggleClass("open"); });JSではシンプルに、「
.burger-icon
のクリックで、open
というclassをtoggleしてね」と伝えているだけです。やりかたは何通りもあると思うのですが、個人的にはこれが一番わかりやすいかなと感じました。