Skip to content

Instantly share code, notes, and snippets.

@FrecklyComb1728
Created December 13, 2025 21:02
Show Gist options
  • Select an option

  • Save FrecklyComb1728/cf70e360b41b86a79e903a6f3b411887 to your computer and use it in GitHub Desktop.

Select an option

Save FrecklyComb1728/cf70e360b41b86a79e903a6f3b411887 to your computer and use it in GitHub Desktop.
一个简约的404错误页,也可替换为其他页面
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/x-icon" href="/favicon.ico">
<title>404 - 页面未找到</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
cursor: default;
}
html, body {
height: 100%;
font-family: 'Segoe UI', sans-serif;
overflow: hidden;
scroll-behavior: smooth;
}
.background {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background: linear-gradient(135deg, #e6f7ff 0%, #f0f8ff 100%);
z-index: -3;
}
.wave-container {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
height: 60vh;
overflow: hidden;
z-index: -2;
}
.wave-layer {
position: absolute;
bottom: 0;
left: 0;
width: 200%;
height: 100px;
background: transparent;
transform: translateX(-25%);
}
@keyframes wave {
0% { transform: translateX(0); }
100% { transform: translateX(-50%); }
}
.wave {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 100%;
background-repeat: repeat-x;
background-size: cover;
animation: wave 40s linear infinite;
opacity: 0.8;
z-index: -1;
}
.wave-1 {
animation-duration: 30s;
}
.wave-2 {
animation-duration: 40s;
z-index: -2;
}
.wave-3 {
animation-duration: 50s;
z-index: -3;
}
.light-layer {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: radial-gradient(circle at 50% 30%, rgba(0, 153, 153, 0.15), transparent 70%);
z-index: -1;
pointer-events: none;
}
.glow-point {
position: absolute;
width: 50px;
height: 50px;
border-radius: 50%;
background: radial-gradient(circle, rgba(0, 153, 153, 0.2) 0%, transparent 70%);
filter: blur(30px);
animation: float 15s ease-in-out infinite;
z-index: 0;
}
@keyframes float {
0%, 100% { transform: translateY(0) rotate(0); }
50% { transform: translateY(-30px) rotate(180deg); }
}
.content {
position: relative;
height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
color: #003333;
text-align: center;
padding: 2rem;
z-index: 3;
}
.error-code {
font-size: 10vw;
font-weight: 900;
color: #008888;
text-shadow: 0 5px 15px rgba(0, 136, 136, 0.1);
line-height: 1;
margin-bottom: 1rem;
animation: pulse 2s infinite;
position: relative;
z-index: 2;
}
.error-code::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 150%;
height: 150%;
background: radial-gradient(circle, rgba(0, 153, 153, 0.05) 0%, transparent 70%);
transform: translate(-50%, -50%);
z-index: -1;
animation: glow 4s ease-in-out infinite alternate;
}
@keyframes pulse {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.03); }
}
@keyframes glow {
0% { transform: translate(-50%, -50%) scale(1); opacity: 0.8; }
100% { transform: translate(-50%, -50%) scale(1.2); opacity: 0.4; }
}
.message {
font-size: 1.8rem;
margin-bottom: 3rem;
max-width: 600px;
color: #006666;
animation: fadeIn 1s ease-out forwards;
animation-delay: 0.5s;
z-index: 2;
position: relative;
opacity: 0;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
.ip-info {
position: absolute;
bottom: 12vh;
left: 50%;
transform: translateX(-50%);
padding: 1.5rem 2rem;
background: rgba(255, 255, 255, 0.7);
border-radius: 1.2rem;
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
box-shadow: 0 5px 20px rgba(0, 102, 102, 0.1);
width: 90%;
max-width: 600px;
text-align: left;
display: flex;
flex-direction: column;
gap: 0.8rem;
animation: fadeInUp 1s ease-out forwards;
z-index: 4;
border: 1px solid rgba(0, 102, 102, 0.1);
}
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateX(-50%) translateY(20px);
}
to {
opacity: 1;
transform: translateX(-50%) translateY(0);
}
}
.ip-label {
font-weight: 600;
color: #004444;
}
.ip-value {
font-weight: 500;
color: #005555;
}
.back-button {
padding: 1rem 2rem;
background: rgba(0, 102, 102, 0.1);
color: #006666;
border: none;
border-radius: 0.5rem;
font-size: 1.2rem;
cursor: pointer;
transition: all 0.3s ease;
box-shadow: 0 5px 15px rgba(0, 102, 102, 0.1);
backdrop-filter: blur(5px);
-webkit-backdrop-filter: blur(5px);
border: 1px solid rgba(0, 102, 102, 0.2);
animation: pulseButton 3s infinite;
z-index: 3;
}
@keyframes pulseButton {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.03); }
}
.back-button:hover {
background: rgba(0, 102, 102, 0.2);
transform: scale(1.05);
box-shadow: 0 8px 20px rgba(0, 102, 102, 0.2);
}
.particle {
position: absolute;
border-radius: 50%;
background: rgba(0, 153, 153, 0.1);
animation: particleMove infinite linear;
z-index: 0;
pointer-events: none;
}
@keyframes particleMove {
0% { transform: translateY(0) rotate(0); opacity: 0.3; }
50% { opacity: 0.8; }
100% { transform: translateY(-100vh) rotate(360deg); opacity: 0; }
}
@media (max-width: 768px) {
.ip-info {
bottom: 10vh;
}
.message {
font-size: 1.4rem;
}
.error-code {
font-size: 14vw;
}
}
</style>
</head>
<body>
<div class="background"></div>
<div class="wave-container">
<div class="wave-layer wave-1">
<svg class="wave" viewBox="0 0 1200 100" preserveAspectRatio="none">
<path fill="rgba(179, 224, 255, 0.3)" d="M0,32L48,42.7C96,53,192,75,288,74.7C384,75,480,53,576,48C672,43,768,53,864,64C960,75,1056,85,1152,80C1248,75,1344,53,1392,42.7L1440,32L1440,100L1392,100C1344,100,1248,100,1152,100C1056,100,960,100,864,100C768,100,672,100,576,100C480,100,384,100,288,100C192,100,96,100,48,100L0,100Z"></path>
</svg>
</div>
<div class="wave-layer wave-2">
<svg class="wave" viewBox="0 0 1200 100" preserveAspectRatio="none">
<path fill="rgba(179, 224, 255, 0.2)" d="M0,64L48,69.3C96,75,192,85,288,69.3C384,53,480,11,576,0C672,0,768,32,864,48C960,64,1056,64,1152,48C1248,32,1344,0,1392,0L1440,0L1440,100L1392,100C1344,100,1248,100,1152,100C1056,100,960,100,864,100C768,100,672,100,576,100C480,100,384,100,288,100C192,100,96,100,48,100L0,100Z"></path>
</svg>
</div>
<div class="wave-layer wave-3">
<svg class="wave" viewBox="0 0 1200 100" preserveAspectRatio="none">
<path fill="rgba(179, 224, 255, 0.15)" d="M0,96L48,90.7C96,85,192,75,288,58.7C384,43,480,21,576,32C672,43,768,85,864,90.7C960,96,1056,64,1152,64C1248,64,1344,96,1392,112L1440,128L1440,100L1392,100C1344,100,1248,100,1152,100C1056,100,960,100,864,100C768,100,672,100,576,100C480,100,384,100,288,100C192,100,96,100,48,100L0,100Z"></path>
</svg>
</div>
</div>
<div class="light-layer"></div>
<div class="glow-point" style="top: 20%; left: 15%; animation-duration: 15s;"></div>
<div class="glow-point" style="bottom: 20%; right: 25%; animation-duration: 20s;"></div>
<div class="glow-point" style="top: 50%; right: 10%; animation-duration: 18s;"></div>
<div id="particles-container"></div>
<div class="content">
<div class="error-code">404</div>
<div class="message">抱歉,您访问的页面不存在或已被移除</div>
<button class="back-button" id="back-btn">返回首页</button>
</div>
<div class="ip-info">
<div class="ip-label">您的访问信息</div>
<div class="ip-value" id="user-ip">正在获取IP地址...</div>
<div class="ip-value" id="ip-location">正在获取位置信息...</div>
</div>
<script>
function createParticles() {
const particleCount = 30;
const container = document.getElementById('particles-container');
for (let i = 0; i < particleCount; i++) {
const particle = document.createElement('div');
particle.className = 'particle';
particle.style.top = `${Math.random() * 100}%`;
particle.style.left = `${Math.random() * 100}%`;
particle.style.animationDuration = `${8 + Math.random() * 4}s`;
const size = 5 + Math.random() * 10;
particle.style.width = `${size}px`;
particle.style.height = `${size}px`;
particle.style.opacity = `${Math.random() * 0.5 + 0.2}`;
container.appendChild(particle);
}
}
document.addEventListener('DOMContentLoaded', () => {
createParticles();
const backBtn = document.getElementById('back-btn');
if (backBtn) {
backBtn.addEventListener('click', () => {
window.location.href = '/';
});
}
fetch('https://myip.ipip.net/')
.then(response => response.text())
.then(data => {
const ipMatch = data.match(/当前 IP:([\d\.]+)/);
const locationMatch = data.match(/来自于:(.+)/);
const ipEl = document.getElementById('user-ip');
const locEl = document.getElementById('ip-location');
if (ipEl) {
ipEl.textContent = ipMatch && ipMatch[1]
? `IP地址:${ipMatch[1]}`
: 'IP地址获取失败';
}
if (locEl) {
locEl.textContent = locationMatch && locationMatch[1]
? `地理位置:${locationMatch[1]}`
: '无法获取地理位置';
}
})
.catch(() => {
const ipEl = document.getElementById('user-ip');
const locEl = document.getElementById('ip-location');
if (ipEl) ipEl.textContent = 'IP地址获取失败';
if (locEl) locEl.textContent = '无法获取地理位置';
});
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment