Thymeleaf只处理th:前缀属性,href="/css/app.css"被浏览器直接请求,但Spring Boot静态资源映射路径为/static/**,故需用th:href="@{/css/app.css}",路径从resources/static/下开始写,不带static前缀。

必须用 th:href + @{...},不能直接写 href;路径从 resources/static/ 开始算,不带 static 前缀。
为什么 href="/css/app.css" 不生效?
Thymeleaf 会忽略原生 HTML 属性,只处理带 th: 前缀的指令。浏览器直接请求 /css/app.css,但 Spring Boot 默认静态资源映射路径是 /static/**,所以实际文件必须放在 resources/static/css/app.css,而访问路径要写成 @{/css/app.css} —— 这里的 /css/... 是相对于 static 目录的,不是 URL 根路径。
常见错误现象:
- 页面无样式,控制台报 404(如
GET http://localhost:8080/css/app.css 404) - 明明文件在
static/css/下,却反复尝试加static/前缀(如@{/static/css/app.css}),结果变成/static/static/css/...导致 404 - 用 IDE 预览 HTML 时样式正常(因为浏览器直接读本地文件),但运行 Spring Boot 后失效
@{...} 路径怎么写才对?
@{...} 是 Thymeleaf 的链接表达式,它会自动拼接上下文路径(context path)和静态资源路径。只要文件在 resources/static/ 下,路径就从该目录内结构开始写。
立即学习“前端免费学习笔记(深入)”;
正确写法示例:
<link rel="stylesheet" th:href="@{/css/bootstrap.min.css}">
<link rel="stylesheet" th:href="@{/plugins/fontawesome/css/all.min.css}">
注意:
- 不要写
./css/、../css/或static/css/ - 如果项目配置了
server.servlet.context-path=/myapp,@{/css/app.css}会自动解析为/myapp/css/app.css,无需手动拼接 - 路径中支持变量,比如
@{/css/{theme}.css(theme=${themeName})}
多个页面共用 CSS 怎么避免重复写?
抽成独立 fragment,比如 templates/modules/head.html:
<th:block th:fragment="common-css">
<link rel="stylesheet" th:href="@{/css/base.css}">
<link rel="stylesheet" th:href="@{/css/theme.css}">
</th:block>
然后在其他页面引用:
<head>
<th:block th:replace="~{modules/head :: common-css}"></th:block>
</head>
这样改一处,全站生效。注意:th:replace 会替换整个标签内容,th:include 已废弃,别用。
外部 CSS 文件里再引入字体或图片也会 404?
会。CSS 里的 url(...) 是相对 CSS 文件自身位置解析的,不是 Thymeleaf 上下文。比如 static/css/app.css 里写了 background: url(../images/logo.png),浏览器会请求 /images/logo.png(根路径),但文件实际在 /static/images/logo.png。
解决方法只有两个:
- 把资源路径写成绝对路径并确保匹配静态资源配置,例如
url(/images/logo.png)(前提是没改spring.mvc.static-path-pattern) - 或者统一把所有静态资源放平级目录下,让 CSS 中的相对路径能自然对齐,比如把字体、图片都放进
static/assets/,CSS 里写url(assets/fonts/icon.woff)
最容易被忽略的是:CSS 内部的路径问题完全不受 Thymeleaf 控制,@{...} 在 CSS 文件里无效,只能靠目录结构和服务器配置兜底。


















