HTMLコーディングをしていると、ページ内の要素に飛ぶためのリンクを張りたい場面があるかと思います。
ですが、ページ内リンクの張り方を知っていても、スムーズスクロールのやり方をはっきりと覚えている人は少ないのではないでしょうか?
ページ内にリンクを張ってスムーズスクロールで飛ばす手法は簡単に作ることができますが、JQueryを少し触る必要が出てくる場合もあるため少し実装が面倒でもあります。
そこで、スムーズスクロールをコピペで実装できるコードの配布と、初めて実装する人でも仕組みが分かるように作り方の手順から詳しく解説していきます。
ページ内リンクとは何か

ページ内リンクとはHTML要素にリンクを張ることを言います。
ポイントはaタグを使って移動先のHTML要素のid名でリンクを張る点です。
一般的な使い方としてはWebサイトのメニューボタンを押すと、特定の要素の位置まで自動的にスクロールさせる場合などによく使われます。
また、自動スクロールする際にアニメーションしながら移動することをスムーズスクロールと呼びます。
言葉で説明しても分かりにくいかと思いますので、こちらのリンクをクリックしてみてください。
HTMLでページ内リンクを作る基本的な実装方法

ここまではページ内リンクの作り方を言葉で説明してきましたが、具体的な実装方法について解説します。
HTMLとCSSを少し書いてJavaScriptをコピペするだけで簡単にできるので、是非チャレンジしてください。
以下に最終的な出来上がりの結果とコードの全文を貼っておきますので、参考程度にご覧ください。
HTML
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=960, initial-scale=1.0">
<link rel="stylesheet" href="./style.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="./index.js"></script>
<title>【スムーズスクロール】HTMLのページ内リンクで飛ばす方法について解説|デモンストレーション</title>
</head>
<body>
<div class="container">
<header>
<div class="menu_wrap">
<ul class="clearfix menu">
<li><a href="#section_01">セクション01</a></li>
<li><a href="#section_02">セクション02</a></li>
<li><a href="#section_03">セクション03</a></li>
<li><a href="#section_04">セクション04</a></li>
</ul>
</div>
</header>
<main>
<section id="section_01">1つ目のセクション</section>
<section id="section_02">2つ目のセクション</section>
<section id="section_03">3つ目のセクション</section>
<section id="section_04">4つ目のセクション</section>
</main>
<footer>
<p class="copyright"><small>Copyright©</small></p>
</footer>
</div>
</body>
</html>
CSS
/* start reset */
* {
margin: 0px;
padding: 0px;
}
a {
text-decoration: none;
}
ul,
li {
list-style: none;
}
/* end reset */
/* start common */
.clearfix:after {
content: "";
display: block;
clear: both;
}
.container {
width: 100%;
height: auto;
}
/* end common */
/* start header */
.container
.menu_wrap {
margin-bottom: 40px;
width: 100%;
height: auto;
background-color: #3da9f4;
}
.container
.menu_wrap
.menu {
margin: auto;
width: 960px;
height: auto;
background: linear-gradient(#41aff8, #3aa1ec);
}
.container
.menu_wrap
.menu
li {
width: 25%;
height: 50px;
line-height: 50px;
text-align: center;
border-left: solid 1px #fff;
box-sizing: border-box;
float: left;
}
.container
.menu_wrap
.menu
li:last-child {
border-right: solid 1px #fff;
}
.container
.menu_wrap
.menu
li
a {
width: 100%;
height: 100%;
color: #fff;
display: block;
transition: opacity 0.3s ease-in-out;
}
.container
.menu_wrap
.menu
li
a:hover {
opacity: 0.5;
}
/* end header */
/* start main */
main {
margin: 0px auto 80px auto;
width: 960px;
}
main
section {
width: 100%;
height: 500px;
line-height: 500px;
text-align: center;
color: #fff;
}
main
section:not(:last-child) {
margin-bottom: 40px;
}
main
#section_01 {
background-color: #dd0000;
}
main
#section_02 {
background-color: #ffaa00;
}
main
#section_03 {
background-color: #55dd55;
}
main
#section_04 {
background-color: #5555ff;
}
/* end main */
/* start footer */
footer {
width: 100%;
height: 40px;
background-color: #3da9f4;
}
footer
.copyright {
line-height: 40px;
text-align: center;
color: #fff;
}
/* end footer */
JavaScript
$(function() {
const scroll_time = 650; //スクロールにかかる時間
let $html_body = $('html,body');
let $page_link = $('a[href^="#"]');
//ページ内リンクがクリックされた時
$page_link.click(function() {
let $target = $($(this).attr('href'));
let target_offset_top = $target.offset().top;
//スムーズスクロール
$html_body.animate({
scrollTop: target_offset_top
}, scroll_time, 'swing');
});
});
HTML内の要素にid名を振り分ける
それでは詳しくページ内リンクの実装方法について見ていきましょう。
まずは、移動先のHTML要素にid名を付けてリンクを張るための準備をしましょう。
また、class名でページ内リンクを張ることはできませんので、ご注意ください。
<main>
<section id="section_01">1つ目のセクション</section>
<section id="section_02">2つ目のセクション</section>
<section id="section_03">3つ目のセクション</section>
<section id="section_04">4つ目のセクション</section>
</main>
aタグのhref属性に「#id名」の形でリンクを張る
次にメニューを作成してaタグのhref属性に移動先の要素のid名を記述します。
<header>
<div class="menu_wrap">
<ul class="menu">
<li><a href="#section_01">セクション01</a></li>
<li><a href="#section_02">セクション02</a></li>
<li><a href="#section_03">セクション03</a></li>
<li><a href="#section_04">セクション04</a></li>
</ul>
</div>
</header>
JavaScriptでid名が振られているa要素を取得する
JavaScriptでaタグのhref属性の値で先頭が「# (ハッシュ)」で始まる要素だけを取得することができます。
その後、取得した要素を変数に代入して、クリックイベントに対応させるようにしていきます。
let $page_link = $('a[href^="#"]');
スクロールアニメーションで飛ばす (スムーズスクロール)
先ほど取得したアンカー要素をクリックイベントに対応させて、ページ内リンクが押された時に飛び先の要素のid名と位置を取得してJQueryのanimateメソッドでhtml、body要素にアニメーションをかけることでスムーズスクロールを実装することができます。
//ページ内リンクがクリックされた時
$page_link.click(function() {
let $target = $($(this).attr('href'));
let target_offset_top = $target.offset().top;
//スムーズスクロール
$html_body.animate({
scrollTop: target_offset_top
}, scroll_time, 'swing');
});
ページ内リンクで位置がズレる時の原因と対処方法

