您让智能体改一下页面,简单项目里就冒出几个名字看不懂的文件:index.html、style.css、script.js。或者这些文件本来就在,智能体的报告里写着"改了样式",光看这句话根本不知道它到底动了什么。

本文拆解浏览器接收的三项基础技术:HTML、CSS 和 JavaScript。为了讲清楚,我们用一个不需要构建的简单静态页面做例子。真实仓库里的文件名和位置可能不一样,所以动手改之前,先让智能体展示项目结构、找出负责目标元素的文件会更省事。本文不教您手写页面布局,这件事交给智能体就好。

页面就是浏览器读的文本

先从简单的静态页面说起:它的源码就是普通文本文件,用记事本就能打开阅读。这里不需要额外构建:浏览器读取 HTML,加载关联的资源,再据此把页面画到屏幕上。

这类项目的起点通常是 index.html 文件。浏览器打开它,解析标签,再按链接加载样式、脚本、图片和字体。

浏览器读取简单静态项目的三个文件,展示出完整的页面index.htmlstyle.cssscript.js浏览器完整页面
简单静态项目可能是这样运作的:浏览器加载三个关联文件,展示出页面

如果项目要经过构建,源码可能存放在组件里,最终的 HTML、CSS 和 JavaScript 由专门的工具生成。下面这三个角色依然是有用的参照,但不用去项目里找同名的三个文件。

我们的简单例子里用三个各司其职的文件:

  • HTML:页面上有什么,标题、段落、按钮、图片;
  • CSS:看起来怎样,颜色、字体、间距、圆角、过渡效果;
  • JavaScript:会发生什么,点击、输入文字、定时器触发。

接下来逐一说明。

HTML:标签构成的结构

HTML 是结构标记,不是绘图。您不用描述按钮长什么样,只要说"这里有个按钮",浏览器自己会把它画出来。

结构的基本单位是标签。几乎总是成对出现:开始标签和结束标签,中间夹着内容。

button 开始 这一行拆成三部分:开始标签、内容和结束标签,整体标注为一个 HTML 元素<button>开始</button>HTML 元素开始标签结束标签内容
这个例子里,三部分共同组成页面上的一个元素

每个部分都有自己的名字,整体则叫做元素。这个词很有用:说到页面时,人们常说"元素",指的就是标签连同里面的内容。

标签名是英语单词的缩写:p 来自 paragraph,a 来自 anchor,img 来自 image。不用死记硬背,但了解这一点通常能帮您猜出陌生标签的作用。

结束标签的区别在于多了一道斜杠。也有元素根本没有结束标签,比如 <img> 不能包含文字或嵌套标签,图片地址是通过 src 属性传进去的。

标签互相嵌套,就像盒子套盒子,关闭顺序反过来:先关内层,再关外层。顺序错了浏览器不会崩溃,它会试着猜,通常猜得不太准。

第二个概念是属性。它是写在开始标签里的补充说明,告诉浏览器一些细节:链接指向哪里、图片从哪取、这个元素叫什么名字。

<a href="https://example.com">打开网站</a>
<img src="cover.png" alt="封面">
<button id="play" class="btn">开始</button>

最后一行的 class 属性两分钟后就会用到:样式靠它应用到按钮上。id="play" 属性给它一个唯一的名字,脚本靠这个名字找到按钮。

现在来看完整的一页,比想象中要短:

<!doctype html>
<html>
<head>
  <title>我的页面</title>
</head>
<body>
  <h1>第一个页面</h1>
  <p>一段普通的文字。</p>
  <button id="play" class="btn">开始</button>
</body>
</html>

分成两部分:<head> 是幕后部分,放浏览器标签页标题和样式链接;<body> 是读者在屏幕上能看到的一切。第一行只是告诉浏览器,这是一份现代 HTML 文档。

页面的嵌套结构:html 里装着带标签页标题的 head,和装着屏幕上一切内容的 body<html></html><head></head><body></body><title>我的页面</title><h1>、<p>、<button>、<img>
盒子套盒子:head 和 body 装在 html 里面,其他内容又装在它们里面

这张图展示了结构最重要的特性:页面上的一切都装在某个东西里面。<body> 装在 <html> 里,按钮装在 <body> 里,文字装在按钮里。文件里那一层层缩进也是因为这个,不是为了好看,而是标出谁装在谁里面。

实际用起来道理很简单。浏览器标签页标题和样式的引用放在 <head> 里,屏幕上完全看不到。其余的一切都在 <body> 里。智能体在报告里写"在 body 里加了一个区块"时,说的正是第二个盒子:新内容出现在了页面上,而不是幕后部分。

这门语言里标签有上百个,但真实页面上翻来覆去用的几乎总是这几个:

标签作用
<h1> ... <h6>标题,从最主要到最次要
<p>一段文字
<a>链接,地址放在 href 属性里
<img>图片,文件路径放在 src 属性里
<button>按钮
<ul> 和 <li>列表和列表项
<div>块容器,用来装其他元素的盒子
<span>一行文字里想单独处理的一小段

