读懂网站的设计语言 · 02.2 / 04

如何看懂网页背后的实现

从截图、录屏和浏览器证据走到动画、状态、Canvas 与 Shader,逐层确认网页如何工作。

  • GoodVibe 编写
  • 多来源网页审查
  • 包含局部效果排查

一张截图只能告诉你结果长什么样,不能告诉你它为什么在这里、什么时候开始、怎样结束,也不能告诉你页面换到手机上之后是否仍然成立。Inspect 是把一个网页拆成几个可以审查的部分,再为每个判断找到证据。

证据可以来自浏览器开发者工具、插件、公开源码、截图与录屏、自动化浏览器检查和运行记录。你会从最容易确认的字体和布局开始,逐步走到动画、状态、资源、Canvas 和 Shader,并为每个问题选择合适的查看方式。

把看起来如此,改写成我知道它为什么如此。

Inspect 的目标

先拆对象

网页不是一个平面

研究网页时,不要只盯着首屏。先把它分成几个不同的观察面,再决定每个面需要哪一种证据。一个页面可以同时拥有清楚的 DOM 结构、复杂的时间轴和一块无法被 Token 替代的 WebGL 场景。

01

内容层

标题、正文、CTA、导航和页面先后顺序。先问用户被要求理解什么。

02

结构层

容器、Section、Grid、Flex、组件边界和响应式变化。先画出页面骨架。

03

视觉层

字体、颜色、间距、边框、材质、图像和视频处理。先找到可计算的值。

04

互动层

Hover、Click、Scroll、Drag、Menu、Loading 和 Error。先列出状态。

05

时间层

触发条件、duration、delay、easing、stagger 和结束状态。先记录一条时间线。

06

渲染层

DOM、CSS、SVG、Video、Canvas、WebGL、Shader 和后处理。先判断材料。

第一份证据

先从字体和布局开始

字体是最容易被 AI 猜错、又最容易影响整页比例的地方。打开开发者工具,选中标题,记录 Computed Style 里的字体族、字重、字号、行高、字间距和最大宽度,再到 Network 或字体面板确认文件是否真的被加载。

布局也一样。不要只量截图上的像素,要确认空间关系来自父容器、Grid、Flex 还是绝对定位。这样你在复刻时才知道应该保留规则,还是只保留一个尺寸。

Typography Evidence

font family · font file · font weight · font size · line height · letter spacing

max width · color · source: SOURCE / PARTIAL / GUESS

Layout Evidence

parent layout · container width · gap · padding · breakpoint · mobile change

开发者工具截图占位

字体和布局证据来自哪里

Visual pending

把页面中的标题与开发者工具证据放在同一张图里,用编号连接字体文件、Computed Style、父容器布局和最终换行。学员需要看见参数怎样改变页面比例。

  1. 01标题节点和最终换行同时可见
  2. 02圈出 font-family、font-size、line-height 与 max-width
  3. 03标出父容器的 Grid、Flex 或定位方式
  4. 04Network 中保留真实字体文件请求
正式素材加入后直接替换此占位块/course/chapter-02/inspect-typography-layout.webp

第二份证据

再看动画和状态

  1. 01

    找到触发条件

    确认动画是页面加载、进入视口、Hover、Click、Scroll 还是某个数据状态触发。

    留下 state-matrix.md
  2. 02

    记录变化属性

    分清 opacity、transform、filter、clip-path、尺寸和内容变化,不用“变得更有活力”代替参数。

    留下 motion-notes.md
  3. 03

    记录时间关系

    写下 duration、delay、easing、stagger 和最终状态,必要时把播放速度调慢再观察。

    留下 timeline.md
  4. 04

    验证可逆性

    检查返回、重复触发、刷新、移动端和 Reduced Motion 时是否仍然有合理的状态。

    留下 interaction-check.md

局部效果

先判断它是什么材料

