404ページ · 404ページ
ピクセルアート調の404ページ
深紫の宇宙を背景に、点滅する星・浮遊するピクセルキャラクター・グリッチするタイトルを組み合わせたレトロゲーム風の404ページ。冷たいエラー画面の代わりに、離脱の瞬間を小さな温度に変える。
このブラウザー内に保存します。別の端末との同期はなく、サイトデータを消すと保存も消えます。
印刷時は見本を静止画にし、プロンプトと解説を出力します。PDF保存はブラウザーの印刷画面から選べます。
Vibehaus · デザイン資料
https://vibe.itlibra.com/design/404-pixel/
完全無料・著作権フリー(CC0)· 料金¥0 · 商用利用・改変自由
プレビュー
指定幅で実際に組み替えて表示します。表示領域より広い場合は、この枠の中で横へスクロールできます。
AIへの指示文
レトロゲーム風の404ページを作ってください。冷たいエラー画面にならず、訪問者が次にどこへ行けばいいかを明確に示す構成で。 キャンバス: - 深紫〜青紫の宇宙背景 (#1a1235 → #2a1d52)、線形グラデで上下反復。 - アクセント色を4色限定: ピンク (#ff6fa0)、緑 (#7dff9f)、イエロー (#ffd65a)、シアン (#6fe3ff)。 - 本文フォントは VT323 (レトロモノスペース、大きめの 1.35rem で読ませる)。 - 見出し/ボタンは Press Start 2P (ピクセルフォント、小さめの 0.8〜1rem で使う)。 - 全要素に `image-rendering: pixelated` を指定してドットのエッジを保つ。 背景演出: - 星空: `radial-gradient` で 1px の白いドットを 8 箇所散らし、`@keyframes twinkle` で 3 秒かけて透明度を 0.4↔0.8 で変化させる。 - 控えめな彩色の煌めき (黄/緑/ピンク) も重ねる。 中央ステージ (max-width 720px): 1. ピクセルキャラクター (120x120): - インライン SVG で 20x20 グリッドのレトロゴースト/お化けをドット絵で作る。 - `shape-rendering: crispEdges` で輪郭を保つ。 - `@keyframes float` で 1.4 秒周期に 8px 上下浮遊。 - 影は楕円のぼかし (`filter: blur(4px)`) で、浮遊と連動して縮小する別アニメ。 2. 巨大な "404" タイトル: - Press Start 2P、font-size clamp(4rem, 16vw, 9rem)、line-height 1。 - text-shadow でピンクとシアンの色ズレを入れ、RGB ズレ風に。 - `@keyframes glitch` で 4 秒周期にランダムな短いズレを差し込む (全体の 7% 程度の時間)。 3. リード: - "> PAGE NOT FOUND" を Press Start 2P、イエロー、0.95rem。 - サブコピーを VT323、ミュートの薄紫、1.35rem。2 行程度。 4. アクションボタン 2 つ: - プライマリ "▶ GO HOME" (緑背景)、セカンダリ "◀ GO BACK" (ピンク背景)。 - Press Start 2P、近黒文字、4px オフセットシャドウ (黄色系)。 - hover で `translate(-2px, -2px)` + シャドウ深め、active で `translate(2px, 2px)` + シャドウ 0。 - トランジションは `steps(1)` で段階的にして、レトロ感を保つ。 5. 追加ヒント: - "try /search or /sitemap next" のような行、各 URL を小さなシアン背景の tag ピルで包む。 最下部: - 画面下に絶対配置で "ERR 0x0194 · signal lost · 2026" を極小の Press Start 2P、letter-spacing 0.2em、ミュート色。 JS 不要、純粋 HTML/CSS + インライン SVG。
バリエーション
ライト版
背景をクリーム (#fef6e4) に、アクセントカラーは維持。 タイトルのシャドウはピンクとシアンで色ズレを保ったまま、ベースを近黒に。 星空は省略、代わりに薄いドットパターン (background-image の radial-gradient) でレトロ感を出す。
キャラクター差し替え版
SVG 部分だけ差し替え可能に設計されている。 猫・ロボット・宇宙人・ピクセル犬などに変更する場合、20x20 のグリッドで rect を並べ、配色を 3 色以内に抑える (一貫性が保てる)。
このプレビューのコード
HTML・CSS・JavaScriptの1ファイルです。外部依存・広告・解析コードはありません。架空の404画面です。復帰先のリンクはページ内の案内の見本へ移動します。実際のサイト遷移や履歴操作は行いません。演出の停止とOSの動き低減に対応します。
コードを表示
<!doctype html>
<!-- Vibehaus · CC0 · 架空の表示・操作見本。外部素材・送信・永続保存なし。 -->
<html lang="ja">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="robots" content="noindex" />
<title>ピクセルアート調の404ページ — Vibehaus プレビュー</title>
<style>
:root {
--bg: #1a1235;
--bg-2: #2a1d52;
--fg: #ffe9b0;
--fg-muted: #a89ac8;
--pink: #ff6fa0;
--green: #7dff9f;
--yellow: #ffd65a;
--cyan: #6fe3ff;
--pixel: "Press Start 2P", "VT323", "Courier New", "Noto Sans JP", "Hiragino Sans", "Meiryo", monospace;
--mono: "VT323", "Courier New", "Noto Sans JP", "Hiragino Sans", "Meiryo", ui-monospace, monospace;
}
* { box-sizing: border-box; image-rendering: pixelated; }
html, body { margin: 0; padding: 0; }
body {
font-family: var(--mono);
background: var(--bg);
background-image:
linear-gradient(180deg, var(--bg-2) 0%, var(--bg) 50%, var(--bg-2) 100%),
radial-gradient(circle at 20% 30%, rgba(255, 214, 90, 0.08) 0 2px, transparent 3px),
radial-gradient(circle at 70% 15%, rgba(125, 255, 159, 0.08) 0 2px, transparent 3px),
radial-gradient(circle at 40% 80%, rgba(255, 111, 160, 0.08) 0 2px, transparent 3px);
background-blend-mode: screen;
color: var(--fg);
min-height: 100dvh;
display: grid;
place-items: center;
padding: 2rem 1rem;
position: relative;
overflow: hidden;
font-size: 18px;
}
/* Starfield */
body::before {
content: "";
position: absolute;
inset: 0;
background-image:
radial-gradient(1px 1px at 10% 20%, #fff 0, transparent 2px),
radial-gradient(1px 1px at 30% 45%, #fff 0, transparent 2px),
radial-gradient(1px 1px at 60% 15%, #fff 0, transparent 2px),
radial-gradient(1px 1px at 75% 60%, #fff 0, transparent 2px),
radial-gradient(1px 1px at 90% 80%, #fff 0, transparent 2px),
radial-gradient(1px 1px at 15% 75%, #fff 0, transparent 2px),
radial-gradient(1px 1px at 45% 25%, #fff 0, transparent 2px),
radial-gradient(1px 1px at 85% 35%, #fff 0, transparent 2px);
background-size: 100% 100%;
opacity: 0.6;
animation: twinkle 3s ease-in-out infinite;
pointer-events: none;
}
@keyframes twinkle {
0%, 100% { opacity: 0.4; }
50% { opacity: 0.8; }
}
.stage {
position: relative;
max-width: 720px;
width: 100%;
text-align: center;
z-index: 1;
}
/* 404 title as giant pixel blocks */
.error-code {
font-family: var(--pixel);
font-size: clamp(4rem, 16vw, 9rem);
line-height: 1;
letter-spacing: 0.04em;
margin: 0 0 1.5rem;
text-shadow:
4px 0 0 var(--pink),
-4px 0 0 var(--cyan),
0 0 20px rgba(255, 111, 160, 0.3);
animation: glitch 4s steps(1) infinite;
}
@keyframes glitch {
0%, 92%, 100% { transform: translate(0, 0); }
93% { transform: translate(-2px, 1px); text-shadow: 4px 0 0 var(--pink), -4px 0 0 var(--cyan); }
94% { transform: translate(3px, -1px); text-shadow: -4px 0 0 var(--pink), 4px 0 0 var(--cyan); }
95% { transform: translate(-1px, 2px); }
96% { transform: translate(2px, -2px); text-shadow: 4px 4px 0 var(--yellow), -4px -4px 0 var(--cyan); }
}
/* Pixel character */
.character {
position: relative;
width: 120px;
height: 120px;
margin: 0 auto 2rem;
image-rendering: pixelated;
}
.character svg { width: 100%; height: 100%; display: block; }
.character::after {
content: "";
position: absolute;
bottom: -8px;
left: 50%;
transform: translateX(-50%);
width: 70px;
height: 10px;
background: rgba(0, 0, 0, 0.35);
border-radius: 50%;
filter: blur(4px);
animation: shadow 1.4s ease-in-out infinite;
}
.character {
animation: float 1.4s ease-in-out infinite;
}
@keyframes float {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-8px); }
}
@keyframes shadow {
0%, 100% { opacity: 0.4; transform: translateX(-50%) scaleX(1); }
50% { opacity: 0.2; transform: translateX(-50%) scaleX(0.7); }
}
.lede {
font-family: var(--pixel);
font-size: 0.95rem;
line-height: 1.7;
color: var(--yellow);
letter-spacing: 0.04em;
margin: 0 0 0.75rem;
}
.sub {
font-family: var(--mono);
font-size: 1.35rem;
color: var(--fg-muted);
margin: 0 0 2.5rem;
}
.actions {
display: inline-flex;
gap: 0.75rem;
flex-wrap: wrap;
justify-content: center;
}
a.btn {
font-family: var(--pixel);
font-size: 0.82rem;
letter-spacing: 0.05em;
padding: 0.85rem 1.2rem;
border: 0;
text-decoration: none;
color: var(--bg);
background: var(--green);
box-shadow: 4px 4px 0 var(--fg);
transition: transform 0.05s steps(1), box-shadow 0.05s steps(1);
cursor: pointer;
image-rendering: pixelated;
}
a.btn:hover { transform: translate(-2px, -2px); box-shadow: 6px 6px 0 var(--fg); }
a.btn:active { transform: translate(2px, 2px); box-shadow: 0 0 0 var(--fg); }
a.btn.alt { background: var(--pink); color: var(--bg); }
.tip {
margin-top: 2.5rem;
font-family: var(--mono);
font-size: 1.1rem;
color: var(--fg-muted);
}
.tip .tag {
display: inline-block;
padding: 0.15rem 0.5rem;
background: var(--cyan);
color: var(--bg);
font-family: var(--pixel);
font-size: 0.72rem;
margin: 0 0.35rem;
}
/* Footer byte */
.byte {
position: absolute;
bottom: 1.5rem;
left: 0;
right: 0;
text-align: center;
font-family: var(--pixel);
font-size: 0.72rem;
color: var(--fg-muted);
letter-spacing: 0.2em;
}
[hidden]{display:none!important}
a,button,input,summary{min-width:44px;min-height:44px}
a{touch-action:manipulation}
button{cursor:pointer}
button:disabled{cursor:default}
a:focus-visible,button:focus-visible,input:focus-visible{outline:3px solid currentColor;outline-offset:4px}
nav a{display:inline-flex;align-items:center;justify-content:center}
nav{flex-wrap:wrap}
header.bar{flex-wrap:wrap;gap:1rem}
input{max-width:100%}
.demo-notes{position:relative;z-index:10;box-sizing:border-box;max-width:1080px;width:calc(100% - 2rem);margin:2rem auto;padding:clamp(1rem,3vw,2rem);background:#1a1235;color:#ffe9b0;border:1px solid currentColor;text-align:left;font-family:"Hiragino Sans","Yu Gothic",Meiryo,sans-serif;font-size:13px;line-height:1.8;letter-spacing:0;overflow-wrap:anywhere}
.demo-notes h2{font-size:18px;line-height:1.5;margin:0 0 .75rem}
.demo-notes h3{font-size:15px;line-height:1.5;margin:0 0 .4rem}
.demo-notes p{font:inherit;color:inherit;opacity:1;margin:0 0 1rem;max-width:none;letter-spacing:0}
.demo-notes section{margin-top:1.25rem;scroll-margin-top:1rem}
.demo-notes button{font:inherit;color:inherit;background:transparent;border:1px solid currentColor;padding:.4rem .75rem}
.demo-notes a{color:inherit}
.demo-notes .demo-motion{margin-bottom:1rem}
.demo-notes section:focus{outline:3px solid currentColor;outline-offset:4px}
@media(prefers-reduced-motion:reduce){*,*::before,*::after{animation:none!important;transition:none!important}
}
body{overflow:visible;display:block}
body>.stage,body>.cta,body>.container{margin-inline:auto}
html[data-demo-paused] *,html[data-demo-paused] *::before,html[data-demo-paused] *::after{animation-play-state:paused!important}
html[data-demo-paused] .ticker p{animation:none!important;padding-left:8px;white-space:normal}
body>.cta-block,body>.frame{margin-inline:auto}
</style>
<noscript><style>*,*::before,*::after{animation:none!important}.ticker p{padding-left:8px;white-space:normal}</style></noscript>
</head>
<body>
<main class="stage">
<div class="character" aria-hidden="true">
<svg viewBox="0 0 20 20" shape-rendering="crispEdges">
<!-- simple retro ghost/blob -->
<rect x="5" y="3" width="10" height="2" fill="#ff6fa0"/>
<rect x="4" y="5" width="12" height="2" fill="#ff6fa0"/>
<rect x="3" y="7" width="14" height="8" fill="#ff6fa0"/>
<rect x="3" y="15" width="2" height="1" fill="#ff6fa0"/>
<rect x="6" y="15" width="2" height="1" fill="#ff6fa0"/>
<rect x="9" y="15" width="2" height="1" fill="#ff6fa0"/>
<rect x="12" y="15" width="2" height="1" fill="#ff6fa0"/>
<rect x="15" y="15" width="2" height="1" fill="#ff6fa0"/>
<!-- eyes -->
<rect x="6" y="9" width="2" height="2" fill="#1a1235"/>
<rect x="12" y="9" width="2" height="2" fill="#1a1235"/>
<rect x="6" y="9" width="1" height="1" fill="#fff"/>
<rect x="12" y="9" width="1" height="1" fill="#fff"/>
<!-- mouth -->
<rect x="8" y="12" width="4" height="1" fill="#1a1235"/>
<rect x="7" y="11" width="1" height="1" fill="#1a1235"/>
<rect x="12" y="11" width="1" height="1" fill="#1a1235"/>
</svg>
</div>
<h1 class="error-code">404</h1>
<p class="lede">> ページが見つかりません</p>
<p class="sub">空のセルに迷い込みました。<br />でも、ここのゴーストは人懐っこいやつです。</p>
<div class="actions">
<a class="btn" href="#demo-link-0">▶ ホームへ</a>
<a class="btn alt" href="#demo-link-1">◀ 前のページに戻る</a>
</div>
<p class="tip">
復帰先は、下の案内で確認できます(表示見本)。
</p>
</main>
<div class="byte">
ERR 0x0194 · 信号消失 · 2026
</div>
<aside class="demo-notes" aria-label="この見本について">
<h2>この見本について</h2>
<p>架空の404画面です。復帰先のリンクはページ内の案内の見本へ移動します。実際のサイト遷移や履歴操作は行いません。配布HTMLはCC0・利用料¥0。外部素材やライブラリの取得は不要です。</p>
<div class="demo-motion">
<button type="button" data-demo-motion data-js-control disabled aria-pressed="false">演出を止める</button>
</div>
<section id="demo-link-0" tabindex="-1">
<h3>▶ ホームへの見本</h3>
<p>復帰先を案内するリンク位置の例です。このHTMLにサイトのルートや閲覧履歴は含まれないため、利用先のURLと復帰処理を接続してください。</p>
</section>
<section id="demo-link-1" tabindex="-1">
<h3>◀ 前のページに戻るの見本</h3>
<p>復帰先を案内するリンク位置の例です。このHTMLにサイトのルートや閲覧履歴は含まれないため、利用先のURLと復帰処理を接続してください。</p>
</section>
<noscript>
<p>JavaScriptなしでも初期表示と説明リンクを利用できます。絞り込み・入力確認・演出の切替は無効です。</p>
</noscript>
</aside><script>
const motion=matchMedia('(prefers-reduced-motion: reduce)'),toggle=document.querySelector('[data-demo-motion]');let paused=false;function syncMotion(){const stop=paused||motion.matches;document.documentElement.toggleAttribute('data-demo-paused',stop);toggle.setAttribute('aria-pressed',String(stop));toggle.disabled=motion.matches;toggle.textContent=motion.matches?'動きを減らす設定で停止中':stop?'演出を再開':'演出を止める'}toggle.addEventListener('click',()=>{paused=!paused;syncMotion()});motion.addEventListener('change',syncMotion);
document.querySelectorAll('[data-js-control]').forEach(el=>el.disabled=false);syncMotion();
</script>
</body>
</html>
2026年10月14日、Chromiumで320・390・768・1280pxの描画とキーボードのフォーカス表示を確認しました。他のブラウザは未確認です。利用先のブラウザと実データでも確認してください。
概要
ピクセルアート調の404ページは、「エラーは冷たいもの」という常識への対案です。レトロゲームで初めてゲームオーバー画面を見た世代にとって、ドット絵・宇宙の背景・点滅する星の組み合わせは、即座に「懐かしい」「遊んでいた」という記憶を呼び起こします。エラー画面が、温度を持つ瞬間です。
404は分岐点である
404ページに辿り着いた訪問者は、離脱するか、もう一度サイトを試すかの分岐点に立っています。白地に「404」とだけ書かれた冷たい画面は、訪問者を離脱の側へ押す。逆に、温度のある画面は回遊の側へ引き戻します。ピクセルアートは多くの人の幼少期の記憶に紐づいているため、特別な説明なしにデフォルトで温かく感じられる——だからこの分岐で有利に働きます。
崩れる形白地に404とだけ書く
情報としては正しいのに、壊れた画面と区別がつきません。訪問者は自分の操作が悪かったのかサイトが落ちているのかを判断できず、そのまま離脱の側へ倒れます。
効く形温度のある画面で迎える
ドット絵と宇宙の背景は、多くの人の幼少期の記憶に紐づいています。特別な説明なしに温かく感じられるぶん、この分岐で回遊の側へ引き戻せます。
失敗を意匠に変える
このページのもう一つの妙は、「壊れている」状態そのものをデザインの素材にする点です。RGBがズレたグリッチ風のタイトル、エラーコード風の符牒——本来ネガティブな「故障」の記号を、レトロSFの演出として楽しく見せる。失敗を隠すのではなく、ブランドの遊び心として引き受ける姿勢が伝わります。
仕上げの判断軸
深紫の宇宙背景に、アクセント4色を少量ずつ散らして色情報を保ちます。浮遊するピクセルキャラクターにアニメーションを付けると「このページは死んでいない」と伝わる。グリッチはシアン/ピンクの text-shadow で常時の色ズレを出しつつ、数秒に一度だけ短い乱れを差し込むと品よくまとまります。復帰ボタンは緑とピンクで「進む/戻る」を色分けし、行き先を明示。
noindex を付け、サイトマップには含めないこと。遊ぶのは見た目だけで、SEOの作法は崩しません。
見本で試せる範囲
架空の404画面です。復帰先のリンクはページ内の案内の見本へ移動します。実際のサイト遷移や履歴操作は行いません。演出の停止とOSの動き低減に対応します。 作品・記事・サービス名や数値は表示のための設定です。リンク先には、このHTMLに含まれる範囲と利用先で接続する処理を説明しています。配布HTMLはCC0・利用料¥0で、保存した1ファイルだけで表示できます。
404ページの構成要素
使いどころ
- 個人開発者・クリエイターサイトの 404 ページ
- ゲーム / Web3 / 開発者ツール系プロダクトで、世界観を壊さずエラーを受け止めたいとき
- エラー画面でも離脱率を下げたい、行き先を明示したい場面
このデザインの分類
背景と狙いどころ
よくある質問
Press Start 2P は本当に読めますか?
アクセシビリティ面は?
404 なのにCTA付きでいいの?
この画面を実装する
動くサンプルとコピペできるコードを、技術別にまとめています。
関連するデザイン
放送終了のカラーバーで迎える404ページ
テレビの放送が終わった後のカラーバーを背景にした404ページ。画像を使わずグラデーションだけで描いたカラーバーに、チャンネル表示と時刻、「このページの放送は終了しました」の案内、検索窓と番組表(サイトマップ)への導線を重ねる。
ストリートグラフィティ風の404ページ
コンクリート壁にスプレー塗料で殴り書きされた「404」を主役にしたストリートグラフィティ風 404 ページ。剥がれかけのポスター、タグ、スプラッタ、警告テープ。失敗ページすらブランドの遊び場にする尖った設計。
アーケード筐体UI風の料金プラン
80年代ゲームセンターのアーケード筐体UIを再現した料金プラン。"INSERT COIN"、ピクセルスコアボード、ハイスコア表で「コインを入れて始める」ノスタルジーをCTAに変換する尖った設計。