静态个人页面的开发

{CF8148AE-3769-4292-9006-950015F90550}.png

火芯的小窝 - 个人主页技术解析(后续更改不更新文章!)

项目地址https://www.hxdxw.cn
技术栈:原生 HTML + CSS + JavaScript,无任何框架依赖

这是一个极简风格个人主页,采用「单页 + 组件化」架构。页面仅包含四个核心组件:

  • 👤 头像卡片:带动画气泡的个人资料展示
  • 🔗 导航按钮:跳转到博客等子站
  • 🎵 音乐播放器:悬浮式 HTML5 播放器
  • 🌙 主题切换:支持明/暗模式一键切换
设计理念:简约不简单,每个组件都经过精心打磨。

📑 目录


目录结构

www.hxdxw.cn/
├── index.html          # 主页面
├── style.css           # 全局样式
├── CNAME               # 域名配置
├── nginx.htaccess     # Nginx 配置
├── README.md           # 项目说明
└── xf-MusicPlayer/    # 音乐播放器组件
    ├── js/
    ├── css/
    ├── icon/
    ├── images/
    └── README.md

HTML 结构

整个页面结构清晰,采用语义化标签:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>火芯的小窝</title>
  <link rel="stylesheet" href="style.css" />
</head>
<body>

  <!-- 主题切换按钮 -->
  <button class="theme-toggle" id="theme-toggle" aria-label="切换主题">
    <svg id="theme-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
      <!-- 太阳图标(白天) -->
      <circle cx="12" cy="12" r="5"/>
      <path d="M12 1v2M12 21v2M4.22 4.22l1.42 1.42..."/>
    </svg>
  </button>

  <!-- 个人资料卡片 -->
  <section class="profile-wrap" aria-label="个人资料">
    <div class="avatar-wrap">
      <!-- 气泡(悬停显示) -->
      <div class="bubble" aria-hidden="true">Hello World!</div>
      <!-- 头像 -->
      <img class="avatar" 
           src="https://q1.qlogo.cn/g?b=qq&nk=915678975&s=640" 
           alt="火芯Ah 的头像" />
    </div>
    <div class="profile-info">
      <p class="profile-name">火芯Ah</p>
      <p class="profile-desc">这是一句个人描述。</p>
    </div>
  </section>

  <!-- 导航按钮 -->
  <nav class="nav-buttons" aria-label="站点导航">
    <a class="nav-btn" href="http://blog.hxdxw.cn" target="_blank">
      <svg>...</svg>
      <span>火芯の博客</span>
    </a>
  </nav>

  <!-- 音乐播放器 -->
  <div id="xf-MusicPlayer"
       data-fadeOutAutoplay
       data-themeColor="xf-wineRed"
       data-randomSongList="1">
  </div>
  <script src="/xf-MusicPlayer/js/xf-MusicPlayer.min.js"></script>

</body>
</html>

设计要点

  • aria-label 提供无障碍访问支持
  • SVG 图标内联,无额外请求
  • 播放器通过 data-* 属性配置,开箱即用

CSS 架构

1. CSS 变量系统

使用 CSS Custom Properties 实现主题切换:

/* 明亮主题变量 */
:root {
  --bg: #f5f5f7;
  --card-bg: #ffffff;
  --text-primary: #1d1d1f;
  --text-secondary: #6e6e73;
  --accent: #0071e3;
  --accent-hover: #0077ed;
  --shadow-sm: 0 2px 8px rgba(0,0,0,.08);
  --shadow-md: 0 8px 32px rgba(0,0,0,.12);
  --radius: 18px;
  --transition: .3s cubic-bezier(.4,0,.2,1);
}

/* 暗色主题变量 */
[data-theme="dark"] {
  --bg: #292929;
  --card-bg: #393939;
  --text-primary: #f5f5f5;
  --text-secondary: #b0b0b0;
  --accent: #0a84ff;
  --accent-hover: #1a9cff;
  --shadow-sm: 0 2px 8px rgba(0,0,0,.28);
  --shadow-md: 0 8px 32px rgba(0,0,0,.35);
}

