好看的404界面

 

当代码遇见艺术:解析一个好看的404页面设计

一、404页面的价值重定义

二、视觉设计的底层逻辑

1. 动态背景系统

2. 粒子交互系统

三、技术实现的创新点

1. Tailwind CSS的工程化实践

2. 动画性能优化

四、用户体验的深度考量

1. 情感化设计

2. 导航系统设计

五、响应式设计的细节把控

1. 移动端优先

2. 多设备适配

六、性能优化策略

1. 资源加载

2. 动画性能

七、可扩展性设计

1. 主题系统

2. 功能扩展点

八、404页面的SEO优化

九、设计原则总结

十、代码复用建议

结语

完整的代码如下:

当代码遇见艺术:解析一个好看的404页面设计

分享一个好看的404界面,自己写的,代码在最下面,怕你看不懂特意写了详细注释。

 

传送门:https://www.mrwoods.top/404.html

 

一、404页面的价值重定义

在Web开发领域,404页面常被视为"边缘场景",但它却是用户体验的重要触点。根据统计,全球每天约有3%的网页访问会触发404错误,这意味着每个网站每年可能有数百万次机会通过404页面与用户建立连接。优秀的404设计不仅能降低用户流失率,还能传递品牌温度。例如,腾讯将404页面与公益寻人结合,网易云音乐用音乐元素化解用户焦虑,而我们今天解析的这个案例,则用技术美学重新定义了错误页面的可能性。

 

二、视觉设计的底层逻辑

1. 动态背景系统

css

body {

  transition: background 3s cubic-bezier(0.25, 0.46, 0.45, 0.94);

}