一个会动的局部可能是 CSS、SVG、视频、Canvas、WebGL 或几种材料叠在一起。先分类,再决定要不要深入源码。分类错误会让你用一套完全不合适的实现方式反复补偿。

线索优先检查不要直接假设
元素可以被选中并有 CSS 状态DOM、Computed Style、动画面板一定是 JavaScript 动画
画面在 Canvas 中持续变化Console、Canvas、Network、运行时输入一定是纯 Shader
大文件随页面请求并循环播放Video、Poster、加载时机和遮罩一定是实时生成
资源失败后整块区域消失Network、MIME、ready 条件和 fallback只是 CSS 没写对
证据对照图占位

看起来像实时 3D,实际由视频和 Canvas 叠加

Visual pending

左侧放页面最终画面,中间标出 MP4 资源请求,右侧隔离轻量 Canvas 粒子层。图下注明哪些结论属于 SOURCE,哪些仍是 PARTIAL。

  1. 01画面、资源请求和渲染图层来自同一次捕获
  2. 02标明视频负责的部分与 Canvas 负责的部分
  3. 03保留 SOURCE / PARTIAL 标签
  4. 04记录原始来源和研究日期
正式素材加入后直接替换此占位块/course/chapter-02/rendering-material-evidence.webp

Shader 和 Canvas

把黑盒拆成输入和状态

第二章不要求你从零写 GLSL。你需要做的是确认这块视觉由什么输入驱动:时间、滚动、鼠标、触摸、分辨率、纹理,还是某个外部视频。画面不显示时,再按初始化、资源、编译和 ready 状态逐层排查。

先取证,再决定是否修改

请先不要修改这个效果的实现。 记录渲染元素、运行时入口、字体、图片、视频、纹理和外部请求。记录 Hover、Scroll、Pointer、Resize 对画面的影响,并把结论标记为 SOURCE、PARTIAL 或 GUESS。 画面没有出现时,按资源请求、Canvas 初始化、Shader 编译、ready 条件、输入参数的顺序排查。
我会保持工作区不变,先建立一份 Inspect Map。 第一轮只记录渲染材料、资源请求、触发条件和运行时输入。每条结论都会附上证据等级;如果画面黑屏,我会从 Network 和 Console 开始定位,并在确认原因以前停止修改。

这段对话没有调用额外 Skill。取证边界已经清楚时,Agent 可以直接按项目规则工作。

截图相似但动画时序不同

记录触发条件、时间线和结束状态,不要只调速度和位置。

Canvas 黑屏

先看资源、初始化和编译错误,再判断是否需要换实现。

移动端被当成桌面端裁切

单独记录 viewport、输入方式和替代方案。

猜测被写成了实现事实

保留 SOURCE、PARTIAL、GUESS,并把未确认项带入复刻。

本节练习

为一个片段建立 Inspect Map

从上一节的 Unknown 中挑一个会影响复刻路线的问题,只审查一个页面片段。先记录基线环境,再按内容、结构、视觉、互动、时间和渲染六层填写证据。二十分钟后仍然无法确认的内容保留为 GUESS,并写清下一步需要什么证据。

一次有边界的网页审查

inspect-map.md
# Inspect Map
## Target- source_url:- route:- fragment:- viewport:- browser:- state:
## Content- text_order:- fixed_or_dynamic:
## Structure- parent_layout:- component_boundary:- responsive_change:
## Visual- typography:- color_and_material:- spacing_and_shape:
## Interaction and Time- trigger:- changed_properties:- duration_delay_easing:- final_state:- reverse_or_repeat:
## Rendering- DOM / SVG / Video / Canvas / WebGL:- assets_and_requests:- runtime_inputs:- fallback:
## Evidence Ledger- [SOURCE] 结论:- evidence:- [PARTIAL] 结论:- missing:- [GUESS] 结论:- next_probe:
## Decision for Clone- implementation_route:- keep_faithful:- simplify_with_reason:- do_not_copy:

学习进度

正在读取你的学习记录…