优势

  • 只需切换 data-theme 属性,所有颜色自动切换
  • 变量统一管理,维护成本低
  • cubic-bezier 自定义缓动曲线,过渡更自然

2. 头像卡片组件

/* 头像容器 */
.avatar-wrap {
  position: relative;
  flex-shrink: 0;
}

/* 气泡 - 默认隐藏 */
.bubble {
  position: absolute;
  bottom: calc(100% - 8px);   /* 紧贴头像顶部 */
  left: calc(100% - 8px);     /* 紧贴头像右侧 */
  background: var(--accent);
  color: #fff;
  font-size: 12px;
  padding: 5px 10px;
  border-radius: 12px 12px 12px 0;  /* 左下角直角 → 尖角 */
  opacity: 0;
  transform: scale(.7) translateY(4px);
  transform-origin: bottom left;
  transition: opacity var(--transition), transform var(--transition);
  pointer-events: none;
}

/* 气泡尖角 */
.bubble::after {
  content: '';
  position: absolute;
  bottom: -6px;
  left: 0;
  border-width: 6px 6px 0 0;
  border-style: solid;
  border-color: var(--accent) transparent transparent transparent;
}

/* 头像 */
.avatar {
  width: 96px;
  height: 96px;
  border-radius: 50%;
  object-fit: cover;
  box-shadow: var(--shadow-md);
  cursor: pointer;
  transition: transform var(--transition), box-shadow var(--transition);
  border: 3px solid var(--card-bg);
}

/* 悬停时气泡 + 头像动画 */
.profile-wrap:hover .bubble {
  opacity: 1;
  transform: scale(1) translateY(0);
}
.profile-wrap:hover .avatar {
  transform: scale(1.05);
  box-shadow: 0 12px 40px rgba(0,0,0,.16);
}

技术亮点

  • transform-origin: bottom left 控制气泡从尖角处展开
  • calc() 精确定位气泡尖角指向头像
  • 悬停时双重动画:气泡淡入 + 头像缩放

3. 导航按钮

.nav-btn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 10px 22px;
  font-size: 14px;
  font-weight: 500;
  color: var(--text-primary);
  background: var(--card-bg);
  border: 1.5px solid rgba(0,0,0,.08);
  border-radius: 50px;
  text-decoration: none;
  box-shadow: var(--shadow-sm);
  position: relative;
  overflow: hidden;  /* 关键:裁剪伪元素 */
  transition: color var(--transition), border-color var(--transition),
              box-shadow var(--transition), transform var(--transition);
}

