人網(wǎng)頁作業(yè)完整指南:HTML+CSS+JavaScript從架構(gòu)到交互)
簡(jiǎn)介這是一份面向Web前端初學(xué)者的個(gè)人網(wǎng)頁設(shè)計(jì)作業(yè)源碼包采用HTMLCSSJavaScript實(shí)現(xiàn)涵蓋個(gè)人主頁、個(gè)人博客、輪播相冊(cè)、魔方相冊(cè)、視頻主頁、收藏、日志與圖片展示等典型頁面可幫助學(xué)習(xí)者系統(tǒng)練習(xí)多頁面布局、交互事件綁定、DOM操作與CSS3動(dòng)畫等基礎(chǔ)技能非常適合作為課程設(shè)計(jì)或畢業(yè)作品集的起步模板。壓縮包共576個(gè)文件以213個(gè)JavaScript、167個(gè)HTML、75個(gè)CSS文件為核心另含SCSS預(yù)處理器源碼、JPG/PNG圖片、字體圖標(biāo)及音視頻等輔助資源整體約23.32MB目錄結(jié)構(gòu)清晰便于按模塊對(duì)照學(xué)習(xí)。該資源已有14668人瀏覽學(xué)習(xí)初學(xué)者可通過分析文件引用關(guān)系、調(diào)試輪播自動(dòng)切換、魔方3D旋轉(zhuǎn)等功能快速掌握前端三大核心技術(shù)的配合邏輯同時(shí)為后續(xù)學(xué)習(xí)React、Vue等框架奠定扎實(shí)基礎(chǔ)。1. 用工程化思維做一份個(gè)人網(wǎng)頁作業(yè)htmlcssjavascript 的最小完整方案一份“Web前端網(wǎng)頁設(shè)計(jì)作業(yè)-個(gè)人網(wǎng)頁”想要真正拿高分難點(diǎn)不在頁面多華麗而在“老師或面試官一眼掃過去能不能看出你理解結(jié)構(gòu)和交互”。很多人的作業(yè)是幾個(gè) div 套著無數(shù) classCSS 一路堆到底JavaScript 從模板里復(fù)制來的卻講不清。換個(gè)角度看這份作業(yè)就是一次縮小的 Web 前端開發(fā)任務(wù)先定信息架構(gòu)、再做視覺設(shè)計(jì)、最后實(shí)現(xiàn)交互和真實(shí)站點(diǎn)的差距只是規(guī)模。我寫個(gè)人網(wǎng)頁不會(huì)先開編輯器而是先在紙上拆模塊我是誰、我會(huì)什么、我做過什么、怎么聯(lián)系我。下面這套方案按從業(yè)者習(xí)慣來組織用 VSCode 寫 htmlcssjs 時(shí)最不容易跑偏。2. HTML先搭信息架構(gòu)再寫語義化標(biāo)簽2.1 個(gè)人網(wǎng)頁的信息模塊怎么拆個(gè)人網(wǎng)頁作業(yè)最常見的長(zhǎng)頁面結(jié)構(gòu)是四塊個(gè)人簡(jiǎn)介、技能清單、作品展示、聯(lián)系信息。不要上來就寫代碼先給每個(gè)模塊定一個(gè)標(biāo)題和一句描述這樣后面寫section和h2時(shí)才有依據(jù)。我一般會(huì)把頁面當(dāng)成一個(gè)簡(jiǎn)歷的網(wǎng)頁版每個(gè)模塊對(duì)應(yīng)一個(gè)錨點(diǎn)鏈接導(dǎo)航欄就是模塊清單。模塊與模塊之間要有層級(jí)而不是平鋪五個(gè)h2就算完事。拆信息架構(gòu)時(shí)還要注意“這個(gè)模塊給誰看”。個(gè)人簡(jiǎn)介區(qū)是給訪客建立第一印象的技能區(qū)要讓人快速知道你熟練什么作品區(qū)要挑兩三個(gè)最能說明問題的項(xiàng)目。作業(yè)里寫什么都行但結(jié)構(gòu)不能亂一個(gè)視覺正常卻語義混亂的頁面在可訪問性和 SEO 上會(huì)同時(shí)失分這也是網(wǎng)頁設(shè)計(jì)作業(yè)經(jīng)常被忽略的隱藏評(píng)分點(diǎn)。2.2 文檔骨架和 lang、doctype 的講究VSCode 里輸入英文感嘆號(hào)生成的 HTML 骨架帶一行!doctype html和html langzh-cn這兩行不是模板的裝飾品。doctype 的作用是讓瀏覽器進(jìn)入標(biāo)準(zhǔn)模式不寫或?qū)戝e(cuò)會(huì)導(dǎo)致舊的怪異模式渲染盒模型計(jì)算都可能出現(xiàn)問題。langzh-cn告訴瀏覽器和搜索機(jī)器人這個(gè)頁面是簡(jiǎn)體中文屏幕閱讀器也會(huì)按中文發(fā)音規(guī)則朗讀翻譯插件能正確識(shí)別語言。!doctype htmlhtml langzh-cn之后依次是meta charset、meta nameviewport和title。字符編碼必須是utf-8否則中文會(huì)顯示成亂碼viewport 設(shè)置widthdevice-width, initial-scale1是移動(dòng)端布局的起點(diǎn)。個(gè)人網(wǎng)頁的標(biāo)題寫成“個(gè)人主頁 - 你的名字”比“無標(biāo)題文檔”專業(yè)得多瀏覽器標(biāo)簽頁和搜索結(jié)果都會(huì)用到這個(gè)。2.3 語義化標(biāo)簽落位header、main、article 怎么用通篇使用div不代表作業(yè)錯(cuò)但用語義化標(biāo)簽?zāi)茏尳Y(jié)構(gòu)在瀏覽器和輔助工具里更清晰。header放站點(diǎn)級(jí)導(dǎo)航main包住當(dāng)前頁面的主體內(nèi)容section配h2表示一個(gè)內(nèi)容塊article用于獨(dú)立成篇的作品條目footer放聯(lián)系方式和版權(quán)。這些標(biāo)簽不是對(duì) div 的替代而是對(duì)信息層級(jí)的補(bǔ)充。我給出一個(gè)可以直接作為作業(yè)底稿的 HTML 結(jié)構(gòu)導(dǎo)航、簡(jiǎn)介、技能、作品、聯(lián)系一次到位!doctype html html langzh-cn head meta charsetutf-8 meta nameviewport contentwidthdevice-width, initial-scale1 title個(gè)人主頁 - 張一/title link relstylesheet hrefcss/style.css /head body header classsite-header a classsite-logo href#homeZhangYi/a nav classsite-nav aria-label主導(dǎo)航 ul lia href#about關(guān)于/a/li lia href#skills技能/a/li lia href#works作品/a/li lia href#contact聯(lián)系/a/li /ul /nav /header main idhome section idabout classhero aria-labelledbyabout-title h1 idabout-title你好我是張一/h1 pWeb前端方向的學(xué)習(xí)者正在搭建自己的第一個(gè)完整頁面。/p /section section idskills aria-labelledbyskills-title h2 idskills-title技能清單/h2 ul classskill-list liHTML 結(jié)構(gòu)與語義化/li liCSS 布局與動(dòng)效/li liJavaScript 基礎(chǔ)交互/li /ul /section section idworks aria-labelledbyworks-title h2 idworks-title作品與練習(xí)/h2 article classwork-card h3個(gè)人網(wǎng)頁作業(yè)/h3 p用原生 htmlcssjavascript 搭建的靜態(tài)個(gè)人站點(diǎn)包含滾動(dòng)高亮、返回頂部、暗色模式。/p /article /section /main footer idcontact address 聯(lián)系我a hrefmailto:zhangyiexample.comzhangyiexample.com/a /address /footer /body /htmlaria-labelledby把section和對(duì)應(yīng)的標(biāo)題 id 關(guān)聯(lián)起來屏幕閱讀器讀到這里會(huì)說“關(guān)于區(qū)域標(biāo)題你好我是張一”而不是播報(bào)一串無意義的 div。ul用在導(dǎo)航和技能列表里比一連串p更符合列表語義。address只用于作者聯(lián)系信息放在 footer 里正合適。2.4 語義標(biāo)簽與 div 寫法對(duì)照如果你想判斷自己的作業(yè)用沒用對(duì)標(biāo)簽直接看語義標(biāo)簽和習(xí)慣性 div 寫法的差別語義標(biāo)簽習(xí)慣性寫法實(shí)際影響headerdiv classheader屏幕閱讀器可快速定位站點(diǎn)導(dǎo)航navdiv classmenu輔助技術(shù)識(shí)別為導(dǎo)航地標(biāo)maindiv classcontent支持無障礙“跳到主內(nèi)容”articlediv classcard閱讀器可識(shí)別為獨(dú)立條目footerdiv classbottom頁腳地標(biāo)語義明確用表格里的對(duì)照檢查你自己的頁面能快速發(fā)現(xiàn)把a(bǔ)rticle寫成一堆嵌套div的問題。寫完這步HTML 部分基本可以收住剩下的美化交給 CSS。3. CSS從三行模式開始把布局和美化拆開做3.1 三行模式的 CSS 文件先定變量、盒模型和字體棧不少人拿到網(wǎng)頁模板第一件事是瘋狂改顏色和邊距最后得到一個(gè)自己都調(diào)不明白的 CSS 文件。我習(xí)慣用“三行模式”開 CSS 文件第一行聲明設(shè)計(jì)變量第二行修正全局盒模型第三行設(shè)置基礎(chǔ)字體和排版。這三行不是偷懶而是給后面所有樣式的確定性。/* 第一行設(shè)計(jì)變量改主題只動(dòng)這里 */ :root { --bg: #ffffff; --text: #222222; --primary: #2563eb; --border: rgba(0, 0, 0, 0.08); --radius: 12px; --max-width: 960px; } /* 第二行統(tǒng)一盒模型避免 padding 撐破布局 */ * { box-sizing: border-box; } /* 第三行基礎(chǔ)字體與行高 */ body { margin: 0; font-family: system-ui, -apple-system, PingFang SC, Microsoft YaHei, sans-serif; line-height: 1.7; color: var(--text); background: var(--bg); }第一行的:root是 CSS 自定義屬性的掛載點(diǎn)后面所有顏色、圓角、最大寬度都可以用var(--primary)引用作業(yè)里想換主題色只需改一處。第二行*選擇器選中所有元素并設(shè)置box-sizing: border-box這樣padding和border不會(huì)把固定寬度撐破橫向滾動(dòng)條的一大半根源在這里被干掉。第三行是中文字體棧的常見寫法system-ui優(yōu)先使用系統(tǒng)字體PingFang SC適配 macOSMicrosoft YaHei兜底 Windows避免換來換去字體不一致。3.2 導(dǎo)航用 flex卡片墻用 grid兩條主線的選擇理由布局選型不需要糾結(jié)太久我一般按這個(gè)標(biāo)準(zhǔn)區(qū)分一維排列用 flex二維網(wǎng)格用 grid。導(dǎo)航欄從左到右排 logo 和菜單項(xiàng)是典型的一維場(chǎng)景flex 足夠作品區(qū)需要上下左右都有多個(gè)卡片用 grid 自動(dòng)換列更省心。.site-header { display: flex; align-items: center; justify-content: space-between; max-width: var(--max-width); margin: 0 auto; padding: 1rem 1.25rem; } .works-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 1.5rem; } .skill-list { display: flex; flex-wrap: wrap; gap: 0.5rem 1rem; }justify-content: space-between讓 logo 靠左、導(dǎo)航靠右中間空隙自動(dòng)分配align-items: center保證垂直居中。.works-grid里的repeat(auto-fit, minmax(280px, 1fr))是響應(yīng)式的核心每列最小 280px屏幕夠?qū)捑投喾艓琢胁粔蚓妥詣?dòng)降為單列全程不需要手寫媒體查詢。flex-wrap: wrap配合gap讓技能列表在小屏?xí)r折行每一項(xiàng)之間的間距一致網(wǎng)頁設(shè)計(jì)作業(yè)的美化大部分靠這種間距控制。3.3 鼠標(biāo)移入事件其實(shí)是 :hover配上 transition 才不突兀熱詞里經(jīng)常出現(xiàn)“css 鼠標(biāo)移入事件”這個(gè)說法的正解是:hover偽類它屬于 CSS 而不是 JavaScript。很多作業(yè)里鼠標(biāo)移到卡片上會(huì)瞬間跳變是因?yàn)橹粚懥?hover沒寫transition。兩者結(jié)合才是平滑的懸浮效果.work-card { padding: 1.25rem; border: 1px solid var(--border); border-radius: var(--radius); transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease; } .work-card:hover { transform: translateY(-4px); box-shadow: 0 10px 24px rgba(0, 0, 0, 0.08); border-color: var(--primary); }:hover觸發(fā)時(shí)卡片向上移動(dòng) 4px 并加深陰影transition讓位移、陰影、邊框色的變化在 0.25 秒內(nèi)完成。參數(shù)值得細(xì)看transform用 GPU 加速比改top/left性能好陰影消散稍有延遲視覺更柔和。注意:hover是鼠標(biāo)專屬觸摸屏沒有懸浮概念所以關(guān)鍵操作不能只放在 hover 上頁面里的鏈接和按鈕要能通過鍵盤聚焦。這時(shí)需要:focus-visible.work-card:focus-within { outline: 2px solid var(--primary); outline-offset: 2px; }:focus-within會(huì)命中“內(nèi)部有元素獲得焦點(diǎn)”的卡片鍵盤用戶按 Tab 進(jìn)入作品鏈接時(shí)能清晰看到焦點(diǎn)框這是網(wǎng)頁設(shè)計(jì)作業(yè)里容易加分但很少有人做的細(xì)節(jié)。3.4 常用偽類選擇器速查與性能提醒CSS 偽類選擇器很多作業(yè)階段掌握下表這一組就夠用選擇器作用使用場(chǎng)景:hover鼠標(biāo)懸停時(shí)命中卡片上浮、鏈接變色:focus-visible鍵盤聚焦且可視時(shí)命中輸入框和鏈接焦點(diǎn)環(huán):nth-child(odd/even)按序號(hào)命中子元素列表隔行變色:not(selector)排除指定元素最后一行的元素不加邊框:focus-within元素內(nèi)部有聚焦項(xiàng)時(shí)命中卡片整體高亮用:nth-child做列表斑馬紋時(shí)HTML 里的子節(jié)點(diǎn)必須是同一類型混入注釋或文本節(jié)點(diǎn)會(huì)影響計(jì)數(shù)規(guī)則。:not()的傳參越簡(jiǎn)單越好復(fù)雜選擇器會(huì)降低可讀性。CSS 動(dòng)畫這類美化手段要克制作業(yè)頁面里兩三個(gè)動(dòng)畫就夠全頁面漂浮的效果反而讓人抓不住重點(diǎn)。優(yōu)先級(jí)方面少用!important多用類選擇器控制權(quán)重否則后續(xù)想覆蓋樣式時(shí)會(huì)越改越亂。4. JavaScript把靜態(tài)頁變成可交互的個(gè)人站點(diǎn)4.1 腳本放在哪里執(zhí)行為什么等 DOMContentLoaded個(gè)人網(wǎng)頁到了 JavaScript 這一步核心不是寫過多少特效而是代碼在正確時(shí)間運(yùn)行。腳本在 body 底部或用defer屬性加載都能保證 DOM 已經(jīng)解析完但defer的語義更明確且不阻塞 CSS 和 HTML 解析script srcjs/main.js defer/scriptdefer告訴瀏覽器腳本會(huì)在文檔解析完成后執(zhí)行多個(gè)defer腳本會(huì)按順序執(zhí)行。如果你仍習(xí)慣把script放 body 末尾邏輯上沒有大問題只是defer對(duì)“腳本與 DOM 位置無關(guān)”這個(gè)事實(shí)表達(dá)得更清楚。為了防止直接訪問不存在的節(jié)點(diǎn)導(dǎo)致 JavaScript 運(yùn)行時(shí)報(bào)錯(cuò)習(xí)慣性在入口先包裹一層document.addEventListener(DOMContentLoaded, () { // 初始化和事件綁定都寫在這里 });這段代碼會(huì)在 DOM 樹構(gòu)建完成后觸發(fā)即使腳本因?yàn)闅v史原因被放在 head 里也不會(huì)拿不到節(jié)點(diǎn)。VSCode 寫代碼時(shí)容易忽視這類細(xì)節(jié)但瀏覽器控制臺(tái)一旦出現(xiàn)“Cannot read properties of null”第一件事就是檢查腳本執(zhí)行順序。4.2 滾動(dòng)高亮與平滑滾動(dòng)用 IntersectionObserver 而不是硬算個(gè)人網(wǎng)頁的導(dǎo)航高亮有一種常見實(shí)現(xiàn)監(jiān)聽scroll事件每次滾動(dòng)時(shí)獲取每個(gè)模塊的位置再判斷當(dāng)前應(yīng)該高亮哪一項(xiàng)。這種寫法能跑但滾動(dòng)事件觸發(fā)頻率高每次都讀取布局信息容易造成卡頓。我更喜歡用 IntersectionObserver 監(jiān)聽模塊與視口的交叉狀態(tài)const sections document.querySelectorAll(main section[id]); const navLinks document.querySelectorAll(.site-nav a); const observer new IntersectionObserver( (entries) { entries.forEach((entry) { if (entry.isIntersecting) { const currentId entry.target.id; navLinks.forEach((link) { link.classList.toggle( active, link.getAttribute(href) #${currentId} ); }); } }); }, { rootMargin: -20% 0px -70% 0px } ); sections.forEach((section) observer.observe(section));rootMargin: -20% 0px -70% 0px把監(jiān)聽區(qū)域壓縮成一個(gè)靠近頁面頂部的橫條模塊滾動(dòng)到這個(gè)范圍內(nèi)才觸發(fā)高亮避免連續(xù)切換。classList.toggle(className, boolean)的第二個(gè)參數(shù)是布爾值true 加類、false 去類比手寫 if/else 簡(jiǎn)潔。錨點(diǎn)跳轉(zhuǎn)的平滑效果用 CSS 一行完成html { scroll-behavior: smooth; }設(shè)置了scroll-behavior后點(diǎn)擊#about這類錨點(diǎn)鏈接會(huì)平滑滾動(dòng)過去不需要 JavaScript 干預(yù)。這個(gè)方案好在邏輯集中滾動(dòng)高亮交給觀察器平滑滾動(dòng)交給 CSS出了錯(cuò)也容易定位。4.3 打字機(jī)效果一個(gè)函數(shù)講清定時(shí)器與遞歸網(wǎng)頁設(shè)計(jì)作業(yè)里常見“打字機(jī)”輸入效果其實(shí)就是定時(shí)把字符串逐字寫入元素。最簡(jiǎn)單的寫法如下function typeWriter(element, text, speed 100) { let index 0; const timer setInterval(() { element.textContent text.slice(0, index 1); index 1; if (index text.length) { clearInterval(timer); } }, speed); } typeWriter(document.querySelector(.hero-title), 你好我是張一);text.slice(0, index 1)每次取前綴字符串index遞增直到長(zhǎng)度耗盡clearInterval(timer)停止計(jì)時(shí)器。如果忘記清理定時(shí)器函數(shù)結(jié)束后回調(diào)會(huì)繼續(xù)執(zhí)行雖然這里 no-op但在復(fù)雜頁面里可能造成內(nèi)存浪費(fèi)。更可控的寫法是把定時(shí)器換成遞歸的setTimeoutfunction typeWriter(element, text, index 0, speed 100) { if (index text.length) { return; } element.textContent text.slice(0, index); setTimeout(() typeWriter(element, text, index 1, speed), speed); }遞歸版本不需要清理定時(shí)器每執(zhí)行一次就在棧上安排下一次但要注意多次調(diào)用時(shí)用clearTimeout取消上一次的句柄避免兩個(gè)打字機(jī)同時(shí)寫入打架。無論哪個(gè)版本參數(shù)speed都需要試手感100 毫秒適中作業(yè)演示時(shí) 80 毫秒更有節(jié)奏感。4.4 暗色模式與表單校驗(yàn)兩個(gè)常見但容易出錯(cuò)的交互暗色模式是個(gè)人網(wǎng)頁里效果立竿見影的交互很多作業(yè)做了一半就不小心把樣式改亂了根本原因是顏色寫死在組件里。配合第 3 章的 CSS 變量暗色切換只需要給html加一個(gè)類覆蓋變量值即可const root document.documentElement; const toggleButton document.querySelector(#theme-toggle); toggleButton.addEventListener(click, () { const isDark root.classList.toggle(dark); localStorage.setItem(theme, isDark ? dark : light); }); root.classList.toggle(dark, localStorage.getItem(theme) dark);classList.toggle(dark)的返回值是布爾值正好表示當(dāng)前是否處于暗色模式localStorage.setItem(theme, ...)把選擇持久化下次打開頁面仍是上次的狀態(tài)。CSS 一側(cè)只需這樣覆蓋html.dark { --bg: #121212; --text: #e5e5e5; --border: rgba(255, 255, 255, 0.1); }因?yàn)樗薪M件都引用var(--bg)和var(--text)改變量就等于全站換膚。需要提醒的是頁面刷新時(shí)腳本較晚執(zhí)行暗色模式可能閃一下白再變黑。常見做法是把這個(gè)恢復(fù)邏輯單獨(dú)寫成一個(gè)小腳本放在 head 里三行代碼script if (localStorage.getItem(theme) dark) { document.documentElement.classList.add(dark); } /script表單校驗(yàn)放在作業(yè)里可以體現(xiàn)基本邏輯能力。前端校驗(yàn)只做體驗(yàn)服務(wù)端仍然要校驗(yàn)。下面這段檢查“郵箱是否為空且格式是否正確”const form document.querySelector(#contact-form); form.addEventListener(submit, (event) { event.preventDefault(); const email form.querySelector(#email); const emailPattern /^[^\s][^\s]\.[^\s]$/; if (!email.value.trim() || !emailPattern.test(email.value)) { const error form.querySelector(.error-message); error.textContent 請(qǐng)輸入有效的郵箱地址; email.focus(); return; } form.submit(); });event.preventDefault()阻止瀏覽器默認(rèn)提交先做校驗(yàn)正則里的[^\s]表示“一個(gè)或多個(gè)既不是空白也不是 的字符”這個(gè) pattern 只覆蓋基礎(chǔ)格式但作業(yè)演示已經(jīng)足夠。email.focus()讓用戶出錯(cuò)后直接回到輸入框交互比只彈一行提示更完整。5. 一鍵返回頂部與提交前驗(yàn)證個(gè)人網(wǎng)頁作業(yè)最后的10分鐘5.1 用 requestAnimationFrame 手寫平滑返回頂部長(zhǎng)頁面里“一鍵返回頂部”是高頻交互網(wǎng)上模板多用scrollTo({ top: 0, behavior: smooth })瀏覽器兼容性好但有短板無法自定義時(shí)間和緩動(dòng)手感。我習(xí)慣用requestAnimationFrame手動(dòng)控制代碼不長(zhǎng)而且能講清楚原理const backTopBtn document.querySelector(#back-top); function scrollToTop() { const startY window.scrollY; const duration 300; const startTime performance.now(); function step(now) { const progress Math.min((now - startTime) / duration, 1); const easeOutCubic 1 - Math.pow(1 - progress, 3); window.scrollTo(0, startY * (1 - easeOutCubic)); if (progress 1) { requestAnimationFrame(step); } } requestAnimationFrame(step); } backTopBtn.addEventListener(click, scrollToTop);performance.now()返回毫秒級(jí)時(shí)間戳progress被限制在 0 到 1 之間超過 duration 后不再繼續(xù)。easeOutCubic是先快后慢的緩動(dòng)曲線視覺上比線性滾動(dòng)自然。400ms 以上會(huì)顯得拖沓300ms 是點(diǎn)擊按鈕后不覺得太急的手感。按鈕顯示時(shí)機(jī)可以用一個(gè) pure 的滾動(dòng)監(jiān)聽控制window.addEventListener( scroll, () { backTopBtn.hidden window.scrollY window.innerHeight; }, { passive: true } );hidden屬性由瀏覽器原生支持不需要維護(hù) classpassive: true告訴瀏覽器不阻止默認(rèn)滾動(dòng)行為避免滾動(dòng)性能損耗。5.2 提交前的三個(gè)快速檢查交作業(yè)前花 10 分鐘做三個(gè)檢查比什么都穩(wěn)。第一步用 VSCode 的 Live Server 或直接在瀏覽器里打開 html 文件打開 DevTools 的 Console 面板紅色報(bào)錯(cuò)必須清零特別是“Uncaught TypeError”。第二步DevTools 里把視口切到 320px 寬度左右來回拖動(dòng)出現(xiàn)橫向滾動(dòng)條就先查圖片是否設(shè)置了max-width: 100%再查site-header是否用flex-wrap或合理padding控制。第三步打開 Network 面板刷新一次找到返回 404 的文件請(qǐng)求常見原因是css/style.css的斜杠路徑寫錯(cuò)。驗(yàn)證時(shí)如果碰到橫向滾動(dòng)條先給img、pre這類可能溢出的元素補(bǔ)上max-width: 100%大多數(shù)個(gè)人網(wǎng)頁作業(yè)的布局問題都出在這一句上。本文還有配套的精品資源點(diǎn)擊獲取