零基础用HTML+CSS+JS手写贪吃蛇游戏

简介:本资源是一份面向前端初学者的HTML贪吃蛇游戏实战项目,聚焦网页基础交互开发,帮助学习者掌握HTML结构搭建、CSS样式控制与JavaScript核心逻辑的协同实现。压缩包共3个文件(1个HTML主程序、1张背景图、1张角色图),总大小仅86KB,轻量易上手,适合嵌入式学习或课堂演示场景。HTML文件承载完整游戏入口与DOM结构,图片资源用于界面美化,整体结构简洁清晰,便于理解页面渲染与事件驱动机制。已有1454人学习下载,反映出其在入门级Web游戏开发中的高实用性与教学认可度。学习者可直接运行index.html体验完整游戏流程,同时深入研读代码,掌握键盘事件监听、setInterval定时刷新、蛇身坐标管理、碰撞检测逻辑及分数实时更新等关键技能,是巩固HTML+CSS+JS三件套综合应用能力的优质练手案例。

1. 这不是写网页,是用“画布+逻辑”亲手捏出一条会动的蛇:零基础也能跑通的 HTML 贪吃蛇

你是不是也试过点开一个网页小游戏,看着那条小蛇左拐右拐、越吃越长,心里嘀咕:“这玩意儿真就靠 HTML 写出来的?不是得装软件、下引擎、配环境吗?”——别怀疑,它真就是用你浏览器里天天打开的 HTML、CSS 和 JavaScript 三件套搭出来的。HTML 不只是排文字、插图片的“说明书”,它还能当舞台;CSS 不只是调颜色、改字体的“化妆师”,它能定位置、做动画;JavaScript 更不是玄学代码,它就是那个在后台掐着秒表、算着坐标、喊“蛇头撞墙了!”的裁判兼导演。这份「用 HTML 做贪吃蛇」资源,就是一套从空白文件开始、不装任何额外工具、不连服务器、双击就能在浏览器里跑起来的完整实践包。它适合所有刚听说“前端”但还没分清 HTML 和 Word 的人,也适合想亲手验证“代码真能控制画面”的好奇者。你不需要懂算法,不用背语法,只要愿意把几行代码复制粘贴进记事本,再拖进浏览器——5 分钟后,你就拥有一条听你键盘指挥的蛇。


2. 先搞懂三个角色:HTML 是舞台,CSS 是布景,JavaScript 是导演

2.1 HTML:不是“写文章”,是“搭舞台框架”

很多人第一次学 HTML,以为是在写作文——其实你在搭一个空剧场。<html>是整个剧场的屋顶,<body>是舞台地面,而<canvas id="game">这一行,就是你在舞台上钉下一块 400×400 像素的黑板。它不显示内容,只提供一个“可画区域”。你后面所有动作——蛇爬、食物闪、分数跳——都发生在这块黑板上。它不像<img>或<p>那样自带内容,它像一张白纸,等着 JavaScript 拿笔去画。所以别急着往里塞文字或图片,先确认这行代码存在、ID 名字拼对(后面 JS 会靠这个 ID 找到它),这就完成了“搭台”。

<!DOCTYPE html> <html> <head> <title>我的第一条贪吃蛇</title> <meta charset="utf-8"> </head> <body> <!-- 这就是舞台:一块叫 game 的画布 --> <canvas id="game" width="400" height="400"></canvas> </body> </html>

这段代码保存为snake.html,双击用 Chrome 或 Edge 打开,你会看到一片空白——别慌,这是正常现象。它没报错,说明舞台已搭好;它没内容,正等着你请导演(JS)上场。注意:width和height是画布“实际大小”,不是 CSS 放大缩小,改这里才真正影响游戏区域分辨率。

2.2 CSS:不是“美颜滤镜”,是“定舞台规矩”

CSS 在这里干两件事:一是让画布居中、加边框,让你一眼看清边界;二是关掉浏览器默认给<body>加的 8 像素外边距(margin),否则舞台会偏移、蛇头可能卡在看不见的缝隙里。新手常误以为 CSS 是“锦上添花”,其实它是“保命规则”——没有它,你写的蛇可能一半在屏幕外,或者撞墙检测永远失灵。