/* 渐变背景层 */
.nav-btn::before {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(135deg, var(--accent) 0%, #5ac8fa 100%);
  opacity: 0;
  transition: opacity var(--transition);
  border-radius: inherit;
  z-index: 0;
}

/* 文字和图标提升到最上层 */
.nav-btn span,
.nav-btn svg {
  position: relative;
  z-index: 1;
}

/* 悬停效果 */
.nav-btn:hover::before {
  opacity: 1;
}
.nav-btn:hover {
  color: #fff;
  border-color: transparent;
  box-shadow: 0 6px 24px rgba(0,113,227,.28);
  transform: translateY(-2px);
}

设计亮点

  • 伪元素实现渐变填充效果
  • position: relative + z-index 控制层叠顺序
  • inset: 0 简写替代 top/right/bottom/left: 0

4. 主题切换

.theme-toggle {
  position: fixed;
  bottom: 20px;
  right: 20px;
  width: 35px;
  height: 35px;
  border-radius: 50%;
  background: var(--card-bg);
  border: 1.5px solid rgba(0,0,0,.08);
  box-shadow: var(--shadow-sm);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all var(--transition);
  z-index: 1000;
}

.theme-toggle:hover {
  transform: scale(1.1);
  box-shadow: var(--shadow-md);
}

.theme-toggle svg {
  width: 24px;
  height: 24px;
  color: var(--text-primary);
  transition: color var(--transition);
}

/* 暗色模式下边框变亮 */
[data-theme="dark"] .theme-toggle {
  border-color: rgba(255,255,255,.1);
}

JavaScript 功能

1. 主题切换逻辑

// 获取元素
const themeToggle = document.getElementById('theme-toggle');
const themeIcon = document.getElementById('theme-icon');
const html = document.documentElement;

// 检查系统偏好和本地存储
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
const savedTheme = localStorage.getItem('theme');

// 初始化主题
if (savedTheme) {
  html.setAttribute('data-theme', savedTheme);
  updateIcon(savedTheme);
} else if (prefersDark) {
  html.setAttribute('data-theme', 'dark');
  updateIcon('dark');
}

// 点击切换
themeToggle.addEventListener('click', () => {
  const currentTheme = html.getAttribute('data-theme');
  const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
  
  html.setAttribute('data-theme', newTheme);
  localStorage.setItem('theme', newTheme);  // 持久化
  updateIcon(newTheme);
});

// 更新图标(太阳 ↔ 月亮)
function updateIcon(theme) {
  if (theme === 'dark') {
    // 月亮图标
    themeIcon.innerHTML = `<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/>`;
  } else {
    // 太阳图标
    themeIcon.innerHTML = `
      <circle cx="12" cy="12" r="5"/>
      <path d="M12 1v2M12 21v2M4.22 4.22l1.42 1.42..."/>
    `;
  }
}

优先级:用户选择 > 系统偏好 > 默认(light)


2. 系统偏好监听

// 监听系统主题变化
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {
  // 仅当用户未手动选择主题时响应
  if (!localStorage.getItem('theme')) {
    const newTheme = e.matches ? 'dark' : 'light';
    html.setAttribute('data-theme', newTheme);
    updateIcon(newTheme);
  }
});

音乐播放器组件

播放器采用第三方插件 xf-MusicPlayer,配置简单:

<div id="xf-MusicPlayer"
     data-fadeOutAutoplay      <!-- 淡出自动播放 -->
     data-themeColor="xf-wineRed"  <!-- 酒红主题 -->
     data-randomSongList="1">  <!-- 随机歌单 -->
</div>
<script src="/xf-MusicPlayer/js/xf-MusicPlayer.min.js"></script>

支持的 data 属性

属性说明可选值
data-themeColor主题颜色xf-original, xf-sky, xf-orange, xf-wineRed, xf-girlPink
data-randomSongList随机歌单1 或空
data-songChart歌榜类型热歌榜, 新歌榜, 飙升榜, 原创榜
data-songList歌单ID网易云歌单ID
data-memory记忆播放1
data-bottomHeight底部距离100px

文件结构

huoxin_cn/
├── index.html           # 主页面(简洁单文件)
├── style.css           # 全局样式(约230行)
├── CNAME               # hxdxw.cn 域名
├── nginx.htaccess      # Nginx 配置(CDN/缓存)
├── README.md           # 项目说明
└── xf-MusicPlayer/    # 第三方播放器组件
    ├── js/             # 播放器脚本
    ├── css/            # 播放器样式
    ├── icon/           # 图标字体
    └── images/          # 默认封面

技术总结

技术点应用场景
CSS Custom Properties主题切换系统
CSS 变量覆盖暗色模式实现
::before / ::after气泡、渐变背景
transform + transition悬停动画效果
localStorage用户偏好持久化
matchMedia API系统主题监听
data-* 属性组件配置化
第三方组件集成音乐播放器

设计理念

  • 极简主义:页面干净清爽,无多余元素
  • 细节打磨:每个动画、每处交互都经过思考
  • 配置优先:通过 HTML 属性而非 JS 配置组件

希望这篇解析对你理解前端项目开发有所帮助! 🚀

个人页面预览:www.hxdxw.cn
个人页面github仓库:https://github.com/shihuoxin/hxdxw.github.io
xf-MusicPlayer作者github仓库:https://github.com/cenguigui/xf-MusicPlayer-master

评论区:

    桀桀桀
    桀桀桀 1楼 2026-04-20 13:54

    太厉害了👍🏻😍😍😍

    回复