前提
今年8月末に、ゼロからHTMLに取り組み始めました。
黒澤さん(@kurokurosawa)によるウェビナー「YoshiTech 会津わろ法則」Round2 の修了生です。
黒澤さんが提唱する「学んだことをQiitaにアウトプットする取り組み」を、少しずつ実践しています。
現状としては、HTML/CSS の基礎についての学習が一区切りついたので、Bootstrap の学習に入っています。
Bootstrap について一区切りついたら、次はJavaScript に進む予定です。
Udemyを利用して学習しています。
現在受講を進めている講座は、
・ウェブ開発入門完全攻略コース - プログラミング をはじめて学び創れる人へ!未経験から現場で使える開発スキルを習得!
・[HTML/CSS/JavaScript] フロントエンドエンジニアになりたい人の Webプログラミング入門
の二つです。
Bootstrap を用いたコードで、「#」を書き忘れてしまいました
Bootstrap を使って、画面幅が狭くなったときに出現する「ハンバーガーメニュー」のコードに取り組んでいた時のことです。
(画面幅が狭くなるとこうなって・・・)
↓
↓
(右側のボタンを押すとこうなるやつです)
こうしたハンバーガーメニューを作ろうと、次のコードを書きました。
<nav class="navbar navbar-expand-lg navbar-light" style="background-color: rgb(194, 226, 247);">
<a class="navbar-brand" href="#">ナビゲーションバー</a>
<button class="navbar-toggler" type="button"
data-toggle="collapse" data-target="NavbarSupportedContent"
aria-controls="NavbarSupportedContent" aria-expanded="false"
aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span></button>
<div class="collapse navbar-collapse" id="NavbarSupportedContent">
<ul class="navbar-nav">
<li class="nav-item"><a class="nav-link" href="#">ホーム</a></li>
<li class="nav-item"><a class="nav-link" href="#">ブログ</a></li>
<li class="nav-item"><a class="nav-link" href="#">ギャラリー</a></li>
</ul>
</div>
</nav>
もちろん、自分でゼロから書いているわけではありません。
Udemy の講座を見ながら、ハンズオン形式の「手取り足取り状態」で書きました。
にもかかわらず・・・エラー発生です。
どんなエラーかというと、ハンバーガーメニューが開いてくれません。
ハンバーガーメニューのボタン自体は表示されるのですが、いくらボタンをクリックしても反応してくれないのです。
結論から言うと、button タグ内の data-target 属性の記述に誤りがありました。
正しくは「data-target="#NavbarSupportedContent"」と書かなければならないのに、「#」を書き忘れていたのです。
書き忘れただけならまだしも・・・
こうした「書き忘れ」自体は、つまるところヒューマンエラーです。
もちろん間違いに対して開き直るのは禁物ですが、かといってヒューマンエラーを根絶するのも不可能でしょう。
大切なのは、ヒューマンエラーの発生を見越しつつ、リカバリーする体制をととのえておくことだと思います。
その意味で、今回の件では「書き忘れ」以上に深刻な問題がありました。
というのも、この書き忘れを見つけるのに、とても時間がかかってしまったのです。
HTML/CSS のコードを書くのにもだいぶ慣れてきて、自分の中では「エラーへの対処法」がそれなりに固まっていたところでした。
もしエラーが発生しても、
・スペルミス
・半角スペースの欠如
・タグ類の閉じ忘れ(特にCSSの「;」の書き忘れ)
・使用する要素や属性の取り違え
・ネスト構造の間違い
といった点に注意してコードを見返せば、エラーの原因は見つかるものだと思っていたのです。
そのやり方が、今回の「#」の書き忘れについては通用しませんでした。
なぜなら、「#」の意味を理解できていなかったからです。
意味を考えない「丸暗記」には限界がある
今回のミスについて、
「data-target 属性について記述する際には、# が必要!」
と割り切って丸暗記してしまうのも、ひとつの対処法かと思います。
はじめのうちは、あえて丸暗記する。
そのうえで、たくさんコードを書きながら、手に覚えさせてしまう。
・・・もちろん、こうしたアプローチも必要です。
ただ、それだけに頼っていると、膨大な時間がかかってしまいます。
そこで、手を動かすことに加えて、「意味を考える」ことが大事になってくるのではないでしょうか。
実際、私はHTML/CSSの学習を始めて、まだそれほど時間が経っていません。
それでも、基礎的なコードの書き方をある程度習得できています。
それは、手を動かしてコードを書くと同時に、コードの意味を考えていたからだと思うのです。
(視聴しているUdemy 講座が、質の高いレクチャーをしてくれるおかげです)
意味を考えずに、ただ丸暗記しようとしていたら、何一つ習得できていなかったことでしょう。
なので今回のミスについても、「# の意味を考える」ことで道が開けるのではないかと考えました。
というわけで、「#」について考えてみました
そこで、「#」がコードの中でどんな役割を果たすのか、自分なりに考えていきたいと思います。
情報をリンクさせるためのものっぽい
今回のコードで「#」が必要になった data-target 属性。
この属性の役割は、「ハンバーガーメニューを開いたときに出てくる情報を指定する」ということだと思います。
つまり、「ハンバーガーメニューのボタン」と「開いたメニューに表示される情報」をリンクさせるための属性です。
「#」をリンクに使う例として思い浮かぶもの
こうした「#」が出てくる例としては、ページ内リンクが思い浮かびます。
<body>
<p>(本文1)</p>
<p>電話番号は<a href="#phone_number">こちら</a>をクリック</p>
<p>(本文2)</p>
<p id="phone_number">電話番号は〇〇〇</p>
</body>
そういえば、id 属性を付加した要素に CSS をあてるときにも、「#」を使いますよね!
#phone_number{
color:red;
border:solid 1px black;
}
似たような例でも「#」を使わない場合が・・・
一方、似たような場面なのに「#」を使わない例も思い浮かびます。
たとえば、外部サイトにリンクを張る場合。
<body>
<p>(本文1)</p>
<p>お店のホームページは<a href="https://〇〇〇">こちら</a>をクリック</p>
<p class="background_color_red">(注意書き1)</p>
<p>(本文2)</p>
<p class="background_color_red">(注意書き2)</p>
</body>
また、class 属性を付加した要素に CSS をあてるときには、「#」ではなく「.」を使います。
.background_color_red{
background-color:red;
}
あるいは、HTMLファイルにCSSスタイルシートを読み込む際にも、「#」は使いません。
<link rel="stylesheet" href="css/style.css">
・・・なぜ「#」を使う場合とそうでない場合に分かれるのでしょう?
「#」を使う場合のポイント1 「ファイル内の特定箇所へのリンク」
ヒントを求めて Web をさまよっていると、とても参考になる記事を見つけました。
ハイパーリンクを提供する | The Web KANZAKI
この記事の中で、ページ内リンクの例として、次のようなコードが挙げられています。
<a href="#detail">このファイル内の詳細へ</a>
そして、直後に次のような注意書きが書かれています。
×よくある間違い:#を忘れると、「detail」という名前のファイルを探そうとしてNot Foundエラーになります。
「#」がなければ、ファイル名と誤解されてしまう・・・
この注意書きが、とても大きなヒントになってくれました!
つまり、まずは次のように考えるとよいのだと思います。
1. リンク先としてファイル全体を指定するときは、「#」は不要
2. リンク先としてファイル内の特定箇所を指定するときは、「#」を使う
2-1 同一ファイル内の特定箇所を指定するときは「#〇〇」
2-2 外部ファイル内の特定箇所を指定するときは「ファイル名#〇〇」
こう考えれば、外部リンクやCSSスタイルシートを読み込む際には「#」が不要で、ページ内リンクには「#」が必要になる理由が分かります。
また、そもそもの発端である「data-target="#〇〇"」の意味についても、だいぶハッキリしてきます。つまり、
【ハンバーガーメニューが開いたときに出てくるようにしたいのは、同一ファイル内の特定箇所にある情報。だからこそ、「#」を書く必要がある】
というわけです。
ここまでイメージできるようになれば、data-target 属性に「#」を書き忘れてエラーが発生した場合にも、リカバリーにかかる時間を短縮できそうです。
「#」を使う場合のポイント2 「名前の唯一性」
ここまでの段階で、今回の目的(「#」の書き忘れへの対処)はすでに達成できています。
ですが、先ほどの記事(ハイパーリンクを提供する | The Web KANZAKI)には、さらなるヒントがありました。
それは、「#」を用いて指定する「名前」についてのお話です。
名前は、同一ドキュメントの中で唯一のものでなければならず、重複してはいけません(Uniqueness)。このとき、(1)大小文字の違いだけによる名前付けは、この唯一性を満足できません;(2)ただし、名前の照合時(string match)に大小文字は区別されます。以下のような使い方をしないよう注意してください。
記事内では、これを「名前の唯一性」と呼んでいます。
「#」を使って指定する名前は、「唯一」のものでなければならない。
だからこそ、CSSをid属性とリンクさせる場合には「#」を使えて、class属性とリンクさせる場合には使えないのですね。
CSSでの「#」と「.」の使い分けにまで、視野を広げることができました!
(そういえば、そもそもの発端であるBootstrapを使ったコードの中で、ハンバーガーメニューに紐づける要素のタグ付けには id 属性が使われていたのでした・・・まるで伏線が回収されたような感覚です笑!)
おまけ:個人的な「#」のビジュアルイメージ
今回の検討を踏まえて、「#」に対して個人的に次のようなビジュアルイメージを持つに至りました。 ![896251_resize.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696316/56501757-526b-24a8-3294-ef512bd09fea.png) ※フック付きロープイラスト/イラストACより先端に金属製のフックが結びつけられたロープです。
(よくアクション映画なんかで、フックを高いところめがけて投げて「ガチっ!」と固定させ、壁をよじ登るのに使うアレです)
ファイル内の特定箇所に向けて、このロープを投げかけるようなイメージ。
また、1本のロープなので1か所にしか使えず、「名前の唯一性」のイメージにもぴったりなんじゃないかな?と思っています。。。
最後まで読んでいただき、ありがとうございました!