jQueryなど便利なライブラリもいいですが、軽量でカスタマイズ自由自在なオリジナリティあふれるネイティブJavaScriptを書くのもいいかも。
jQueryなど便利なライブラリもいいですが、軽量でカスタマイズ自由自在なオリジナリティあふれるネイティブJavaScriptを書くのもいいかも。

スムーススクロール

注意
これらの記事は2016年当時の物で結構古いです。モダンブラウザでは不要な記述やJavaScriptでなくともCSSで実現できる機能もあります。 当時の記録として残してありますがあまり参考になるものではありません。
概要
スムーススクロール。
実装例は本サイトです。ブラウザ内右下の矢印クリックで目的のアンカー名へスクロールします。
使用方法
基本的に設置するだけですが、任意のタイミングでアクションさせられるよう拡張してあります。
備考
元ネタに色々拡張して現在の形になりました。

/**
 * スムーススクロール
 *
 * @author ao-system
 */
var SmoothScroll = {
	_speed: 20,	//work
	_lastPos: 0,	//work
	_interval: 0,	//work

/**
 * 要素の位置を返す
 */
	offsettop: function (elm) {
		var offsettop = elm.offsetTop;
		if (elm.offsetParent) {
			while (elm = elm.offsetParent) {
				offsettop += elm.offsetTop;
			}
		}
		return offsettop;
	},

/**
 * スクロール位置を返す
 */
	scrolltop: function () {
		if (document.body && document.body.scrollTop) {
			return document.body.scrollTop;
		}
		if (document.documentElement && document.documentElement.scrollTop) {
			return document.documentElement.scrollTop;
		}
		if (window.pageYOffset) {
			return window.pageYOffset;
		}
		return 0;
	},

/**
 * addEventListener 各ブラウザ互換対応
 */
	addEvt: function(elm, tpe, func) {
		if (elm.addEventListener) {
			return elm.addEventListener(tpe, func, false);
		} else if (elm.attachEvent) {
			return elm.attachEvent('on' + tpe, func);
		} else {
			return elm['on' + tpe] = func;
		}
	},

/**
 * イベントをキャンセルする
 */
	killEvt: function(evt) {
		if (evt.preventDefault && evt.stopPropagation) {
			evt.preventDefault();
			evt.stopPropagation();
		} else {
			evt.cancelBubble = true;
			evt.returnValue = false;
		}
	},

/**
 * 目的地へスクロール
 */
	doScroll: function(targetPos) {
		var currentPos = SmoothScroll.scrolltop();	//現在の位置
		var moveSize = Math.ceil((targetPos - currentPos) / SmoothScroll._speed);
		if (moveSize == 0) {
			if (targetPos > currentPos) {
				moveSize = 1;
			} else {
				moveSize = -1;
			}
		}
		currentPos += moveSize;
		window.scrollTo(0,currentPos);
		if (currentPos == targetPos || SmoothScroll._lastPos == currentPos) {	//目的地に達したか、動けなくなったか
			clearInterval(SmoothScroll._interval);
			window.scrollTo(0,targetPos);
		}
		SmoothScroll._lastPos = currentPos;
	},

/**
 * イベント用意
 */
	render: function() {
		render2 = function() {	//内部function
			SmoothScroll.killEvt(this);
			var aTagName = this.hash.substr(1);
			var aTags = document.getElementsByTagName('a');
			for (var i = 0; i < aTags.length; i++) {
				if (aTags[i].name == aTagName) {
					clearInterval(SmoothScroll._interval);
					(function(aTag){
						SmoothScroll._interval = setInterval(function(){SmoothScroll.doScroll(SmoothScroll.offsettop(aTag))},10);
					})(aTags[i]);
				}
			}
		}
		var aTags = document.getElementsByTagName('a');
		for (var i = 0; i < aTags.length; i++) {
			if (aTags[i].href && aTags[i].href.indexOf('#') != -1 && ((aTags[i].pathname == location.pathname) || ('/' + aTags[i].pathname == location.pathname))) {
				SmoothScroll.addEvt(aTags[i], 'click', SmoothScroll.killEvt);
				aTags[i].onclick = render2;
			}
		}
	},

/**
 * 初期設定
 */
	init: function() {
		SmoothScroll.addEvt(window,'load', SmoothScroll.render);
	},

/**
 * アンカー名へスクロールする Load時にセット
 */
	anchorScroll: function(anchor) {
		SmoothScroll.addEvt(window,'load',function(){
			if (document.getElementById('loading')) {	//ページロード中表示があればそれを消す
				document.getElementById('loading').outerHTML = '';
			}
			var elm = document.getElementsByName(anchor).item(0);
			SmoothScroll._interval = setInterval(function(){SmoothScroll.doScroll(SmoothScroll.offsettop(elm));},10);
		});
	},

/**
 * name名へスクロールする。ダイレクト実行
 */
	nameScroll: function(namename) {
		var elm = document.getElementsByName(namename).item(0);
		SmoothScroll._interval = setInterval(function(){SmoothScroll.doScroll(SmoothScroll.offsettop(elm))},10);
	},

/**
 * ID名へスクロールする。ダイレクト実行
 */
	idScroll: function(idname) {
		var elm = document.getElementById(idname);
		SmoothScroll._interval = setInterval(function(){SmoothScroll.doScroll(SmoothScroll.offsettop(elm))},10);
	},

	dummy:0
};
SmoothScroll.init();