最后两个本身没有任何含义,也不会画出任何东西。它们是空盒子,方便样式和脚本挂靠,正因为如此,任何页面上它们的数量都是最多的。

CSS:页面怎么有了样子

光秃秃的结构看起来很寒酸:白底黑字,灰色的系统按钮,一切都贴在左边。这和一个经过设计的页面之间的差距,大部分是 CSS 造出来的。

CSS 由规则组成。一条规则回答两个问题:应用在什么上,要改什么。

.btn {
  background: #6c5ce7;    /* 背景色 */
  color: #ffffff;         /* 文字颜色 */
  padding: 12px 24px;     /* 内边距 */
  border-radius: 12px;    /* 圆角 */
}

第一行是选择器:它说明这条规则应用到哪些元素上。接下来花括号里是一对对"属性: 值",每一对以分号结尾。

btn 前面的点表示这是一个类。还记得按钮上的 class="btn" 属性吗?这里就是它发挥作用的地方:您在结构里给元素贴上标签,在样式里再引用这个标签。同一个标签可以贴在十个按钮上,一条规则就能让这十个按钮长得一模一样。

CSS 的属性有几百个,但只要认识其中几个,读别人的文件就能大致看懂在干什么:

  • color 是文字颜色,background 是背景颜色或图片;
  • font-size 和 font-family 是字号和字体;
  • padding 是元素内部的间距,margin 是元素外部、和邻居之间的间距;
  • border-radius 是圆角,也是让界面看起来"高级"的一半功劳;
  • transition 让变化变得平滑,不是一下子跳过去,而是花 0.2 秒完成。

规则大多写在独立的文件里,页面通过幕后部分的一行代码知道它的存在:

<head>
  <link rel="stylesheet" href="style.css">
</head>

去掉这一行,样式文件就不会加载。文字和元素依然留在结构里,但熟悉的布局和外观可能会消失,页面有时也会变得更难用。

同一份结构展示两次:左边没有样式,只有文字和灰色矩形按钮,右边是同样的元素,加上了间距、颜色和圆角只有 HTMLHTML 加 CSS
元素完全相同,顺序也一样。变化的只有颜色、间距和形状

图中左右两边是同一个页面:标题、两行文字、一个按钮。没有增加也没有减少任何元素,这个例子里只改动了样式文件。

这是排查思路的地图,不是技术上的高墙。有时新布局需要智能体去改 HTML 里的类或容器,而一条写歪的 CSS 规则也可能盖住按钮、挡住点击。所以每次视觉改动之后,都要看看 diff、打开页面、检查受影响的操作。

JavaScript:动作发生的地方

HTML 和 CSS 已经能展示页面,加上平滑的过渡或动画。但我们例子里的按钮还没有自己的行为:点它,分数不会变。

页面上的自定义逻辑通常由 JavaScript 添加。按钮在 HTML 里已经有了唯一的名字 id="play"。接下来的思路很简单:找到元素,等一个事件发生,再改点什么。

// 通过 id 找到按钮
const button = document.getElementById("play");
let score = 0;

// 监听事件:点击时要做什么
button.addEventListener("click", function () {
  score = score + 1;
  button.textContent = "得分:" + score;
});

第一次点击把文字变成"得分:1",第二次变成"得分:2"。如果什么都没发生,先检查 HTML 里是不是写着 id="play",脚本里用的是不是同一个名字 play。

这里有三个细节。const 和 let 用来声明变量,也就是一个带名字、装着值的盒子。addEventListener 让页面监听某个事件:点击、输入文字、鼠标悬停。花括号里则是一个函数,事件发生时才会执行的一段代码。

注意最后一行:脚本改的是按钮的文字。这一点很重要:JavaScript 能在页面运行时直接改动结构和样式。它能添加一段文字、隐藏一个区块、给按钮换颜色。所以三个层之间的界线不是一堵墙,而是分工。

实际操作时,如果元素要响应数据、处理点击或做计算,先去 JavaScript 里找。平滑出现、变色、简单的移动往往是 CSS 做的。这只是一个起点,不是最终结论:改完之后打开页面,亲自检查外观和行为,光看一张截图是不够的。

一个按钮,三个文件

把所有内容放到一个元素上试试。"开始"按钮同时存在于三个文件里,各自负责自己的部分。

<button id="play" class="btn">开始</button>
.btn {
  background: #6c5ce7;
  border-radius: 12px;
}
const playButton = document.getElementById("play");

playButton.addEventListener("click", function () {
  playButton.textContent = "游戏已开始";
});

如果三个文件都连接好了,点击会把"开始"变成"游戏已开始"。现在这个例子就能实际测试,不用再凭空想象一个不存在的功能。

接下来是最有用的部分,看看去掉某一行会发生什么:

  • 去掉 HTML,一切都消失了:没有东西可以再拿去做样式或加逻辑;
  • 去掉 CSS,按钮还在原地,照常能点,只是看起来像九十年代的灰色系统按钮;
  • 去掉 JS,按钮长得好看,但是死的。点了也没有任何反应。

由此得到一张给智能体布置任务时用的简单地图。如果您不满意它看起来怎么样,先从样式找起。如果不满意它做了什么,先从脚本找起。如果元素根本不存在,那就从结构找起。注意是"先从",真正的改动可能会波及相邻的层,所以智能体的结论要看 diff,还要在浏览器里核实。

项目文件夹里都有什么

简单页面最常见的配置是这样的:

index.html    结构,入口文件
style.css     样式
script.js     行为

它们靠结构里的两行代码连在一起。样式在幕后部分引入,脚本放在最后、</body> 关闭之前,这样脚本运行时所有元素已经存在:

<head>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <!-- 页面结构 -->
  <script src="script.js"></script>
</body>

也有不一样的情况。大项目里文件有几十个,分放在 css/、js/ 这样的文件夹里,旁边还有图片和字体。也可能反过来,只有一个文件,这种情况紧接着下面就会说到。结构、样式、逻辑这三个角色始终存在,只是文件名和引入方式可能不一样。

样式和脚本写在页面内部的情况

三个文件是最常见的配置,但不是唯一一种。同一份 CSS 可以放在三个不同的地方,这三种您迟早都会遇到。

第一种您已经见过:独立文件加一行 <link>。第二种是把 <style> 区块直接写在结构里,不用单独的文件:

<head>
  <style>
    .btn {
      background: #6c5ce7;
      border-radius: 12px;
    }
  </style>
</head>

里面的写法完全一样:选择器、花括号、"属性: 值"对。变的只是位置。这种写法适合只有一个页面、不值得为它单独建文件的场景。

第三个位置是内联样式,也就是 inline styles。属性直接挂在元素上,写在 style 属性里:

<button class="btn" style="background: #e17055; font-size: 20px">开始</button>

这里不需要选择器:规则显然就是针对写着它的那个元素。所以没有花括号,也没有类前面的点,只是一对对"属性: 值"用分号隔开,全部写在一行里。

这种写法只有一次性用的时候方便。接下来全是缺点。规则只对这一个元素生效:十个按钮就要写十份,以后要改就得十个都改。普通的内联样式的优先级通常高于文件里的普通规则。用 style 给按钮上了色,再去 style.css 里改同一个属性,却搞不懂颜色为什么没变。所以 style 属性该是最先排查的对象之一,详细的优先级规则暂时用不上。

脚本的情况差不多,只是位置有两个。独立文件通过 <script src="..."> 引入,也可以直接把代码写在标签之间:

<script>
  document.getElementById("play").addEventListener("click", function () {
    alert("游戏已开始");
  });
</script>

整理成一张表,方便随时查看:

什么放在哪里HTML 里长什么样
样式独立文件<link rel="stylesheet" href="style.css">
样式页面内的区块<style> ... </style>
样式直接写在元素上style="color: red"
脚本独立文件<script src="script.js"></script>
脚本页面内的区块<script> ... </script>

最极端的情况是把所有东西都堆到一起:结构、<style> 区块、<script> 区块全都写在一个 index.html 里。这没什么可怕的,对小页面来说甚至更简单:只有一个文件,浏览器打开就能用,路上不会丢东西。麻烦是后来才出现的,页面变大之后,要在这一大团里找东西就难了。这时候内容通常会被拆到各自的文件里,变成前面说的那老三样。

在让智能体"改一下样式"之前,先弄清楚样式放在哪。如果项目里只有一个 index.html,可能根本没有 style.css 这个文件,改动其实是在结构内部完成的。如果元素没有变化,请智能体检查三件事:该引入的样式文件有没有连接上,选择器对不对,元素上有没有内联的 style 或者优先级更高的规则。这样排查范围就能缩小,不用瞎猜是谁的问题。

和 Claude Code 配合时怎么运作

现在清楚了智能体处理页面时到底在做什么:

  • 在简单的静态项目里,智能体可以自己写好并连接 HTML、CSS 和 JavaScript。在其他项目里,先让它展示项目结构,说出负责目标元素的文件;
  • 写入之前能看到多少内容,取决于设置和工作模式。如果智能体提前展示了改动方案,请先审阅;写入之后无论如何都要看一下 diff 和最终文件。style.css 这样的文件名能提示文件的角色,但并不能保证什么;
  • 视觉上的改动要靠肉眼查看、点击受影响的元素来确认,行为上的改动要靠实际操作来确认。截图看不出计数器已经不会计数了;
  • 如果出了问题,描述观察到的现象,而不是您猜测出问题的那一层:"改完之后按钮还看得见,但点击没有任何反应"。这样智能体就能去检查 HTML、CSS 和 JavaScript 之间的连接。