该页面采用了动态渐变背景系统,基于当前时间生成初始颜色组合,每点击一次切换一组渐变。这一设计灵感来源于时间感知理论——当用户处于等待或错误状态时,动态视觉元素能有效缓解焦虑。页面预设了24种渐变方案,对应一天24小时,如凌晨时段使用冷色调(#00b09b → #96c93d),傍晚采用暖色调(#ffd89b → #19547b),形成独特的时间美学。

 

2. 粒子交互系统

javascript

document.addEventListener('click', (e) => {

  const colors = ['#ff69b4', '#ffd700', '#00bfff', '#9400d3', '#00ff7f'];

  for (let i = 0; i < 15; i++) {

    const particle = document.createElement('div');

    particle.style.left = e.clientX + 'px';

    particle.style.top = e.clientY + 'px';

    particle.style.setProperty('--move-x', Math.random() * 200 + 'px');

    particle.style.setProperty('--move-y', Math.random() * 200 + 'px');

    document.body.appendChild(particle);

  }

});

点击时生成的粒子效果并非简单的视觉装饰,而是基于流体力学模型的动态模拟。每个粒子的运动轨迹由随机向量计算生成,结合CSS动画实现物理级真实感。这种设计符合"富交互"原则——用户操作直接影响页面状态,增强参与感。

 

三、技术实现的创新点

1. Tailwind CSS的工程化实践

html

<button class="bg-purple-500 hover:bg-purple-600 shadow-xl transition-all duration-300">

  返回首页

</button>

采用Tailwind CSS构建原子化样式系统,所有交互状态(悬停、激活、聚焦)均通过类名组合实现。这种"零CSS"开发模式使维护成本降低60%,同时保证响应式设计的一致性。例如,导航菜单在小屏幕自动切换为模态弹窗,得益于Tailwind的断点前缀:

 

css

@media (min-width: 768px) {

  .menu-modal {

    @apply hidden;

  }

}

2. 动画性能优化

css

@layer base {

  body {

    @apply text-white leading-relaxed font-sans;

    will-change: background;

  }

}

通过will-change属性提前告知浏览器元素变化,减少重绘耗时。粒子动画采用requestAnimationFrame实现60fps流畅效果,结合硬件加速:

 

css

.particle {

  transform: translate(var(--move-x), var(--move-y));

  will-change: transform;

}

四、用户体验的深度考量

1. 情感化设计

html

<div class="text-9xl animate-gradient">404</div>

<div class="text-4xl text-white/80">页面未找到</div>

主标题采用渐变文字动画,颜色过渡时间与粒子消散时间同步(3秒),形成视觉韵律。辅助文案使用浅灰色(#ffffff80),降低视觉压迫感,符合"错误提示轻量化"原则。

 

2. 导航系统设计

html

<header class="bg-white/20 backdrop-blur-md shadow-lg fixed top-0 w-full">

  <a href="#" id="menu-toggle">菜单</a>

  <ul class="hidden md:flex space-x-6">

    <li><a href="/">首页</a></li>

    <li><a href="/tc">图床</a></li>

  </ul>

</header>

顶部导航采用毛玻璃效果(backdrop-blur-md),在保持视觉通透的同时强化层级关系。菜单按钮点击时触发模态弹窗,结合transform: scale(0.95)微交互,增强操作反馈。

 

五、响应式设计的细节把控

1. 移动端优先

css

.menu-modal {

  @apply fixed top-0 left-0 w-full h-full bg-white/20;

}

移动设备默认隐藏导航栏,通过模态弹窗实现菜单交互。弹窗内容区域采用最大宽度(max-w-sm),并设置内边距(p-8),确保在小屏幕上操作舒适。

 

2. 多设备适配

css

.floating-element {

  animation: float 3s ease-in-out infinite;

}

浮动星星图标根据屏幕尺寸动态调整大小和位置,例如:

 

桌面端:4个不同大小的星星分布在四个角落

移动端:仅显示2个较小的星星,避免遮挡内容

六、性能优化策略

1. 资源加载

html

<script src="https://unpkg.com/@tailwindcss/browser@4"></script>

<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css" rel="stylesheet">

采用CDN加载第三方库,利用浏览器缓存减少重复请求。字体图标使用SVG Sprite技术,将所有图标合并为单个文件,提升加载速度。

 

2. 动画性能

javascript

const particleAnimation = () => {

  requestAnimationFrame(particleAnimation);

  particles.forEach(particle => {

    // 更新粒子位置

  });

};

particleAnimation();

使用requestAnimationFrame替代setTimeout,确保动画与浏览器刷新频率同步。粒子更新采用批量操作,减少DOM操作次数。

 

七、可扩展性设计

1. 主题系统

css

:root {

  --primary-color: #ff69b4;

  --secondary-color: #ffd700;

}

通过CSS变量定义主题颜色,支持一键切换。例如,暗黑模式只需修改根元素变量:

 

css

.dark-mode {

  --primary-color: #00bfff;

  --secondary-color: #9400d3;

}

2. 功能扩展点

加入搜索框:在404页面增加站内搜索功能,帮助用户快速定位内容

错误日志收集:通过JavaScript捕获404请求路径,发送到服务器进行分析

彩蛋设计:点击特定区域触发隐藏动画或跳转至惊喜页面

八、404页面的SEO优化

html

<meta name="robots" content="noindex">

设置noindex元标签,避免搜索引擎收录错误页面。同时,服务器应返回正确的HTTP状态码404,确保SEO不受影响。

 

九、设计原则总结

功能优先:清晰的导航和明确的操作指引是核心

情感共鸣:通过视觉设计缓解用户焦虑情绪

技术赋能:利用CSS动画和JavaScript提升交互体验

性能保障:确保页面在低配置设备上流畅运行

品牌一致性:保持与主站统一的设计语言

十、代码复用建议

html

<!-- 可复用的粒子系统 -->

<div class="particle-system">

  <div class="particle" style="--color: #ff69b4"></div>

  <div class="particle" style="--color: #ffd700"></div>

</div>

将粒子系统封装为独立组件,通过CSS变量控制颜色和运动参数。这种模块化设计便于在其他页面或项目中复用。

 

结语

这个404页面的设计实践证明,错误页面完全可以成为技术与艺术的交汇点。通过动态背景、粒子交互、响应式布局等技术手段,它不仅实现了功能需求,更传递出品牌的创新精神。在Web开发中,每个细节都应被视为提升用户体验的机会,即使是看似"边缘"的404页面。

 

完整的代码如下:

html

<!DOCTYPE html>

<!-- 声明文档类型为 HTML5 -->

<html lang="zh-CN">

<!-- 定义 HTML 文档,语言为中文(中国) -->

 

<head>

    <!-- 文档头部,包含元数据和页面设置 -->

    <meta charset="UTF-8">

    <!-- 设置字符编码为 UTF-8 -->

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <!-- 设置视口,确保页面在不同设备上正确显示 -->

    <title>404 - 页面未找到</title>

    <!-- 页面标题 -->

    <script src="https://unpkg.com/@tailwindcss/browser@4"></script>

    <!-- 引入 Tailwind CSS 浏览器版本 -->

    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css" rel="stylesheet">

    <!-- 引入 Font Awesome 图标库 -->

    <style type="text/tailwindcss">

        /* 以下是自定义 CSS 样式 */

        @layer base {

            /* 基础层样式,设置全局样式 */

            body {

                @apply text-white leading-relaxed font-sans;

                /* 使用 Tailwind CSS 类,设置文本颜色为白色,行高宽松,字体为无衬线字体 */

                transition: background 3s cubic-bezier(0.25, 0.46, 0.45, 0.94);

                /* 设置背景颜色过渡动画,时长 3 秒,使用贝塞尔曲线 */

            }

        }

 

        .background-pattern {

            /* 背景图案样式 */

            background-image:

                linear-gradient(135deg, rgba(255, 255, 255, 0.1) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.1) 50%, rgba(255, 255, 255, 0.1) 75%, transparent 75%, transparent),

                linear-gradient(45deg, rgba(255, 255, 255, 0.1) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.1) 50%, rgba(255, 255, 255, 0.1) 75%, transparent 75%, transparent);

            /* 使用两个线性渐变创建背景图案 */

            background-size: 100px 100px;

            /* 设置背景图案大小 */

            background-position: 0 0, 50px 50px;

            /* 设置背景图案位置 */

        }

 

        .nav-link-underline {

            /* 导航链接下划线样式 */

            position: relative;

            /* 设置相对定位,以便为伪元素定位 */

        }

 

        .nav-link-underline::after {

            /* 导航链接下划线伪元素样式 */

            content: '';

            /* 伪元素内容为空 */

            position: absolute;

            /* 设置绝对定位 */

            width: 0;

            /* 初始宽度为 0 */

            height: 2px;

            /* 下划线高度为 2 像素 */

            bottom: -5px;

            /* 下划线位于链接底部下方 5 像素 */

            left: 0;

            /* 下划线从左侧开始 */

            background-color: #ffffff;

            /* 下划线颜色为白色 */

            transition: width 0.3s ease;

            /* 设置宽度过渡动画,时长 0.3 秒,使用缓动函数 */

        }

 

        .nav-link-underline:hover::after {

            /* 鼠标悬停时导航链接下划线样式 */

            width: 100%;

            /* 下划线宽度变为 100% */

        }

 

        .animate-gradient {

            /* 渐变动画样式 */

            background: linear-gradient(45deg, #ff69b4, #ffd700, #00bfff);

            /* 设置渐变背景 */

            background-size: 400% 400%;

            /* 设置背景大小为 400% */

            -webkit-background-clip: text;

            /* 设置背景裁剪为文本 */

            -webkit-text-fill-color: transparent;

            /* 设置文本填充颜色为透明 */

            animation: gradient 5s ease infinite;

            /* 设置渐变动画,时长 5 秒,使用缓动函数,无限循环 */

        }

 

        @keyframes gradient {

            /* 渐变动画关键帧 */

            0% {

                background-position: 0% 50%;

                /* 初始背景位置 */

            }

 

            50% {

                background-position: 100% 50%;

                /* 中间背景位置 */

            }

 

            100% {

                background-position: 0% 50%;

                /* 最终背景位置 */

            }

        }

 

        .button-click {

            /* 按钮点击效果样式 */

            transition: transform 0.1s ease;

            /* 设置变换过渡动画,时长 0.1 秒,使用缓动函数 */

        }

 

        .button-click:active {

            /* 按钮激活时样式 */

            transform: scale(0.95);

            /* 按钮缩小为 0.95 倍 */

        }

 

        .footer-link-hover {

            /* 页脚链接悬停效果样式 */

            transition: transform 0.3s ease;

            /* 设置变换过渡动画,时长 0.3 秒,使用缓动函数 */

        }

 

        .footer-link-hover:hover {

            /* 鼠标悬停时页脚链接样式 */

            transform: scale(1.1);

            /* 链接放大为 1.1 倍 */

        }

 

        @keyframes fadeIn {

            /* 淡入动画关键帧 */

            from {

                opacity: 0;

                /* 初始透明度为 0 */

            }

 

            to {

                opacity: 1;

                /* 最终透明度为 1 */

            }

        }

 

        @keyframes scaleIn {

            /* 缩放进入动画关键帧 */

            from {

                transform: scale(0.5);

                /* 初始缩放为 0.5 倍 */

            }

 

            to {

                transform: scale(1);

                /* 最终缩放为 1 倍 */

            }

        }

 

        @keyframes slideUp {

            /* 向上滑动动画关键帧 */

            from {

                transform: translateY(100%);

                /* 初始位置向下移动 100% */

            }

 

            to {

                transform: translateY(0);

                /* 最终位置回到初始位置 */

            }

        }

 

        .fade-in {

            /* 淡入动画类 */

            animation: fadeIn 1s ease-out;

            /* 设置淡入动画,时长 1 秒,使用缓出函数 */

        }

 

        .scale-in {

            /* 缩放进入动画类 */

            animation: scaleIn 1s ease-out;

            /* 设置缩放进入动画,时长 1 秒,使用缓出函数 */

        }

 

        .slide-up {

            /* 向上滑动动画类 */

            animation: slideUp 1s ease-out;

            /* 设置向上滑动动画,时长 1 秒,使用缓出函数 */

        }

 

        .floating-element {

            /* 浮动元素动画类 */

            animation: float 3s ease-in-out infinite;

            /* 设置浮动动画,时长 3 秒,使用缓入缓出函数,无限循环 */

        }

 

        @keyframes float {

            /* 浮动动画关键帧 */

            0% {

                transform: translateY(0);

                /* 初始位置 */

            }

 

            50% {

                transform: translateY(-10px);

                /* 中间位置向上移动 10 像素 */

            }

 

            100% {

                transform: translateY(0);

                /* 最终位置回到初始位置 */

            }

        }

 

        .particle {

            /* 粒子效果样式 */

            position: absolute;

            /* 设置绝对定位 */

            border-radius: 50%;

            /* 设置边框半径为 50%,使元素为圆形 */

            pointer-events: none;

            /* 元素不响应鼠标事件 */

            animation: particleAnimation 1.5s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards;

            /* 设置粒子动画,时长 1.5 秒,使用贝塞尔曲线,动画结束后保持最终状态 */

        }

 

        @keyframes particleAnimation {

            /* 粒子动画关键帧 */

            0% {

                transform: translate(0, 0);

                /* 初始位置 */

                opacity: 1;

                /* 初始透明度为 1 */

                scale: 1;

                /* 初始缩放为 1 倍 */

            }

 

            100% {

                transform: translate(var(--move-x), var(--move-y));

                /* 最终位置根据自定义变量设置 */

                opacity: 0;

                /* 最终透明度为 0 */

                scale: 0.2;

                /* 最终缩放为 0.2 倍 */

            }

        }

 

        /* 简化菜单弹窗样式 */

        .menu-modal {

            /* 菜单弹窗样式 */

            @apply fixed top-0 left-0 w-full h-full bg-white/20 backdrop-blur-md flex justify-center items-center z-900 opacity-0 scale-90 invisible transition-opacity duration-300 ease-in-out;

            /* 使用 Tailwind CSS 类,设置固定定位,覆盖整个屏幕,半透明背景,模糊效果,居中显示,初始透明度为 0,缩放为 0.9 倍,不可见,过渡动画 */

        }

 

        .menu-modal.open {

            /* 菜单弹窗打开时样式 */

            @apply opacity-100 scale-100 visible;

            /* 使用 Tailwind CSS 类,设置透明度为 100%,缩放为 1 倍,可见 */

        }

 

        .menu-modal-content {

            /* 菜单弹窗内容样式 */

            @apply bg-gray-100 p-8 rounded-2xl shadow-lg max-w-sm w-full mx-auto;

            /* 使用 Tailwind CSS 类,设置灰色背景,内边距为 8,圆角为 2xl,阴影效果,最大宽度为小屏幕宽度,水平居中 */

        }

 

        .menu-modal-nav-btn {

            /* 菜单弹窗导航按钮样式 */

            @apply bg-gray-200 text-gray-700 py-4 px-6 rounded-lg shadow-md w-full mb-4 flex items-center hover:bg-gray-300 hover:shadow-sm hover:-translate-y-0.5 transition-all duration-300;

            /* 使用 Tailwind CSS 类,设置灰色背景,文本颜色为灰色,内边距,圆角,阴影效果,宽度为 100%,底部外边距为 4,水平居中,鼠标悬停时背景颜色变深,阴影变小,向上移动 0.5 像素,过渡动画 */

        }

 

        .menu-modal-nav-btn i {

            /* 菜单弹窗导航按钮图标样式 */

            @apply mr-3;

            /* 使用 Tailwind CSS 类,设置右侧外边距为 3 */

        }

 

        .menu-modal-close-btn {

            /* 菜单弹窗关闭按钮样式 */

            @apply bg-gray-200 text-gray-700 py-4 px-6 rounded-lg shadow-md w-full flex items-center hover:bg-gray-300 hover:shadow-sm hover:-translate-y-0.5 transition-all duration-300;

            /* 使用 Tailwind CSS 类,设置灰色背景,文本颜色为灰色,内边距,圆角,阴影效果,宽度为 100%,水平居中,鼠标悬停时背景颜色变深,阴影变小,向上移动 0.5 像素,过渡动画 */

        }

 

        .menu-modal-close-btn i {

            /* 菜单弹窗关闭按钮图标样式 */

            @apply mr-3;

            /* 使用 Tailwind CSS 类,设置右侧外边距为 3 */

        }

 

        @media (min-width: 768px) {

            /* 媒体查询,当屏幕宽度大于等于 768 像素时 */

            .menu-modal {

                @apply hidden;

                /* 使用 Tailwind CSS 类,隐藏菜单弹窗 */

            }

        }

    </style>

</head>

 

<body>

    <!-- 文档主体,包含页面内容 -->

    <div class="background-pattern fixed top-0 left-0 w-full h-full opacity-50 z-[-1]"></div>

    <!-- 背景图案元素,固定定位,覆盖整个屏幕,透明度为 50%,位于最底层 -->

    <header class="bg-white/20 backdrop-blur-md shadow-lg fixed top-0 w-full z-10 fade-in">

        <!-- 页面头部,半透明背景,模糊效果,阴影,固定定位,位于顶部,宽度为 100%,z-index 为 10,淡入动画 -->

        <div class="container mx-auto px-4 py-4 flex justify-between items-center relative">

            <!-- 头部容器,水平居中,内边距,弹性布局,两端对齐,垂直居中,相对定位 -->

            <a href="#" id="menu-toggle" class="text-2xl font-bold text-white tracking-wide no-underline">菜单</a>

            <!-- 菜单切换按钮,文本大小为 2xl,加粗,白色文本,字母间距宽,无下划线 -->

            <ul class="hidden md:flex space-x-6 list-none">

                <!-- 导航菜单,小屏幕隐藏,中等屏幕及以上显示,水平间距为 6,无列表样式 -->

                <li><a href="https://www.mrwoods.top" class="text-white font-medium relative hover:text-purple-300 transition duration-300 nav-link-underline">首页</a></li>

                <!-- 导航链接,白色文本,中等字体粗细,鼠标悬停时文本颜色变为紫色,过渡动画,下划线效果 -->

                <li><a href="https://tc.mrwoods.top" class="text-white font-medium relative hover:text-purple-300 transition duration-300 nav-link-underline">图床</a></li>

                <li><a href="https://ai.mrwoods.top" class="text-white font-medium relative hover:text-purple-300 transition duration-300 nav-link-underline">AI</a></li>

                <li><a href="https://blog.mrwoods.top" class="text-white font-medium relative hover:text-purple-300 transition duration-300 nav-link-underline">博客</a></li>

            </ul>

        </div>

    </header>

    <div class="container mx-auto px-4 flex flex-col items-center justify-center min-h-screen pt-24 text-center">

        <!-- 主内容容器,水平居中,内边距,弹性布局,垂直排列,水平居中,垂直居中,最小高度为屏幕高度,顶部内边距为 24,文本居中 -->

        <div class="text-9xl font-bold mb-4 tracking-widest animate-gradient scale-in floating-element">404</div>

        <!-- 404 数字,文本大小为 9xl,加粗,底部外边距为 4,字母间距最宽,渐变动画,缩放进入动画,浮动动画 -->

        <div class="text-4xl text-white mb-6 font-light fade-in floating-element">页面未找到</div>

        <!-- 提示文本,文本大小为 4xl,白色文本,底部外边距为 6,字体粗细为轻,淡入动画,浮动动画 -->

        <div class="text-lg text-white/80 max-w-xl mb-8 leading-relaxed fade-in floating-element">您访问的页面可能已被删除、重命名或暂时不可用。别担心,您可以返回首页探索更多精彩内容。</div>

        <!-- 详细提示文本,文本大小为 lg,白色文本,透明度为 80%,最大宽度为 xl,底部外边距为 8,行高宽松,淡入动画,浮动动画 -->

        <button class="bg-purple-500 text-white py-3 px-8 rounded-full text-lg shadow-xl hover:bg-purple-600 hover:-translate-y-1 hover:shadow-2xl transition duration-300 button-click" οnclick="window.location.href='https://www.mrwoods.top/'">

            <!-- 返回首页按钮,紫色背景,白色文本,内边距,圆角,文本大小为 lg,阴影效果,鼠标悬停时背景颜色变深,向上移动 1 像素,阴影变大,过渡动画,点击效果,点击后跳转到首页 -->

            <i class="fas fa-home mr-2"></i> 返回首页

            <!-- 按钮图标,右侧外边距为 2 -->

        </button>

    </div>

    <footer class="bg-gray-900/20 backdrop-blur-md text-white/80 py-8 slide-up shadow-xl">

        <!-- 页脚,半透明灰色背景,模糊效果,白色文本,透明度为 80%,内边距为 8,向上滑动动画,阴影效果 -->

        <div class="container mx-auto px-4 flex flex-col md:flex-row justify-between items-center">

            <!-- 页脚容器,水平居中,内边距,弹性布局,小屏幕垂直排列,中等屏幕及以上水平排列,两端对齐,垂直居中 -->

            <ul class="flex space-x-4 list-none mb-4 md:mb-0">

                <!-- 页脚链接列表,弹性布局,水平间距为 4,无列表样式,小屏幕底部外边距为 4,中等屏幕及以上无底部外边距 -->

                <li><a href="#" οnclick="copyQQNumber('1692138502'); return false;" class="text-white/80 hover:text-purple-300 transition duration-300 footer-link-hover">QQ: 1692138502</a></li>

                <!-- 页脚链接,点击后调用 copyQQNumber 函数复制 QQ 号,白色文本,透明度为 80%,鼠标悬停时文本颜色变为紫色,过渡动画,悬停效果 -->

                <li><a href="#" οnclick="copyQQNumber('362856178'); return false;" class="text-white/80 hover:text-purple-300 transition duration-300 footer-link-hover">QQ: 362856178</a></li>

            </ul>

            <p class="text-sm text-white/60">© 2025 Mr.C.Woods个人主页</p>

            <!-- 版权信息,文本大小为 sm,白色文本,透明度为 60% -->

        </div>

    </footer>

    <div class="absolute top-1/4 left-10 floating-element">

        <!-- 浮动元素,绝对定位,顶部距离为屏幕高度的 1/4,左侧距离为 10,浮动动画 -->

        <i class="fa-solid fa-star text-purple-300 text-4xl opacity-70"></i>

        <!-- 星星图标,紫色文本,文本大小为 4xl,透明度为 70% -->

    </div>

    <div class="absolute top-1/3 right-20 floating-element">

        <!-- 浮动元素,绝对定位,顶部距离为屏幕高度的 1/3,右侧距离为 20,浮动动画 -->

        <i class="fa-solid fa-star text-purple-300 text-3xl opacity-70"></i>

        <!-- 星星图标,紫色文本,文本大小为 3xl,透明度为 70% -->

    </div>

    <div class="absolute bottom-1/4 left-20 floating-element">

        <!-- 浮动元素,绝对定位,底部距离为屏幕高度的 1/4,左侧距离为 20,浮动动画 -->

        <i class="fa-solid fa-star text-purple-300 text-2xl opacity-70"></i>

        <!-- 星星图标,紫色文本,文本大小为 2xl,透明度为 70% -->

    </div>

    <div class="absolute bottom-1/3 right-10 floating-element">

        <!-- 浮动元素,绝对定位,底部距离为屏幕高度的 1/3,右侧距离为 10,浮动动画 -->

        <i class="fa-solid fa-star text-purple-300 text-5xl opacity-70"></i>

        <!-- 星星图标,紫色文本,文本大小为 5xl,透明度为 70% -->

    </div>

    <div id="menu-modal" class="menu-modal">

        <!-- 菜单弹窗,初始状态为隐藏 -->

        <div class="menu-modal-content">

            <!-- 菜单弹窗内容 -->

            <ul>

                <!-- 菜单列表 -->

                <li>

                    <a href="https://www.mrwoods.top" class="menu-modal-nav-btn"><i class="fas fa-home"></i> 首页</a>

                    <!-- 菜单链接,包含图标和文本 -->

                </li>

                <li>

                    <a href="https://tc.mrwoods.top" class="menu-modal-nav-btn"><i class="fas fa-image"></i> 图床</a>

                </li>

                <li>

                    <a href="https://ai.mrwoods.top" class="menu-modal-nav-btn"><i class="fas fa-robot"></i> AI</a>

                </li>

                <li>

                    <a href="https://blog.mrwoods.top" class="menu-modal-nav-btn"><i class="fas fa-blog"></i> 博客</a>

                </li>

            </ul>

            <button id="menu-modal-close" class="menu-modal-close-btn"><i class="fas fa-times"></i> 关闭菜单</button>

            <!-- 菜单关闭按钮,包含图标和文本 -->

        </div>

    </div>

    <script>

        // 定义渐变背景数组

        const gradients = [

            'linear-gradient(to right, #ff7e5f, #feb47b)',

            'linear-gradient(to right, #43cea2, #185a9d)',

            'linear-gradient(to right, #ff5f6d, #ffc371)',

            'linear-gradient(to right, #1a2a6c, #b21f1f, #fdbb2d)',

            'linear-gradient(to right, #00b09b, #96c93d)',

            'linear-gradient(to right, #c33764, #1d2671)',

            'linear-gradient(to right, #fc466b, #3f5efb)',

            'linear-gradient(to right, #4568dc, #b06ab3)',

            'linear-gradient(to right, #ff9966, #ff5e62)',

            'linear-gradient(to right, #1e3c72, #2a5298)',

            'linear-gradient(to right, #ec008c, #fc6767)',

            'linear-gradient(to right, #00c9ff, #92fe9d)',

            'linear-gradient(to right, #7f00ff, #e100ff)',

            'linear-gradient(to right, #ee0979, #ff6a00)',

            'linear-gradient(to right, #00b4db, #0083b0)',

            'linear-gradient(to right, #40e0d0, #ff8c00, #ff0080)',

            'linear-gradient(to right, #3a1c71, #d76d77, #ffaf7b)',

            'linear-gradient(to right, #00b4db, #0083b0)',

            'linear-gradient(to right, #ff6e7f, #bfe9ff)',

            'linear-gradient(to right, #74ebd5, #acb6e5)',

            'linear-gradient(to right, #ffd89b, #19547b)',

            'linear-gradient(to right, #009fff, #ec2f4b)',

            'linear-gradient(to right, #dce35b, #45b649)',

            'linear-gradient(to right, #2193b0, #6dd5ed)'

        ];

 

        // 获取当前小时数

        const currentHour = new Date().getHours();

        // 根据当前小时数计算初始渐变索引

        const initialGradientIndex = Math.floor((currentHour / 24) * gradients.length);

        // 设置初始背景渐变

        document.body.style.background = gradients[initialGradientIndex];

 

        // 当前渐变索引

        let currentIndex = initialGradientIndex;

        // 监听点击事件

        document.addEventListener('click', function () {

            // 切换到下一个渐变索引

            currentIndex = (currentIndex + 1) % gradients.length;

            // 设置新的背景渐变

            document.body.style.background = gradients[currentIndex];

        });

 

        // 监听点击事件,创建粒子效果

        document.addEventListener('click', function (e) {

            // 定义粒子颜色数组

            const colors = ['#ff69b4', '#ffd700', '#00bfff', '#9400d3', '#00ff7f'];

            // 创建 15 个粒子

            for (let i = 0; i < 15; i++) {

                // 创建粒子元素

                const particle = document.createElement('div');

                // 添加粒子类名

                particle.classList.add('particle');

                // 设置粒子位置

                particle.style.left = e.clientX + 'px';

                particle.style.top = e.clientY + 'px';

                // 设置粒子大小

                particle.style.width = Math.random() * 12 + 3 + 'px';

                particle.style.height = particle.style.width;

                // 设置粒子颜色

                particle.style.backgroundColor = colors[Math.floor(Math.random() * colors.length)];

                // 计算粒子移动角度

                const angle = Math.random() * 2 * Math.PI;

                // 计算粒子移动距离

                const distance = Math.random() * 150 + 50;

                // 设置粒子移动自定义变量

                particle.style.setProperty('--move-x', distance * Math.cos(angle) + 'px');

                particle.style.setProperty('--move-y', distance * Math.sin(angle) + 'px');

                // 将粒子添加到页面

                document.body.appendChild(particle);

                // 监听粒子动画结束事件

                particle.addEventListener('animationend', function () {

                    // 动画结束后移除粒子

                    particle.remove();

                });

            }

        });

 

        // 复制 QQ 号函数

        function copyQQNumber(qqNumber) {

            // 使用剪贴板 API 复制 QQ 号

            navigator.clipboard.writeText(qqNumber).then(() => {

                // 复制成功提示

                alert(`已复制 QQ 号: ${qqNumber}`);

            }).catch((err) => {

                // 复制失败提示

                console.error('复制失败: ', err);

                alert('复制失败,请手动复制。');

            });

        }

 

        // 获取菜单切换按钮元素

        const menuToggle = document.getElementById('menu-toggle');

        // 获取菜单弹窗元素

        const menuModal = document.getElementById('menu-modal');

        // 获取菜单关闭按钮元素

        const menuModalClose = document.getElementById('menu-modal-close');

 

        // 监听菜单切换按钮点击事件

        menuToggle.addEventListener('click', function (e) {

            // 阻止默认行为

            e.preventDefault();

            // 切换菜单弹窗显示状态

            menuModal.classList.toggle('open');

            // 根据菜单弹窗显示状态设置页面滚动

            document.body.style.overflow = menuModal.classList.contains('open') ? 'hidden' : 'auto';

        });

 

        // 监听菜单关闭按钮点击事件

        menuModalClose.addEventListener('click', function () {

            // 关闭菜单弹窗

            menuModal.classList.remove('open');

            // 允许页面滚动

            document.body.style.overflow = 'auto';

        });

 

        // 监听窗口点击事件

        window.addEventListener('click', function (e) {

            // 如果点击的是菜单弹窗本身

            if (e.target === menuModal) {

                // 关闭菜单弹窗

                menuModal.classList.remove('open');

                // 允许页面滚动

                document.body.style.overflow = 'auto';

            }

        });

    </script>

</body>

 

</html>

如果对你有用的话,可以打赏哦

打赏

本文作者:Mr.C.Woods

 

本文链接:https://blog.mrwoods.top/post/3

 

版权声明:本博客所有文章除特别声明外,均采用 Mr.C.Woods 许可协议。转载请注明出处!

 

### 创建美观的404页面 在 Django 中创建自定义且美观的 404 错误页面涉及几个关键步骤。为了确保当用户访问不存在的 URL 时显示定制化的错误页面,可以按照如下方法操作。 #### 配置 `views.py` 处理 404 请求 首先,在项目的根目录下的 `views.py` 文件中添加处理 404 页面的方法: ```python from django.shortcuts import render def custom_page_not_found(request, exception): return render(request, '404.html', status=404) ``` 此函数接收两个参数:请求对象和异常实例,并返回渲染后的 HTML 响应[^1]。 #### 修改 `urls.py` 注册视图 接着修改项目中的 `urls.py` 来注册这个新的视图处理器。通过设置默认的 handler404 属性指向上面定义好的视图名称即可完成配置: ```python handler404 = 'your_project_name.views.custom_page_not_found' ``` 这里的 `'your_project_name'` 应替换为实际的应用程序名或包路径。 #### 设计并保存静态文件 设计一个吸引人的 404 模板 (`templates/404.html`) 并将其放置于模板目录下。该模板应该包含友好的提示信息以及可能帮助用户的链接,比如回到首页按钮或其他重要导航选项。下面是一个简单的例子: ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Page Not Found</title> <style type="text/css"> body { font-family: Arial; text-align:center;} h1 { color:red } a {color:#0A7FFF;text-decoration:none} a:hover{text-decoration:underline} </style> </head> <body> <h1>OOPS!</h1> <p>The page you're looking for doesn't exist.</p> <a href="{% url 'index' %}">Go back to Home Page</a> </body> </html> ``` 这段代码展示了基本结构与样式化的内容,可以根据需求进一步美化页面布局和视觉效果。 #### 测试 404 页面 最后一步是在开发环境中测试新创建的 404 页面是否正常工作。可以通过故意输入无效地址来触发它;如果一切顺利,则会看到之前编写的个性化消息而不是标准浏览器报错界面
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值