纯HTML塔罗星座运势网站源码解析:从基础技术到完整项目实践
发布时间:2026/9/4 18:07:17
分类:文化教育
浏览:1234

简介这是一套面向前端初学者与星座主题网页开发者的HTML5响应式网站源码聚焦塔罗牌占卜与十二星座运势展示两大核心功能解决个性化占星类网站快速搭建需求。资源包含183个文件涵盖13个HTML页面、11个CSS样式表含Bootstrap、Font Awesome、AOS等主流框架、8个JS交互脚本以及85张PNG与29张JPG高清星座图、图标及背景素材整体包体37.97MB结构清晰、代码独立无需后端即可直接运行预览。已有1004人学习下载适合用于课程设计、个人作品集或小型占星服务站点部署。读者可直接获取完整十二页面体系——从首页轮播、Tab切换的星座介绍、时间轴式运势解析到表单交互的占卜测算、图文并茂的博客栏目及响应式联系页所有动态效果均已封装注释简明上手门槛低开箱即用。1. 项目缘起为什么一个纯HTML的运势网站依然有市场最近在整理一些老项目时翻出了一个几年前做的塔罗牌和十二星座运势网站的源码。这个项目很有意思它没有用到任何后端语言没有数据库甚至连JavaScript都只用了最基础的部分完完全全就是一个由HTML、CSS和少量JS构成的静态网站。你可能觉得在如今React、Vue、Next.js满天飞的时代这种“原始”的网站还有价值吗答案是肯定的而且价值可能比你想象的要大。这个项目的核心关键词是“好看”和“源码”。对于很多刚入门前端、想找个完整项目练手的朋友或者是一些需要快速搭建一个轻量级展示页面的运营、自媒体从业者来说一个结构清晰、视觉效果不错、并且能直接拿来修改的纯HTML源码就是一个宝藏。它避开了复杂的环境配置、包依赖和构建流程你只需要一个浏览器和一个文本编辑器就能打开、运行和修改。所有的逻辑都摆在明面上HTML负责结构CSS负责“颜值”JS负责那一点点交互学习路径非常直观。从网络热词也能看出像“html网页制作”、“html css js网页设计”、“爱心代码大全html”、“html表白代码”这类搜索一直有很高的热度。这说明市场上有大量用户的需求并不是去开发一个复杂的Web应用他们只是想快速做出一个具有特定主题比如运势、表白、生日祝福的、视觉效果不错的单页。我这个塔罗牌与星座运势网站的源码正好切中了这个需求点它提供了一个完整的、可直接二次开发的“壳子”。所以我决定把这个老项目的源码重新整理、优化并分享出来。接下来我会带你彻底拆解这个网站的每一个部分从页面结构设计、CSS视觉风格的实现到那一点点让页面“活”起来的JavaScript交互以及如何将它变成属于你自己的作品。你会发现用最基础的技术也能做出让人眼前一亮的网页。2. 网站整体架构与设计思路解析这个运势网站采用了经典的单页应用SPA结构但在技术实现上是最轻量的那种。整个网站只有一个index.html文件通过CSS和JS来控制内容的显示与隐藏模拟出多个页面的跳转效果。这样做的好处是极致简单用户访问体验流畅没有真正的页面刷新。2.1 视觉风格定位神秘感与精致感的平衡塔罗牌和星座运势的主题天然带有神秘、复古、浪漫的色彩。因此在设计上我们需要避免过于科技感或扁平化的风格。我最终确定的视觉基调是“深色星空”搭配“鎏金质感”。色彩方案主背景采用深紫色#1a0b2e到深蓝色#0c0521的径向渐变模拟宇宙星空的深邃感。文字和主要装饰元素使用香槟金#d4af37和浅米色#f5e8c8营造出古典、珍贵的质感。点缀色用了少许玫红色#ff6b9d用于强调和互动反馈。字体选择英文标题使用了带有衬线的Cinzel字体可通过Google Fonts引入这种字体有很强的古典和神秘气息。中文部分则使用系统默认的衬线字体如SimSun,Songti SC来保证可读性同时衬线字体也与主题更搭。布局与留白采用居中对称布局内容区域有足够的留白避免信息拥挤。卡牌和星座图标采用卡片式设计增加阴影和微妙的发光效果让其从深色背景中“浮”出来。注意深色背景上的浅色文字一定要保证足够的对比度以满足无障碍访问标准。我使用的金色#d4af37在深紫色背景上的对比度经过检查是达标的。你可以使用在线工具如WebAIM Contrast Checker来验证你的配色方案。2.2 核心功能模块划分整个网站主要分为三大模块通过顶部的导航栏进行切换首页Home展示网站主题、一句吸引人的slogan以及直接进入塔罗牌或星座运势的快速入口按钮。这里是吸引用户停留的第一印象。塔罗牌占卜Tarot核心功能页。展示22张大阿尔克那牌。用户点击“抽牌”按钮后通过JavaScript随机选取1-3张牌并以优雅的动画形式翻转展示同时显示该张牌的正位/逆位释义。十二星座运势Zodiac另一个核心功能页。以网格形式展示12个星座的图标和名称。点击任意星座会以模态框Modal或页面内展开的形式展示该星座今日/本周的运势详情内容为静态文案可替换。所有数据塔罗牌释义、星座运势文案都直接以JSON格式或JavaScript对象的形式写在同一个JS文件里这就是我们的“数据库”。这种方式的优缺点非常明显优点部署简单无需服务器支持可以直接放在GitHub Pages、Netlify等静态托管服务上。缺点内容更新需要修改源码并重新部署无法动态更新。但对于这种展示型、内容更新频率不高的网站来说完全够用。3. HTML结构从骨架到语义化网站的HTML结构是一切的基石。一个好的结构不仅利于CSS样式编写和JavaScript交互也对搜索引擎友好。下面是我们index.html的核心骨架。!DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 title星语秘境 - 塔罗与星座运势/title link relstylesheet hrefcss/style.css link hrefhttps://fonts.googleapis.com/css2?familyCinzel:wght400;700displayswap relstylesheet link relstylesheet hrefhttps://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css /head body !-- 导航栏 -- nav classmain-nav div classnav-container a href# classlogo 星语秘境/a ul classnav-menu lia href#home classnav-link activei classfas fa-home/i 首页/a/li lia href#tarot classnav-linki classfas fa-cards/i 塔罗占卜/a/li lia href#zodiac classnav-linki classfas fa-star/i 星座运势/a/li /ul /div /nav !-- 主内容区 -- main classcontent-wrapper !-- 首页区域 -- section idhome classpage active div classhero h1窥探命运的一角/h1 p让古老的塔罗与星辰的指引为你揭示当下的启示。/p div classcta-buttons a href#tarot classbtn btn-primary抽取塔罗牌/a a href#zodiac classbtn btn-secondary查看星座运势/a /div /div /section !-- 塔罗牌区域 -- section idtarot classpage h2塔罗牌占卜/h2 div classtarot-controls button iddraw-one classbtn抽取一张/button button iddraw-three classbtn抽取三张/button button idreset-cards classbtn重置/button /div div classtarot-container idtarot-container !-- 牌背 -- div classcard card-back>/* style.css */ :root { --color-bg-dark: #0c0521; --color-bg-purple: #1a0b2e; --color-gold: #d4af37; --color-gold-light: #f5e8c8; --color-accent: #ff6b9d; --color-text: #e0e0e0; --font-heading-en: Cinzel, serif; } body { margin: 0; font-family: SimSun, Songti SC, serif; color: var(--color-text); background: radial-gradient(ellipse at center, var(--color-bg-purple) 0%, var(--color-bg-dark) 70%); min-height: 100vh; overflow-x: hidden; }这里使用了CSS变量Custom Properties来定义颜色和字体方便全局管理和统一修改。背景采用了从中心向外的径向渐变营造出深邃的星空感。min-height: 100vh确保即使内容很少页面也能占满整个视口高度。4.2 导航栏与页面切换动画.main-nav { background-color: rgba(12, 5, 33, 0.9); backdrop-filter: blur(10px); position: sticky; top: 0; z-index: 1000; border-bottom: 1px solid rgba(212, 175, 55, 0.3); } .nav-menu .nav-link { color: var(--color-gold-light); text-decoration: none; padding: 0.5rem 1.5rem; border-radius: 20px; transition: all 0.3s ease; } .nav-menu .nav-link.active, .nav-menu .nav-link:hover { background-color: rgba(212, 175, 55, 0.15); color: var(--color-gold); } /* 页面切换效果 */ .page { display: none; opacity: 0; transform: translateY(20px); transition: opacity 0.5s ease, transform 0.5s ease; padding: 2rem; } .page.active { display: block; opacity: 1; transform: translateY(0); }导航栏使用了position: sticky使其在滚动时始终固定在顶部并增加了毛玻璃背景效果backdrop-filter提升质感。页面切换的动画是关键非激活的页面display: none并完全透明且下移激活的页面则淡入并上移归位。这个简单的组合实现了平滑的过渡效果。4.3 塔罗牌卡片的实现这是视觉效果的重点。我们要实现一个可以正反面翻转的卡片。.tarot-container { display: flex; justify-content: center; gap: 2rem; flex-wrap: wrap; margin: 3rem auto; perspective: 1000px; /* 为3D翻转创建透视空间 */ } .card { width: 180px; height: 280px; position: relative; transform-style: preserve-3d; /* 子元素保持3D空间 */ transition: transform 0.8s cubic-bezier(0.175, 0.885, 0.32, 1.275); cursor: pointer; border-radius: 12px; box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5), inset 0 0 0 1px rgba(255, 255, 255, 0.1); } .card.flipped { transform: rotateY(180deg); } .card-front, .card-back { position: absolute; width: 100%; height: 100%; backface-visibility: hidden; /* 翻转时隐藏背面 */ border-radius: 12px; display: flex; align-items: center; justify-content: center; overflow: hidden; } .card-back { background: linear-gradient(45deg, var(--color-bg-dark), #2a1b5e); border: 2px solid var(--color-gold); } .card-back::before { content: ; font-size: 3rem; opacity: 0.7; } .card-front { background-color: var(--color-gold-light); transform: rotateY(180deg); /* 正面初始就是翻转状态 */ color: #333; } .card-front img { width: 90%; height: auto; border-radius: 8px; }核心原理3D空间在容器.tarot-container上设置perspective赋予其3D景深。在卡片.card上设置transform-style: preserve-3d让其子元素正反面在3D空间内变换。正反面重叠卡片的正面.card-front和背面.card-back都使用position: absolute叠在一起。隐藏背面backface-visibility: hidden是关键属性。它让元素的“背面”在面向用户时不可见。.card-back的背面是它自己默认可见.card-front我们一开始就设置了transform: rotateY(180deg)所以它的“正面”是背对用户的因此被隐藏了。触发翻转当为卡片添加.flipped类时整个卡片旋转180度。此时原本背对用户的.card-front变成了正面由于backface-visibility: hidden原本的正面.card-back被隐藏从而实现了翻转效果。cubic-bezier缓动函数让翻转动画更有弹性。4.4 星座网格与模态框.zodiac-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 1.5rem; margin-top: 2rem; } .zodiac-item { background: rgba(255, 255, 255, 0.05); border: 1px solid rgba(212, 175, 55, 0.2); border-radius: 10px; padding: 1.5rem 1rem; text-align: center; cursor: pointer; transition: all 0.3s ease; } .zodiac-item:hover { transform: translateY(-5px); border-color: var(--color-gold); box-shadow: 0 10px 20px rgba(212, 175, 55, 0.2); } .zodiac-item i { font-size: 2.5rem; color: var(--color-gold); margin-bottom: 0.5rem; } /* 模态框样式 */ .zodiac-detail-modal { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.8); z-index: 2000; align-items: center; justify-content: center; } .zodiac-detail-modal.active { display: flex; } .modal-content { background: linear-gradient(to bottom right, var(--color-bg-purple), #2d1b69); width: 90%; max-width: 600px; padding: 2rem; border-radius: 15px; border: 1px solid var(--color-gold); position: relative; animation: modalAppear 0.4s ease-out; } keyframes modalAppear { from { opacity: 0; transform: scale(0.9); } to { opacity: 1; transform: scale(1); } } .close-modal { position: absolute; top: 1rem; right: 1rem; background: none; border: none; color: var(--color-text); font-size: 1.5rem; cursor: pointer; }星座网格使用了CSS Grid布局repeat(auto-fill, minmax(150px, 1fr))这个写法非常强大它能自动根据容器宽度排列项目并确保每个项目至少150px宽实现了完美的响应式。 模态框是经典的“覆盖层”实现。默认隐藏display: none当需要显示时通过JS添加.active类变为display: flex并配合一个简单的缩放淡入动画。5. JavaScript交互让静态页面“活”起来静态的HTML和CSS构成了网站的躯壳和外观而JavaScript则是赋予其灵魂的关键。我们的main.js文件主要负责三件事页面路由切换、塔罗牌抽签逻辑、星座详情展示。5.1 数据层data.js首先我们需要定义网站的核心数据。将数据独立出来是很好的实践。// data.js const tarotCards [ { id: 0, name: 愚者, image: images/tarot/00_fool.jpg, meaningUp: 新的开始冒险无限可能。, meaningRev: 鲁莽犹豫不决风险。 }, { id: 1, name: 魔术师, image: images/tarot/01_magician.jpg, meaningUp: 创造力技能行动力。, meaningRev: 欺骗未使用的才能。 }, // ... 其他20张大阿尔克那牌数据 ]; const zodiacSigns [ { id: 0, name: 白羊座, icon: ♈, date: 3月21日-4月19日, todayFortune: 今日行动力满满适合开启新项目但需注意沟通方式。, weekFortune: 本周贵人运佳合作事务进展顺利。财务上有小惊喜。 }, { id: 1, name: 金牛座, icon: ♉, date: 4月20日-5月20日, todayFortune: 适合处理财务和资源问题享受美食能带来好心情。, weekFortune: 本周重心在家庭和安全感上适合整理家居或与家人沟通。 }, // ... 其他10个星座数据 ];5.2 页面路由与导航我们通过监听导航栏链接的点击事件并利用URL的hash#home,#tarot来模拟路由。// main.js document.addEventListener(DOMContentLoaded, function() { // 获取所有页面和导航链接 const pages document.querySelectorAll(.page); const navLinks document.querySelectorAll(.nav-link); // 初始化根据当前URL的hash显示对应页面 function showPage(pageId) { // 隐藏所有页面 pages.forEach(page { page.classList.remove(active); }); // 显示目标页面 const targetPage document.getElementById(pageId); if (targetPage) { targetPage.classList.add(active); } // 更新导航栏激活状态 navLinks.forEach(link { link.classList.remove(active); if (link.getAttribute(href) #${pageId}) { link.classList.add(active); } }); // 更新URL hash可选为了可分享链接 window.location.hash pageId; } // 为导航链接添加点击事件 navLinks.forEach(link { link.addEventListener(click, function(e) { e.preventDefault(); const pageId this.getAttribute(href).substring(1); // 去掉#号 showPage(pageId); }); }); // 监听浏览器前进/后退按钮hash变化 window.addEventListener(hashchange, function() { const pageId window.location.hash.substring(1) || home; showPage(pageId); }); // 页面加载时初始化 const initialPageId window.location.hash.substring(1) || home; showPage(initialPageId); // ... 后续塔罗牌和星座的代码 });这段代码构建了一个简单的客户端路由。它做了以下几件事showPage函数是核心负责切换页面的active类并更新导航栏状态。为导航链接绑定点击事件阻止默认跳转转而调用showPage。监听hashchange事件这样用户点击浏览器前进/后退按钮时页面也能正确切换。页面加载时根据当前URL的hash值或默认home来显示对应页面。5.3 塔罗牌抽签逻辑这是整个网站最有趣的交互部分。我们需要实现随机抽牌、动画翻转和显示释义。// main.js (接上文) // 塔罗牌相关元素 const tarotContainer document.getElementById(tarot-container); const drawOneBtn document.getElementById(draw-one); const drawThreeBtn document.getElementById(draw-three); const resetBtn document.getElementById(reset-cards); const interpretationEl document.getElementById(interpretation); let drawnCards []; // 记录当前已抽出的牌 // 渲染一张牌到页面 function renderCard(cardData, isReversed) { const cardEl document.createElement(div); cardEl.className card; cardEl.dataset.cardId cardData.id; cardEl.innerHTML div classcard-back/div div classcard-front img src${cardData.image} alt${cardData.name} div classcard-name${cardData.name}/div /div ; tarotContainer.appendChild(cardEl); // 延迟一点时间触发翻转动画让牌背先显示 setTimeout(() { cardEl.classList.add(flipped); }, 100); // 点击牌可以查看正逆位 cardEl.addEventListener(click, function() { const meaning isReversed ? cardData.meaningRev : cardData.meaningUp; interpretationEl.innerHTML h3${cardData.name} ${isReversed ? (逆位) : (正位)}/h3 p${meaning}/p ; }); return { element: cardEl, data: cardData, reversed: isReversed }; } // 抽牌函数 function drawCards(num) { // 清空当前展示和释义 tarotContainer.innerHTML ; interpretationEl.innerHTML ; drawnCards []; // 复制牌组并随机排序 let availableCards [...tarotCards]; // 简单的洗牌算法 (Fisher-Yates) for (let i availableCards.length - 1; i 0; i--) { const j Math.floor(Math.random() * (i 1)); [availableCards[i], availableCards[j]] [availableCards[j], availableCards[i]]; } // 抽取前N张 const selectedCards availableCards.slice(0, num); selectedCards.forEach(card { // 随机决定正逆位 (30%概率逆位) const isReversed Math.random() 0.3; const cardObj renderCard(card, isReversed); drawnCards.push(cardObj); }); } // 绑定按钮事件 drawOneBtn.addEventListener(click, () drawCards(1)); drawThreeBtn.addEventListener(click, () drawCards(3)); resetBtn.addEventListener(click, () { tarotContainer.innerHTML div classcard card-back>// main.js (接上文) // 星座相关元素 const zodiacGrid document.getElementById(zodiac-grid); const zodiacModal document.getElementById(zodiac-modal); // 生成星座网格 function renderZodiacGrid() { zodiacGrid.innerHTML ; zodiacSigns.forEach(sign { const signEl document.createElement(div); signEl.className zodiac-item; signEl.dataset.signId sign.id; signEl.innerHTML div classzodiac-icon${sign.icon}/div h3${sign.name}/h3 p classzodiac-date${sign.date}/p ; signEl.addEventListener(click, () showZodiacDetail(sign.id)); zodiacGrid.appendChild(signEl); }); } // 显示星座详情模态框 function showZodiacDetail(signId) { const sign zodiacSigns.find(s s.id signId); if (!sign) return; zodiacModal.innerHTML div classmodal-content button classclose-modaltimes;/button div classmodal-header span classmodal-icon${sign.icon}/span h2${sign.name} (${sign.date})/h2 /div div classmodal-body div classfortune-section h3i classfas fa-sun/i 今日运势/h3 p${sign.todayFortune}/p /div div classfortune-section h3i classfas fa-calendar-week/i 本周运势/h3 p${sign.weekFortune}/p /div div classfortune-note pi classfas fa-info-circle/i 运势仅供参考生活由你创造。/p /div /div /div ; zodiacModal.classList.add(active); // 关闭模态框事件 const closeBtn zodiacModal.querySelector(.close-modal); closeBtn.addEventListener(click, () { zodiacModal.classList.remove(active); }); // 点击模态框背景关闭 zodiacModal.addEventListener(click, (e) { if (e.target zodiacModal) { zodiacModal.classList.remove(active); } }); } // 初始化星座网格 renderZodiacGrid();星座部分的逻辑清晰明了renderZodiacGrid动态创建12个星座卡片并为每个卡片绑定点击事件。点击后showZodiacDetail函数会根据ID找到对应的星座数据生成模态框的HTML内容并显示。模态框的关闭逻辑绑定了两个事件点击关闭按钮和点击模态框的黑色半透明背景。6. 项目部署与二次开发指南至此一个完整的、纯前端的塔罗牌与星座运势网站就完成了。你可以把index.html,css/style.css,js/data.js,js/main.js以及图片资源images/文件夹放在同一个目录下直接用浏览器打开index.html就能运行。6.1 如何部署到线上如果你想分享给朋友或放在个人主页上需要将其部署到静态网站托管服务。这里以GitHub Pages为例这是完全免费的。在GitHub上创建一个新的仓库Repository例如命名为fortune-website。将你的项目所有文件除了node_modules等无关文件上传到这个仓库。进入仓库的Settings-Pages。在Source下拉菜单中选择你存放代码的分支通常是main或master然后选择根目录/。点击Save。几分钟后GitHub会提供一个类似https://你的用户名.github.io/fortune-website/的网址你的网站就上线了。6.2 如何进行二次开发这个源码的价值在于它是一个绝佳的模板你可以轻松地将其改头换面。更换主题想做一个“每日诗词”网站把塔罗牌数据换成唐诗宋词把星座网格换成诗人头像修改data.js和对应的图片即可。CSS中的颜色变量--color-*是全局控制的改几处就能换一套配色。增加功能比如为塔罗牌增加“保存本次占卜结果”的功能。这需要用到浏览器的localStorageAPI将drawnCards数组序列化后存起来并新增一个“历史记录”页面来展示。优化体验可以加入更复杂的抽牌动画比如牌从牌堆里飞出的效果。这需要更深入的CSS动画或JavaScript动画库如anime.js知识。接入动态数据如果想让运势内容每天自动更新就不能再把数据写死在JS里了。你需要一个后端服务比如用Python的Flask、Node.js的Express写个简单的API来提供每日运势数据然后网站通过fetchAPI来获取。但这超出了纯HTML项目的范畴属于全栈开发了。踩坑提醒在修改CSS时特别是涉及flexbox或grid布局如果发现元素位置不对劲第一件事是打开浏览器的开发者工具F12使用元素检查器查看盒模型和应用的样式这能解决90%的布局问题。另外动态添加的元素如果事件不生效检查一下事件绑定的时机确保在DOM元素创建之后再绑定。这个项目麻雀虽小五脏俱全。它涵盖了静态网站的核心技术语义化HTML、现代CSS布局与动画、基础的DOM操作和事件处理。通过拆解和改造它你不仅能得到一个好看的网站更能深入理解这些基础技术是如何协同工作的。希望这份详细的源码解读和实现指南能成为你前端学习或创意实践中的一个有力跳板。本文还有配套的精品资源点击获取