メニューをサイトの上部に固定化するコーディングをしている場合や、飛び先の要素の余白の付け方が間違っている時にページ内リンクをクリックしてスムーズスクロールをすると、思っていた位置よりも下に来てしまう場合などがあります。
まず、一番簡単な原因と対策方法から解説すると、飛び先の要素の余白の付け方を間違っている場合などは大抵の場合marginで設定している時があるのでpaddingに変えてあげるだけで直すことができます。
それ以外の原因と対策方法については以下の解説をご覧ください。
メニューの高さを考慮していない
メニューをページの上部に固定する場合、高さを考慮する必要があるのですが、それを怠ってしまうとスムーズスクロールした時にコンテンツとメニューが被ってしまう現象が起きてしまいます。
その場合は、JavaScriptでメニューの高さを考慮したコードを足してあげる必要があります。
以下がそのサンプルコードになります。ポイントは「 - $menu.height()」としているところです。
$(function() {
const scroll_time = 650; //スクロールにかかる時間
let $html_body = $('html,body');
let $page_link = $('a[href^="#"]');
let $menu = $('.menu');
//ページ内リンクがクリックされた時
$page_link.click(function() {
let $target = $($(this).attr('href'));
let target_offset_top = $target.offset().top;
//スムーズスクロール
$html_body.animate({
scrollTop: target_offset_top - $menu.height()
}, scroll_time, 'swing');
});
});
まとめ
今回はページ内リンクの設置法とスムーズスクロールの作り方とズレた時の対処法について解説しました。
ページ内リンクを利用したスムーズスクロールの実装はよく使われるので必ず覚えておきましましょう。
もし、どうしても作り方を忘れてしまうという人はページをブックマークしておくことをオススメします。
それでは、皆さん良いコーディングライフを!
