https://laihao.vaserver.com/lucky.html
「本周幸運度調查」互動網頁,包含 HTML 結構、CSS 樣式與 JavaScript 互動邏輯。以下逐行(或逐段)解釋其作用與設計意圖:
文件開頭與 設定
CSS 樣式定義()
顏色與變數(:root)
:root, [data-theme="light"] {
--color-bg: #fff8fc;
--color-surface: #ffffff;
--color-surface-2: #fff0f7;
--color-surface-offset: #ffe3f0;
--color-border: rgba(219, 128, 172, 0.24);
--color-text: #6e3d57;
--color-text-muted: #9a6b83;
--color-primary: #ff7eb6;
--color-primary-hover: #f964a7;
--color-secondary: #8ed8ff;
--color-accent: #ffe38a;
--color-success: #7bcf9b;
--shadow-md: 0 16px 40px rgba(255, 126, 182, 0.16);
--radius-lg: 24px;
--radius-full: 999px;
--space-2: .5rem;
--space-3: .75rem;
--space-4: 1rem;
--space-6: 1.5rem;
--space-8: 2rem;
--space-10: 2.5rem;
--text-sm: clamp(.92rem, .88rem + .2vw, 1rem);
--text-base: clamp(1rem, .96rem + .25vw, 1.08rem);
--text-lg: clamp(1.2rem, 1.05rem + .7vw, 1.5rem);
--text-xl: clamp(1.8rem, 1.3rem + 2vw, 2.8rem);
--font-body: 'Zen Maru Gothic', sans-serif;
--font-display: 'Kosugi Maru', sans-serif;
}
定義所有顏色、間距、圓角、字體大小等 CSS 變數,方便統一調整主題。
使用 clamp() 讓字體大小隨視窗寬度自適應。
全域設定
- { box-sizing: border-box; }
所有元素的寬高計算包含 padding 與 border。
body {
margin: 0;
min-height: 100vh;
font-family: var(--font-body);
background: radial-gradient(circle at 10% 10%, rgba(255, 227, 138, .55), transparent 24%),
radial-gradient(circle at 88% 14%, rgba(142, 216, 255, .45), transparent 22%),
radial-gradient(circle at 82% 82%, rgba(255, 126, 182, .18), transparent 26%),
linear-gradient(180deg, #fffafd 0%, #fff4f9 100%);
color: var(--color-text);
line-height: 1.7;
padding: 24px;
}
移除預設邊距,設定最小高度為視窗高度。
背景使用多層漸層(黃、藍、粉紅)營造夢幻感。
文字顏色與行高設定。
主要容器與卡片
.wrap { max-width: 760px; margin: 0 auto; }
內容最大寬度 760px,居中對齊。
.card {
background: rgba(255,255,255,.88);
border: 1px solid var(--color-border);
border-radius: 32px;
box-shadow: var(--shadow-md);
backdrop-filter: blur(10px);
overflow: hidden;
}
卡片背景半透明白色,帶邊框、圓角、陰影與毛玻璃效果。
頂部英雄區(Hero)
.hero {
padding: 32px 24px 16px;
text-align: center;
position: relative;
}
頂部區塊,文字居中。
.badge {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 8px 16px;
background: var(--color-surface-2);
border: 1px solid var(--color-border);
border-radius: var(--radius-full);
font-size: var(--text-sm);
color: var(--color-text-muted);
}
頂部小標籤(「✨ 本周幸運度調查」),圓角膠囊樣式。
h1 {
font-family: var(--font-display);
font-size: var(--text-xl);
line-height: 1.2;
margin: 18px 0 12px;
}
主標題使用圓體字,字體大小自適應。
.lead {
margin: 0 auto;
max-width: 28rem;
color: var(--color-text-muted);
font-size: var(--text-base);
}
副標題文字,限制最大寬度並使用較淡顏色。
.sparkles {
display: flex;
justify-content: center;
gap: 10px;
margin-top: 18px;
flex-wrap: wrap;
}
.sparkles span {
padding: 6px 12px;
border-radius: var(--radius-full);
background: #fff;
border: 1px dashed var(--color-border);
font-size: .88rem;
}
三個小標籤(「粉粉好運」等),白色背景加虛線邊框。
內容區與題目
.content { padding: 12px 24px 28px; }
內容區內距。
.question {
display: none;
animation: fade .35s ease;
}
.question.active, .result.active { display: block; }
題目預設隱藏,只有 .active 的題目會顯示。
使用 fade 動畫淡入。
.step {
font-size: var(--text-sm);
color: var(--color-text-muted);
margin-bottom: 8px;
}
顯示「第 X 題 / 3」的小字。
h2 {
margin: 0 0 8px;
font-size: var(--text-lg);
}
題目標題。
.hint {
margin: 0 0 20px;
color: var(--color-text-muted);
font-size: var(--text-sm);
}
題目下方的提示文字。
.options {
display: grid;
gap: 12px;
}
選項按鈕用網格排列,間距 12px。
.option-btn {
width: 100%;
text-align: left;
border: 0;
border-radius: 20px;
padding: 16px 18px;
background: #fff;
color: var(--color-text);
font-size: 1rem;
font-family: inherit;
border: 1px solid rgba(219, 128, 172, 0.18);
box-shadow: 0 8px 18px rgba(255, 126, 182, 0.08);
transition: transform .18s ease, box-shadow .18s ease, background .18s ease;
cursor: pointer;
}
.option-btn:hover, .option-btn:focus-visible {
transform: translateY(-2px);
background: #fff7fb;
box-shadow: 0 14px 24px rgba(255, 126, 182, 0.12);
outline: none;
}
選項按鈕樣式:白色背景、圓角、陰影。
滑鼠懸停或聚焦時微微上浮、背景變粉、陰影加深。
結果區
.result {
display: none;
text-align: center;
padding-top: 8px;
}
結果區預設隱藏,居中對齊。
.result-box {
background: linear-gradient(180deg, #fff8d9 0%, #fff 55%, #fff4fa 100%);
border: 1px solid rgba(255, 194, 77, 0.32);
border-radius: 28px;
padding: 28px 20px;
}
結果卡片背景為黃到粉的漸層,帶金色邊框。
.big {
font-family: var(--font-display);
font-size: clamp(2rem, 1.6rem + 2vw, 3rem);
line-height: 1.2;
margin: 0 0 10px;
color: #ff6fa8;
}
大字結果標題(「幸運無比 100% ✨」)。
.fortune {
margin: 0 auto 16px;
max-width: 30rem;
color: var(--color-text);
}
幸運文字段落。
.love-note {
display: inline-block;
background: #fff;
border: 1px dashed rgba(219, 128, 172, .35);
border-radius: 20px;
padding: 12px 16px;
color: var(--color-text-muted);
font-size: var(--text-sm);
}
小提醒框(虛線邊框)。
.actions {
display: flex;
justify-content: center;
gap: 12px;
margin-top: 20px;
flex-wrap: wrap;
}
按鈕群組,居中排列。
.primary, .secondary {
border: 0;
border-radius: var(--radius-full);
padding: 12px 18px;
font-family: inherit;
font-size: var(--text-sm);
cursor: pointer;
}
.primary {
background: var(--color-primary);
color: white;
box-shadow: 0 10px 20px rgba(255, 126, 182, .24);
}
.primary:hover { background: var(--color-primary-hover); }
.secondary {
background: white;
color: var(--color-text);
border: 1px solid var(--color-border);
}
主要按鈕(粉色)與次要按鈕(白色描邊)。
.footer-note {
margin-top: 16px;
text-align: center;
color: var(--color-text-muted);
font-size: .92rem;
}
底部小字提醒。
進度條
.progress {
margin: 0 0 20px;
height: 10px;
background: #ffe7f2;
border-radius: 999px;
overflow: hidden;
}
.progress > span {
display: block;
height: 100%;
width: 33.33%;
background: linear-gradient(90deg, #ff98c5, #ffd970);
border-radius: inherit;
transition: width .25s ease;
}
進度條背景為粉紅色,內部填充為粉到黃漸層。
初始寬度 33.33%(第一題)。
動畫與響應式
@keyframes fade {
from { opacity: 0; transform: translateY(6px); }
to { opacity: 1; transform: translateY(0); }
}
淡入動畫。
@media (max-width: 640px) {
body { padding: 14px; }
.hero, .content { padding-left: 18px; padding-right: 18px; }
.card { border-radius: 24px; }
.result-box { padding: 24px 16px; }
.option-btn { padding: 14px 15px; }
}
手機版(寬度 ≤ 640px)調整內距與圓角。
HTML 主體結構()
JavaScript 互動邏輯()
const questions = [...document.querySelectorAll('.question')];
const progressBar = document.getElementById('progressBar');
const result = document.getElementById('result');
const fortuneText = document.getElementById('fortuneText');
const detailText = document.getElementById('detailText');
const restartBtn = document.getElementById('restartBtn');
const copyBtn = document.getElementById('copyBtn');
取得所有題目、進度條、結果區與按鈕的 DOM 元素。
const fortunes = [
{
main: '你是這個世界上最幸福的人之一,這周的你不只幸運無比,還會被朋友的愛、溫柔的陪伴和亮晶晶的好事圍繞著。',
detail: '宇宙偷偷蓋章:你值得被喜歡、被照顧、被溫柔對待。'
},
{
main: '恭喜你抽到滿滿幸福運,這一周的你會特別被偏愛,笑容會變多,身邊也會一直有暖暖的友情陪著你。',
detail: '你的好運不是路過,是住下來了。'
},
{
main: '你的幸運光環已經亮起來了,好消息、小驚喜和朋友的愛都會悄悄靠近,讓你成為超幸福的發光小寶貝。',
detail: '本周宜:開心、被愛、收下幸福。'
}
];
定義三組隨機出現的幸運文字。
let current = 0;
目前題目索引(從 0 開始)。
function showQuestion(index) {
questions.forEach((q, i) => q.classList.toggle('active', i === index));
progressBar.style.width = ${((index + 1) / questions.length) * 100}%;
}
顯示指定索引的題目,並更新進度條寬度。
function showResult() {
questions.forEach(q => q.classList.remove('active'));
progressBar.style.width = '100%';
const picked = fortunes[Math.floor(Math.random() * fortunes.length)];
fortuneText.textContent = picked.main;
detailText.textContent = picked.detail;
result.classList.add('active');
}
隱藏所有題目,進度條填滿,隨機選一組幸運文字並顯示結果區。
document.querySelectorAll('.option-btn').forEach((btn) => {
btn.addEventListener('click', () => {
current += 1;
if (current < questions.length) {
showQuestion(current);
} else {
showResult();
}
});
});
為所有選項按鈕綁定點擊事件:
每點一次,current 加 1。
若還有下一題,顯示下一題;否則顯示結果。
restartBtn.addEventListener('click', () => {
current = 0;
result.classList.remove('active');
showQuestion(current);
});
「再測一次」按鈕:重置索引、隱藏結果、回到第一題。
copyBtn.addEventListener('click', async () => {
const text = 本周幸運度調查結果:幸運無比 100%!${fortuneText.textContent} ${detailText.textContent};
try {
await navigator.clipboard.writeText(text);
copyBtn.textContent = '已複製成功';
setTimeout(() => copyBtn.textContent = '複製祝福文案', 1500);
} catch (e) {
copyBtn.textContent = '複製失敗';
setTimeout(() => copyBtn.textContent = '複製祝福文案', 1500);
}
});
「複製祝福文案」按鈕:
組合結果文字。
使用 Clipboard API 複製到剪貼簿。
成功或失敗後短暫改變按鈕文字,1.5 秒後恢復。
整體流程總結
頁面載入時,第一題顯示,進度條 33%。
使用者點擊任一選項 → 進入下一題,進度條變 66%。
第三題點擊後 → 隱藏題目,進度條 100%,隨機顯示一組幸運文字。
使用者可點擊「再測一次」重新開始,或「複製祝福文案」分享結果。