CSSとJSで作るマウスに反応して枠と文字が発光するボタン

ホバー

CSSとJSで作るマウスに反応して枠と文字が発光するボタン

投稿日2026/01/24

更新日2026/1/23

近年のUIデザインでは、「派手すぎないが確実に目を引く演出」が求められています。
マウスの位置に反応して枠線と文字がふわっと発光するネオン調ボタンです。

CSS変数とradial-gradient()を中心に構成されており、JavaScriptは「マウス位置をCSSに渡す」だけというミニマル設計。
デザイン性と実装の美しさを両立した、実用向けのエフェクトになっています。

Preview プレビュー

Code コード

<div class="kumonosu-container">
	<button class="kumonosu-btn kumonosu-btn-blue">
		<span class="kumonosu-text">Button</span>
	</button>

	<button class="kumonosu-btn kumonosu-btn-mid">
		<span class="kumonosu-text">Button</span>
	</button>

	<button class="kumonosu-btn kumonosu-btn-red">
		<span class="kumonosu-text">Button</span>
	</button>
</div>
:root {
	--kumonosu-bg: #1a1a1a;
	--x: 220;
	--y: 235;
	--kumonosu-glow-size: 100px;
	--kumonosu-color-blue: #3624ff;
	--kumonosu-color-red: #ff3c3c;
	--kumonosu-color-mid: color-mix(in srgb,
			var(--kumonosu-color-blue),
			var(--kumonosu-color-red) 50%);
}
* {
	box-sizing: border-box;
}
body {
	margin: 0;
	min-height: 100vh;
	background-color: var(--kumonosu-bg);
}
/* レイアウト */
.kumonosu-container {
	display: flex;
	justify-content: center;
	align-items: center;
	min-height: 100vh;
	gap: 1.5rem;
	font-family: system-ui, -apple-system, sans-serif;
}
/* メインボタン */
.kumonosu-btn {
	position: relative;
	padding: 1.5rem 3rem;
	font-size: 1rem;
	font-weight: bold;
	text-transform: uppercase;
	letter-spacing: 0.1ch;
	color: transparent;
	cursor: pointer;
	border-radius: 1rem;
	border: 4px solid transparent;
	--kumonosu-btn-color: var(--kumonosu-color-mid);
	--kumonosu-glow-effect: radial-gradient(50% 50% at center,
			white,
			var(--kumonosu-btn-color),
			transparent) calc((var(--x) * 1px) - (var(--kumonosu-glow-size) / 2)) calc((var(--y) * 1px) - (var(--kumonosu-glow-size) / 2)) / var(--kumonosu-glow-size) var(--kumonosu-glow-size) no-repeat fixed;
	background:
		linear-gradient(var(--kumonosu-bg), var(--kumonosu-bg)) padding-box,
		var(--kumonosu-glow-effect),
		linear-gradient(black, black) border-box;
	transition: transform 0.2s;
	touch-action: none;
}
.kumonosu-btn-blue {
	--kumonosu-btn-color: var(--kumonosu-color-blue);
}
.kumonosu-btn-mid {
	--kumonosu-btn-color: var(--kumonosu-color-mid);
}
.kumonosu-btn-red {
	--kumonosu-btn-color: var(--kumonosu-color-red);
}
.kumonosu-btn:active {
	transform: scale(0.98);
}
/* 文字の発光 */
.kumonosu-text {
	background: var(--kumonosu-glow-effect), rgba(255, 255, 255, 0.2);
	-webkit-background-clip: text;
	background-clip: text;
}
/* 背後グロー */
.kumonosu-btn::after {
	content: "";
	position: absolute;
	inset: -4px;
	filter: blur(20px);
	background: var(--kumonosu-glow-effect);
	border-radius: 1rem;
	z-index: -1;
}
/* 内部質感 */
.kumonosu-btn::before {
	content: "";
	position: absolute;
	inset: 0;
	background: var(--kumonosu-bg);
	z-index: -1;
	border-radius: calc(1rem - 4px);
	box-shadow: 0 1px rgba(255, 255, 255, 0.15) inset;
}
const syncPointer = ({ x, y }) => {
	document.documentElement.style.setProperty('--x', x.toFixed(2));
	document.documentElement.style.setProperty('--y', y.toFixed(2));
};

window.addEventListener('pointermove', syncPointer);

syncPointer({
	x: window.innerWidth / 2,
	y: window.innerHeight / 2
});

Explanation 詳しい説明

仕様概要

  • 発光位置
    マウス(またはタッチ)の位置をCSS変数--x, --yとして管理
  • 発光表現
    radial-gradient()を背景に使用し、ボタン枠・文字・ぼかしに共有
  • 構造
    • 本体背景(padding-box)
    • 光のエフェクト(background layer)
    • 枠線(border-box)
  • 対応入力
    pointermove を使用しているため、マウス・タッチ・ペンに対応

レイヤー構造の考え方

このボタンは視覚的に三層構造になっています。

  1. ::before
    • 内側の背景と微妙な質感(inset shadow)
  2. 本体 background
    • 枠線だけが光るように見せるメイン表現
  3. ::after
    • 背後に広がるぼかしグロー(filter: blur)

この分離により、
「派手だけど安っぽくならない」ネオン表現が成立しています。

カスタマイズ方法

色を変更したい場合

--kumonosu-color-blue: #3624ff;
--kumonosu-color-red:  #ff3c3c;

を変更するだけでOK。
color-mix()を使っているため、中間色も自動で調整されます。

光の広がりを変えたい場合

--kumonosu-glow-size: 100px;
  • 小さく → シャープで鋭い光
  • 大きく → 柔らかく幻想的な光

ボタンサイズを変えたい場合

padding: 1.5rem 3rem;
border-radius: 1rem;
border: 4px solid transparent;

これらは連動しているため、角丸とボーダー幅はセットで調整すると破綻しません。