写在前面
有没有想过,当用户误触失效链接时,跳出的不再是单调的 “404 错误”,而是一个兼具设计感与交互趣味的定制页面?今天就来分享一个高颜值、高适配性的 404 页面组件(react),源码直接复制即用,轻松为你的网站增添细节亮点!
页面效果
直接上源码
需要的依赖
npm install styled-components
在index.html头部引入
<link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC&display=swap" rel="stylesheet">
import React from 'react';
import styled, { keyframes } from 'styled-components';
// 水墨扩散动画
const inkSpread = keyframes`
0% { transform: scale(0.8); opacity: 0; }
100% { transform: scale(1); opacity: 0.2; } /* 降低不透明度避免干扰内容 */
`;
const Container = styled.div`
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 100vh;
background: #f9f5e9;
font-family: 'Noto Serif SC', serif;
padding: 2rem;
position: relative;
overflow: hidden;
`;
const InkBlot = styled.div`
position: absolute;
width: ${props => props.size}px;
height: ${props => props.size}px;
background: radial-gradient(circle, rgba(0,0,0,0.08) 0%, rgba(0,0,0,0) 70%);
border-radius: 50%;
animation: ${inkSpread} 3s ease-out forwards;
z-index: 0;
pointer-events: none; /* 防止干扰交互 */
`;
const Content = styled.div`
position: relative;
z-index: 1;
text-align: center;
max-width: 600px;
`;
const Svg404 = styled.svg`
width: 200px;
height: 200px;
margin-bottom: 2rem;
path {
stroke: #333;
stroke-width: 2;
fill: none;
stroke-dasharray: 1000;
stroke-dashoffset: 1000;
animation: brushStroke 3s ease-in-out forwards;
}
@keyframes brushStroke {
0% { stroke-dashoffset: 1000; }
100% { stroke-dashoffset: 0; }
}
`;
const Title = styled.h1`
font-size: 2.5rem;
color: #333;
font-weight: 400;
margin-bottom: 1rem;
letter-spacing: 5px;
`;
const Subtitle = styled.p`
font-size: 1.1rem;
color: #666;
line-height: 1.8;
margin-bottom: 2rem;
`;
const Button = styled.button`
padding: 12px 32px;
background: transparent;
color: #333;
border: 1px solid #333;
border-radius: 0;
font-size: 1rem;
cursor: pointer;
transition: all 0.3s ease;
position: relative;
overflow: hidden;
&:before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.05);
transition: all 0.3s ease;
}
&:hover {
background: rgba(0,0,0,0.02);
&:before {
left: 0;
}
}
`;
const NotFoundPage = () => {
// 创建6个不同位置、大小的水墨团
const inkBlots = [
{ id: 1, size: 250, top: '10%', left: '5%', delay: '0s' },
{ id: 2, size: 300, top: '15%', right: '5%', delay: '0.5s' },
{ id: 3, size: 200, bottom: '20%', left: '10%', delay: '1s' },
{ id: 4, size: 350, bottom: '15%', right: '5%', delay: '1.5s' },
{ id: 5, size: 180, top: '60%', left: '15%', delay: '0.8s' },
{ id: 6, size: 220, top: '30%', right: '20%', delay: '1.2s' }
];
return (
<Container>
{/* 水墨背景元素 */}
{inkBlots.map(blot => (
<InkBlot
key={blot.id}
size={blot.size}
style={{
top: blot.top,
left: blot.left,
right: blot.right,
bottom: blot.bottom,
animationDelay: blot.delay
}}
/>
))}
{/* 原有内容保持不变 */}
<Content>
<Svg404 viewBox="0 0 200 100">
<path d="M30,80 L30,20 M30,50 L70,10 M70,10 L70,80" />
<path d="M90,80 C90,20 150,20 150,80 C150,140 90,140 90,80 Z" />
<path d="M170,80 L170,20 M170,50 L210,10 M210,10 L210,80" />
</Svg404>
<Title>页面未寻得</Title>
<Subtitle>
所觅之页,如墨入水,散于无形<br />
或返首页,或观他处,皆可随心
</Subtitle>
<Button onClick={() => window.location.href = '/'}>
返回首页
</Button>
</Content>
</Container>
);
};
export default NotFoundPage;
结语
404 页面不再是 “被遗忘的角落”,而是展现品牌调性与用户关怀的窗口。无论是简洁的企业官网,还是充满创意的个人博客,这个可复用的组件都能为你的网站注入一丝巧思。