body { margin: 0; /* 关键!去掉浏览器默认外边距 */ display: flex; justify-content: center; align-items: center; min-height: 100vh; background: #f0f0f0; } #game { border: 2px solid #333; background: white; }

把上面 CSS 放进<head>里的<style>标签内,或另存为style.css并用<link rel="stylesheet" href="style.css">引入。效果是:页面变灰底,画布稳稳居中,带一道清晰黑边。重点看margin: 0——这是血泪经验:某次我调试半天发现蛇总在右下角消失,最后发现是 body 默认 margin 把画布挤歪了,蛇头坐标算出来却撞在“看不见的墙”上。

2.3 JavaScript:不是“写程序”,是“当实时裁判”

JS 是整场戏的灵魂。它不做复杂计算,只干三件事:
①记状态:蛇头在哪(x, y)、朝哪走(dx, dy)、身体多长(数组存每节坐标);
②盯时间:每 120 毫秒(约 8 帧/秒)检查一次:蛇该往哪挪?吃到食物没?撞自己或墙没?
③画画面:清空画布 → 画蛇身 → 画食物 → 显示分数。
它不预演、不预测,纯靠“下一帧”实时判断。所以你按方向键,不是立刻改变蛇头,而是告诉 JS:“下次检查时,请把 dx/dy 设成 -1/0/1”,它会在下一个 120ms 后执行。这种“帧驱动”逻辑,是所有游戏的基础,也是新手最容易卡壳的点——别想“按下就动”,要想“下一帧才动”。


3. 第一个能跑的例子:从零开始,手敲 60 行代码,让蛇动起来

3.1 准备工作:建三个文件,理清分工

你只需要新建三个纯文本文件(用记事本、VS Code 或任意编辑器):

  • snake.html:放 HTML 结构 + 内联 CSS + 引入 JS
  • style.css(可选):放样式,若嫌麻烦可全写进 HTML 的<style>里
  • script.js:放全部游戏逻辑

提示:文件必须放在同一文件夹下,且名字一字不差。大小写敏感,Script.js或snake.HTML都会导致 JS 找不到画布。

3.2 复制粘贴:60 行极简版,专注“动起来”

下面代码是删减到只剩核心逻辑的版本(无分数、无重启、无音效),目标只有一个:让蛇在画布里自动爬行,按方向键能转向。把它完整复制进script.js:

// script.js const canvas = document.getElementById('game'); const ctx = canvas.getContext('2d'); // 游戏参数:格子大小 20px,蛇初始位置在画布中央 const gridSize = 20; let snake = [{x: 10, y: 10}]; // 蛇身:一个对象数组,每个对象是 {x, y} 坐标 let food = {x: 15, y: 15}; // 食物位置 let dx = 0, dy = 0; // 蛇移动方向:dx=1向右,dy=-1向上 // 键盘监听:只响应方向键,避免按其他键干扰 document.addEventListener('keydown', (e) => { if (e.key === 'ArrowUp' && dy === 0) { dx = 0; dy = -1; } if (e.key === 'ArrowDown' && dy === 0) { dx = 0; dy = 1; } if (e.key === 'ArrowLeft' && dx === 0) { dx = -1; dy = 0; } if (e.key === 'ArrowRight' && dx === 0) { dx = 1; dy = 0; } }); // 主循环:每 120ms 执行一次 function gameLoop() { // 1. 更新蛇头位置(新头 = 旧头 + 方向) const head = {x: snake[0].x + dx, y: snake[0].y + dy}; // 2. 插入新头到蛇身最前面 snake.unshift(head); // 3. 简单逻辑:没吃食物就剪掉尾巴(保持长度),吃了就留着(变长) // (这里先不处理吃食物,只保证蛇能动) snake.pop(); } // 绘制函数:清屏 → 画蛇 → 画食物 function draw() { // 清空画布(重置为白色) ctx.fillStyle = 'white'; ctx.fillRect(0, 0, canvas.width, canvas.height); // 画蛇身:每节是 20×20 的绿色方块 ctx.fillStyle = 'green'; snake.forEach(segment => { ctx.fillRect(segment.x * gridSize, segment.y * gridSize, gridSize, gridSize); }); // 画食物:红色方块 ctx.fillStyle = 'red'; ctx.fillRect(food.x * gridSize, food.y * gridSize, gridSize, gridSize); } // 游戏主函数:循环调用更新和绘制 function main() { gameLoop(); draw(); } // 每 120ms 执行一次 main,形成动画 setInterval(main, 120);

3.3 让它跑起来:三步验证法

  1. 检查 HTML 是否引入 JS:打开snake.html,确认<body>底部有<script src="script.js"></script>(必须在</body>之前);
  2. 保存并刷新:保存所有文件,双击snake.html,等待 2 秒;
  3. 观察现象:
    • ✅ 正确:绿色方块(蛇)从画布中央开始,自动向右缓慢爬行;按上下左右键,蛇立即转向(注意:不能 180° 急转弯,比如向右时按左键无效,这是防自杀设计);
    • ❌ 错误:一片空白 → 检查script.js文件名是否拼错、是否和 HTML 同目录;
    • ❌ 错误:蛇不动 → 检查浏览器控制台(F12 → Console)是否有Uncaught TypeError: Cannot read property 'getContext' of null,说明getElementById('game')没找到画布,大概率是 HTML 里<canvas>的id写成了gamee或大小写不对。

注意:这段代码故意没加“撞墙死亡”逻辑,所以蛇会穿墙而出,从另一边进来——这是刻意为之的简化。先确保“动”和“转向”成立,再加规则。


4. 新手必踩的 5 个坑:我翻车三次才总结出的排查清单

4.1 现象:页面空白,控制台报错 “Cannot read property 'getContext' of null”

原因:JavaScript 执行时,还没找到<canvas id="game">这个元素。常见于:JS 代码写在<head>里(此时 HTML 还没加载完),或id名字拼错(如写成game-canvas但 JS 里写getElementById('game'))。
解决:把<script src="script.js"></script>放到<body>最底部(</body>之前);用浏览器开发者工具(F12)右键检查画布元素,确认其id属性值完全一致。

4.2 现象:蛇不动,控制台无报错

原因:setInterval(main, 120)没触发,大概率是main函数名写错,或main里漏写了gameLoop()或draw()调用。也可能是浏览器禁用了脚本(极少见,但可检查地址栏左侧图标)。
解决:在main函数第一行加console.log('tick');,刷新页面看控制台是否每 120ms 打印一次。不打印 → 检查setInterval语法;打印了但蛇不动 → 检查gameLoop里snake.unshift(head)是否执行(在unshift前加console.log(snake)看数组是否增长)。

4.3 现象:蛇乱跳、坐标突变、一按键就消失

原因:dx/dy被重复赋值。例如在keydown事件里写了dx = 1; dx = -1;连续两行,或没加&& dy === 0判断导致反向键生效。
解决:把keydown事件里的所有dx/dy赋值,替换成console.log('up:', dx, dy),按方向键看控制台输出是否符合预期(如按↑应输出up: 0 -1)。确保每个if分支互斥,且只改一个方向变量。

4.4 现象:蛇看起来“抖动”或移动不流畅

原因:setInterval时间设太短(如10),浏览器来不及渲染;或太长(如500),动画卡顿。120ms(≈8fps)是平衡点,既不卡又不快。另一个原因是画布width/height和 CSS 设置冲突(如 HTML 里设width="400",CSS 又用#game{width: 800px}拉伸),导致坐标计算错乱。
解决:固定用setInterval(main, 120);检查画布属性:右键画布 → “检查元素”,看 computed 样式中width和height是否与 HTML 中width/height属性值一致。不一致就删掉 CSS 里的width/height,只靠 HTML 属性控制。

4.5 现象:按方向键没反应,但控制台有tick日志

原因:键盘事件监听对象错了。document.addEventListener('keydown', ...)是对的;如果写成canvas.addEventListener('keydown', ...)就无效,因为键盘事件默认不冒泡到 canvas,需监听全局document。
解决:确认事件监听写在document上;测试方法:在keydown回调里加console.log(e.key),按任意键看是否输出键名(如ArrowUp)。不输出 → 监听对象错误;输出了但蛇不动 → 问题在if判断逻辑。


5. 下一步学什么:从“会动”到“能玩”,一条平滑升级路径

5.1 加一条“吃食物”逻辑:3 行代码,游戏立活

现在蛇只会爬,加“吃”就让它有目标。核心就三步:
① 判断蛇头坐标是否等于食物坐标;
② 相等则生成新食物(随机位置,避开蛇身);
③ 不剪尾巴(snake.pop()不执行),蛇就变长了。

在gameLoop()函数里,snake.unshift(head)后面插入:

// 检查是否吃到食物 if (head.x === food.x && head.y === food.y) { // 生成新食物:随机位置,但确保不在蛇身上 food = { x: Math.floor(Math.random() * canvas.width / gridSize), y: Math.floor(Math.random() * canvas.height / gridSize) }; // 不执行 snake.pop(),蛇身自动变长 } else { snake.pop(); // 没吃到才剪尾巴 }

注意:Math.random()生成 0~1 小数,乘以格子数再Math.floor得整数坐标。canvas.width / gridSize是画布能容纳的格子总数(400/20=20),所以x和y范围是 0~19,完美适配。

5.2 加“撞墙死亡”:5 行判断,建立真实边界感

当前蛇穿墙,加四条边界判断即可。在gameLoop()开头,const head = ...后面插入:

// 检查是否撞墙:x 或 y 超出 [0, 画布格子数) 范围 if (head.x < 0 || head.x >= canvas.width / gridSize || head.y < 0 || head.y >= canvas.height / gridSize) { alert('Game Over! 你撞墙了!'); snake = [{x: 10, y: 10}]; // 重置蛇 dx = 0; dy = 0; // 停止移动 food = {x: 15, y: 15}; // 重置食物 }

这段代码让蛇一旦越界就弹窗、重置。它用的是“硬重置”,后续可升级为“暂停+按钮重启”,但此刻目标明确:先让规则生效,感受“失败”的反馈。

5.3 加“撞自己死亡”:遍历身体,1 行核心判断

蛇头碰到自己身体任何一节,就 Game Over。只需在撞墙判断之后,加一个循环:

// 检查是否撞自己:跳过蛇头(i=0),从第二节开始比 for (let i = 1; i < snake.length; i++) { if (head.x === snake[i].x && head.y === snake[i].y) { alert('Game Over! 你咬到自己了!'); snake = [{x: 10, y: 10}]; dx = 0; dy = 0; food = {x: 15, y: 15}; break; // 找到就退出,避免重复弹窗 } }

血泪经验:初学者常写for (let i = 0; i < snake.length; i++),结果蛇头永远等于自己,一运行就弹窗。记住:i=0是蛇头,必须从i=1开始比。

5.4 学习路径建议:按“功能模块”拆解,拒绝死磕文档

你不需要一口气啃完 JavaScript 所有语法。按这个顺序推进,每步 30 分钟,当天就能看到成果:

阶段目标关键动作查什么资料
第1天:动起来蛇自动爬、能转向敲完 3.2 节代码,调通setInterval和keydownMDNsetInterval、KeyboardEvent.key
第2天:有目标吃到食物变长、随机刷新加if (head===food)和Math.random()MDNMath.random、Array.push/unshift
第3天:守规则撞墙/撞己死亡、弹窗提示加if (head.x < 0)和alert()MDNalert、比较运算符< >=
第4天:更友好显示分数、空格键重启用<div>显示score变量,监听e.key===' 'MDNdocument.getElementById().textContent
第5天:像游戏按钮控制、背景音乐(可选)用<button onclick="reset()">替代alertMDNonclick、<audio>标签

从那以后我每次教新人,都强制他们先删掉所有“炫技代码”(比如渐变色、阴影、计时器),只留snake,food,dx/dy,setInterval这四个变量和一个循环。跑通再加,加一条测一条。因为贪吃蛇的本质不是“多酷”,而是“坐标、方向、时间”这三个概念的诚实对话——蛇不会骗你,它动不了,一定是坐标算错了;它不转向,一定是dx/dy没更新。这种即时反馈,是编程世界里最珍贵的“后悔药”。希望帮到你。

本文还有配套的精品资源,点击获取

相关新闻

rea项目实战:从资源管理到系统设计的关键技术解析

rea项目实战:从资源管理到系统设计的关键技术解析

项目标题: rea项目正文: rea关键词:摘要描述:输入信息严重不足。当前仅提供“rea”一个词条&#xff0c;无法判断其所属领域&#xff08;科技/生活/职场/手工等&#xff09;、项目类型&#xff08;工具/方法/系统/概念等&#xff09;、目标用户与核心诉求&#xff0c;也无法确定…

2026/10/21 5:23:08 阅读更多 →
运行时环境分析器 rea:用现场快照还原故障真相,加速根因定位

运行时环境分析器 rea:用现场快照还原故障真相,加速根因定位

说起来有点不好意思&#xff0c;这个项目最开始只有三个字母&#xff1a;rea。旁边同事看到代码仓库名的时候&#xff0c;问得最多的一句是&#xff1a;你是在写单词缩写还是在写咒语&#xff1f;其实两个意思都有。当时我被一类特别讨厌的线上问题反复折磨&#xff1a;日志、监…

2026/10/21 5:23:08 阅读更多 →
宝马6GT音响升级记录:东莞虎门杰之声低音系统案例

宝马6GT音响升级记录:东莞虎门杰之声低音系统案例

摘要&#xff1a;本案例围绕宝马6GT的低频表现展开&#xff0c;重点记录法国FOCAL劲浪亚麻盆10英寸低音与原装箱体的安装过程&#xff0c;以及东莞虎门杰之声对尾箱空间、固定方式和系统衔接的施工处理。文中不涉及价格、优惠或联系方式。图&#xff1a;宝马6GT到店&#xff0c…

2026/10/21 5:23:08 阅读更多 →

最新新闻

MySQL与MongoDB日志体系实战:慢查询排查与故障恢复

MySQL与MongoDB日志体系实战:慢查询排查与故障恢复

运维数据库这些年&#xff0c;我有个很深的体会&#xff1a;MySQL和MongoDB放在一起讲日志&#xff0c;不是因为他们像&#xff0c;恰恰是因为他们太不一样了。很多团队两个库都在用&#xff0c;白天业务跑着没事&#xff0c;一到高峰期告警就炸锅&#xff0c;大家下意识去翻日…

2026/10/21 6:07:27 阅读更多 →
DNS主从复制与分离解析:高可用架构与流量调度实战

DNS主从复制与分离解析:高可用架构与流量调度实战

1. 从一个真实运维场景说起&#xff1a;为什么DNS主从和分离解析值得单独拿出来讲很多刚接触DNS运维的朋友&#xff0c;第一次把域名解析服务搭起来的时候&#xff0c;通常都是单机跑一个服务&#xff0c;配置文件里写几条A记录&#xff0c;测试一下能解析出IP&#xff0c;就觉…

2026/10/21 6:07:27 阅读更多 →
Pikachu靶场实战:文件包含漏洞从原理到利用与防御全解析

Pikachu靶场实战:文件包含漏洞从原理到利用与防御全解析

1. 认识文件包含漏洞&#xff1a;一个include引发的连锁反应1.1 文件包含漏洞到底是什么很多刚入门的朋友第一次听到“文件包含”四个字&#xff0c;第一反应是“是不是类似引用别人的代码库”。这么理解大方向没错&#xff0c;但要害在于&#xff1a;在PHP这类服务端脚本语言中…

2026/10/21 6:07:27 阅读更多 →
【例 2】北极通讯网络(信息学奥赛一本通- P1487)

【例 2】北极通讯网络(信息学奥赛一本通- P1487)

【题目描述】原题来自&#xff1a;Waterloo University 2002北极的某区域共有 n 座村庄&#xff0c;每座村庄的坐标用一对整数 (x,y) 表示。为了加强联系&#xff0c;决定在村庄之间建立通讯网络。通讯工具可以是无线电收发机&#xff0c;也可以是卫星设备。所有的村庄都可以拥…

2026/10/21 6:07:27 阅读更多 →
STM32F411标准例程模板:从工程搭建到外设驱动开发实战

STM32F411标准例程模板:从工程搭建到外设驱动开发实战

简介&#xff1a;面向 STM32F411 开发者的一份标准例程模板&#xff0c;基于 ARM Cortex-M4 内核&#xff0c;涵盖启动代码、HAL 库、系统时钟配置、主函数框架及 LED/串口/定时器等外设示例&#xff0c;适合快速搭建项目并学习片上外设用法。压缩包 5.47MB&#xff0c;共 212 …

2026/10/21 6:07:27 阅读更多 →
HTTP实战笔记:从协议底层逻辑到线上问题排查的工程指南

HTTP实战笔记:从协议底层逻辑到线上问题排查的工程指南

1. 为什么值得重新聊一聊 HTTP做后端开发或者前端联调时间长了&#xff0c;你会发现一个现象&#xff1a;很多人对 HTTP 的理解停留在“请求-响应”“GET 和 POST 的区别”这个层面&#xff0c;一旦遇到线上问题——比如接口偶发超时、浏览器缓存不生效、跨域预检请求莫名多了一…

2026/10/21 6:06:26 阅读更多 →

日新闻

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

这段时间硬件圈和AI圈都在传一个事&#xff1a;AMD锐龙AI Max PRO 400系列把最高192GB统一内存搬进了PC形态的产品里&#xff0c;按宣传口径&#xff0c;本地跑320B参数的大家伙不再是纸面概念。我第一反应倒不是“内存真大”&#xff0c;而是这话背后的含金量——它把过去只能…

2026/10/21 0:00:11 阅读更多 →
AI助手深度使用体验:对话质量、长文本处理与指令遵循如何留住用户

AI助手深度使用体验:对话质量、长文本处理与指令遵循如何留住用户

1. 从“封号重开”这个行为说起&#xff1a;用户到底在追求什么“封号重开”这四个字&#xff0c;放在任何产品语境里都带着一股决绝的味道。一个账号从零开始积累使用记录、调教偏好、沉淀工作流&#xff0c;背后是大量的时间和精力成本。正常情况下&#xff0c;没有人愿意主动…

2026/10/21 0:00:11 阅读更多 →
ROS中YOLOv3工程落地:通信同步、坐标变换与性能调优

ROS中YOLOv3工程落地:通信同步、坐标变换与性能调优

1. 为什么在ROS里硬刚YOLOv3不是“炫技”&#xff0c;而是工程落地的必经之路我第一次在某高校机器人实验室看到那台搭载Jetson TX2的移动底盘原地打转、反复识别错垃圾桶时&#xff0c;就意识到&#xff1a;单纯跑通darknet_ros demo和真正让YOLOv3在ROS里“干活”&#xff0c…

2026/10/21 0:00:11 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型&#xff08;GMM&#xff09;的语音识别系统&#xff0c;很多人第一反应就是一堆数学公式&#xff0c;觉得门槛很高。但如果你真的在MATLAB里把它落地跑通&#xff0c;会发现核心其实就是三件事&#xff1a;把声音变成特征向量&#xff0c;用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人&#xff0c;但落到具体操作上&#xff0c;无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程&#xff1a;对图像做反白、改调色板、彩色转灰度&#xff0c;最后把像素数据导出成txt文件。单看每一…

2026/10/20 20:43:59 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词&#xff0c;你会发现一个很有意思的现象&#xff1a;每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型&#xff0c;有人指的是运动控制系统&#xff0c;还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/21 4:27:17 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 10:02:08 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:45 阅读更多 →