ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Swagger UI 主题样式修改:从基础到深度定制(附完整代码示例)

Swagger UI 主题样式修改:从基础到深度定制(附完整代码示例) 1. 为什么需要自定义 Swagger UI 主题Swagger UI 是前后端开发中最流行的 API 文档可视化工具之一。它默认提供了简洁的界面风格但在实际项目中我们往往需要将 Swagger UI 的配色、Logo、字体等改为符合企业品牌规范的样式。本文将系统介绍从简单配色调整到深度主题定制的多种方案并附上可直接落地的代码示例。2. 基础方式通过 SwaggerUIBundle 配置注入 CSSSwagger UI 最常用的集成方式是通过SwaggerUIBundle初始化。在初始化配置中我们可以利用customCss属性直接注入自定义样式。这是最快捷的方式适合轻量级修改。2.1 HTML 集成示例!DOCTYPE html html langzh-CN head meta charsetUTF-8 titleAPI 文档/title link relstylesheet hrefhttps://unpkg.com/swagger-ui-dist5/swagger-ui.css /head body div idswagger-ui/div lt;script srchttps://unpkg.com/swagger-ui-dist5/swagger-ui-bundle.jsgt;lt;/scriptgt; lt;scriptgt; window.onload function () { SwaggerUIBundle({ url: https://petstore.swagger.io/v2/swagger.json, dom_id: #swagger-ui, customCss: .swagger-ui .topbar { background-color: #1a1a2e; } .swagger-ui .topbar .download-url-wrapper .select-label { color: #e0e0e0; } .swagger-ui .info .title { color: #16213e; font-size: 28px; } .swagger-ui .scheme-container { background-color: #f8f9fa; box-shadow: none; } , customSiteTitle: 我的 API 文档, deepLinking: true, presets: [ SwaggerUIBundle.presets.apis, SwaggerUIBundle.SwaggerUIStandalonePreset ], layout: StandaloneLayout }); }; lt;/scriptgt; /body /html这种方式适合快速调整顶栏颜色、标题样式等少量元素。所有样式直接写在customCss字段中Swagger UI 会自动将其注入到页面的style标签内。3. 覆盖 CSS 变量Swagger UI 3.x 的主题机制Swagger UI 3.x 版本引入了 CSS 自定义属性CSS Variables这让我们可以更优雅地实现主题切换而不需要深入到具体选择器中去覆盖样式。通过重写这些变量可以批量控制整体配色。3.1 核心 CSS 变量一览CSS 变量名作用范围默认值--swagger-ui-color-primary主色调链接、按钮等#4990e2--swagger-ui-color-success成功状态GET 按钮等#49cc90--swagger-ui-color-warning警告状态#ffa500--swagger-ui-color-error错误状态DELETE 按钮等#f93e3e--swagger-ui-color-info信息提示#89bf04--swagger-ui-font-family全局字体sans-serif--swagger-ui-font-size基础字号14px3.2 通过 HTML 覆盖变量style :root { --swagger-ui-color-primary: #6c5ce7; --swagger-ui-color-success: #00b894; --swagger-ui-color-warning: #fdcb6e; --swagger-ui-color-error: #d63031; --swagger-ui-font-family: PingFang SC, Microsoft YaHei, sans-serif; --swagger-ui-font-size: 15px; } .swagger-ui .topbar { background: linear-gradient(135deg, #6c5ce7, #a29bfe); } .swagger-ui .opblock-tag { border-bottom: 2px solid var(--swagger-ui-color-primary); } /style将上述style块放在 HTML 的head中优先于 Swagger UI 默认样式加载即可生效。使用:root选择器统一修改变量后所有引用这些变量的 UI 元素都会自动响应。3.3 通过 JavaScript 动态修改变量script // 动态切换主题 function applyTheme(theme) { const root document.documentElement; if (theme dark) { root.style.setProperty(--swagger-ui-color-primary, #74b9ff); root.style.setProperty(--swagger-ui-color-success, #55efc4); root.style.setProperty(--swagger-ui-color-warning, #ffeaa7); root.style.setProperty(--swagger-ui-color-error, #ff7675); document.querySelector(.swagger-ui .topbar) .style.background #2d3436; } else { root.style.setProperty(--swagger-ui-color-primary, #6c5ce7); root.style.setProperty(--swagger-ui-color-success, #00b894); root.style.setProperty(--swagger-ui-color-warning, #fdcb6e); root.style.setProperty(--swagger-ui-color-error, #d63031); document.querySelector(.swagger-ui .topbar) .style.background linear-gradient(135deg, #6c5ce7, #a29bfe); } } /script这种方式允许运行时切换主题例如白天/夜间模式非常适合需要在后台管理系统内嵌 Swagger UI 的场景。4. 深度定制自定义 Swagger UI 插件实现主题切换如果需要更复杂的主题定制例如多套主题、品牌 Logo 替换、自定义布局推荐使用 Swagger UI 的插件机制。通过编写专属插件我们可以在不影响核心功能的前提下做到完全可控。4.1 编写 TopbarPlugin 插件// swagger-theme-plugin.js const TopbarPlugin function (system) { return { components: { // 覆盖默认的 Topbar 组件 Topbar: function TopbarOverride(OriginalTopbar) { // 返回一个新的 React 组件包装器 const WrappedTopbar function (props) { // 使用 React.createElement 自定义顶栏 return React.createElement(div, { className: my-custom-topbar, style: { backgroundColor: #1e272e, padding: 12px 24px, display: flex, alignItems: center, justifyContent: space-between, boxShadow: 0 2px 8px rgba(0,0,0,0.15) } }, [ React.createElement(img, { key: logo, src: https://example.com/company-logo.png, alt: 公司Logo, style: { height: 32px } }), React.createElement(span, { key: title, style: { color: #ffffff, fontSize: 18px, fontWeight: 600, fontFamily: PingFang SC, sans-serif } }, 企业级 API 开放平台) ]); }; return WrappedTopbar; } } }; }; // 注册插件 window.onload function () { SwaggerUIBundle({ url: https://petstore.swagger.io/v2/swagger.json, dom_id: #swagger-ui, plugins: [TopbarPlugin], layout: StandaloneLayout, presets: [ SwaggerUIBundle.presets.apis, SwaggerUIBundle.SwaggerUIStandalonePreset ] }); };上述插件通过覆盖 Swagger UI 内部的Topbar组件完全接管了顶部导航栏的渲染逻辑。你可以在自定义组件中自由添加公司 Logo、产品名称、导航链接等元素。4.2 多主题切换插件白天/夜间模式// multi-theme-plugin.js const ThemeTogglePlugin function () { const themes { light: { topbarBg: #ffffff, topbarBorder: #e0e0e0, textColor: #333333, primaryColor: #6c5ce7 }, dark: { topbarBg: #1e272e, topbarBorder: #2d3436, textColor: #dfe6e9, primaryColor: #74b9ff } }; return { statePlugins: { theme: { actions: { toggleTheme: function () { return { type: THEME_TOGGLE, payload: null }; } }, reducers: { THEME_TOGGLE: function (state) { const current state.get(current) || light; const next current light ? dark : light; // 应用到 DOM const theme themes[next]; const root document.documentElement; root.style.setProperty(--swagger-ui-color-primary, theme.primaryColor); const topbar document.querySelector(.swagger-ui .topbar); if (topbar) { topbar.style.backgroundColor theme.topbarBg; topbar.style.borderBottom 1px solid theme.topbarBorder; } return state.set(current, next); } }, selectors: { currentTheme: function (state) { return state.get(current) || light; } } } }, components: { ThemeToggleButton: function () { var btn document.createElement(button); btn.innerText 切换主题; btn.style.cssText margin-left:16px;padding:6px 14px;border:1px solid #ccc;border-radius:4px;cursor:pointer;; btn.onclick function () { // 触发 store action var store document.querySelector(#swagger-ui) .swaggerUI.getSystem().getStore(); store.dispatch({ type: THEME_TOGGLE }); }; return btn; } } }; };该插件实现了内置的状态管理和主题切换按钮。你可以根据实际项目需要扩展到三套甚至更多套主题。5. 实战打造企业品牌风格 Swagger UI 页面下面给出一个完整的企业风格改造示例包含品牌配色、自定义字体、圆角卡片和优化后的表格样式。!DOCTYPE html html langzh-CN head meta charsetUTF-8 title企业 API 文档中心/title link relstylesheet hrefhttps://unpkg.com/swagger-ui-dist5/swagger-ui.css style /* CSS 变量覆盖 */ :root { --swagger-ui-color-primary: #2563eb; --swagger-ui-color-success: #10b981; --swagger-ui-color-warning: #f59e0b; --swagger-ui-color-error: #ef4444; --swagger-ui-font-family: PingFang SC, Microsoft YaHei, Helvetica Neue, sans-serif; --swagger-ui-font-size: 15px; } /* 顶栏品牌化 */ .swagger-ui .topbar { background: linear-gradient(135deg, #1e3a5f 0%, #2563eb 100%); padding: 14px 0; box-shadow: 0 2px 12px rgba(37, 99, 235, 0.25); } .swagger-ui .topbar .wrapper { max-width: 1280px; margin: 0 auto; padding: 0 24px; } .swagger-ui .topbar a { color: #ffffff !important; } .swagger-ui .topbar .download-url-wrapper .select-label { display: flex; align-items: center; color: #e2e8f0; } /* 信息区卡片化 */ .swagger-ui .info { margin: 30px 0; padding: 32px; background: #ffffff; border-radius: 12px; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08), 0 4px 16px rgba(0, 0, 0, 0.04); } .swagger-ui .info .title { font-size: 26px; color: #1e293b; } .swagger-ui .info .description p { color: #475569; line-height: 1.8; } /* 接口分组标签美化 */ .swagger-ui .opblock-tag { font-size: 18px; font-weight: 600; color: #1e293b; border-bottom: 2px solid #e2e8f0; padding-bottom: 10px; margin-bottom: 20px; } .swagger-ui .opblock-tag:hover { border-bottom-color: var(--swagger-ui-color-primary); } .swagger-ui .opblock-tag small { color: #94a3b8; font-weight: 400; } /* 接口卡片样式 */ .swagger-ui .opblock { border-radius: 8px; margin-bottom: 16px; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06); border: 1px solid #e2e8f0; } .swagger-ui .opblock .opblock-summary { border-radius: 8px; } .swagger-ui .opblock .opblock-summary-description { color: #64748b; font-size: 14px; } /* 响应区域美化 */ .swagger-ui .responses-inner { padding: 20px; background-color: #f8fafc; border-radius: 0 0 8px 8px; } .swagger-ui table thead tr td, .swagger-ui table thead tr th { background-color: #f1f5f9; color: #1e293b; font-weight: 600; } .swagger-ui table tbody tr td { border-color: #e2e8f0; } /* 代码示例区 */ .swagger-ui .highlight-code { border-radius: 6px; } .swagger-ui .microlight { font-family: Fira Code, Consolas, monospace !important; font-size: 13px !important; line-height: 1.6 !important; } /* 响应式适配 */ media (max-width: 768px) { .swagger-ui .wrapper { padding: 0 12px; } .swagger-ui .info { padding: 20px; margin: 16px 0; } .swagger-ui .info .title { font-size: 20px; } } /* 滚动条美化 */ .swagger-ui ::-webkit-scrollbar { width: 6px; height: 6px; } .swagger-ui ::-webkit-scrollbar-thumb { background-color: #cbd5e1; border-radius: 3px; } .swagger-ui ::-webkit-scrollbar-thumb:hover { background-color: #94a3b8; } /* 底部信息 */ .swagger-ui .info .info__footer { margin-top: 20px; padding-top: 16px; border-top: 1px solid #e2e8f0; color: #94a3b8; font-size: 13px; } lt;/stylegt; /head body div idswagger-ui/div lt;script srchttps://unpkg.com/swagger-ui-dist5/swagger-ui-bundle.jsgt;lt;/scriptgt; lt;script srchttps://unpkg.com/swagger-ui-dist5/swagger-ui-standalone-preset.jsgt;lt;/scriptgt; lt;scriptgt; window.onload function () { SwaggerUIBundle({ url: https://petstore.swagger.io/v2/swagger.json, dom_id: #swagger-ui, deepLinking: true, displayRequestDuration: true, filter: true, defaultModelsExpandDepth: 1, defaultModelExpandDepth: 1, docExpansion: list, syntaxHighlight: { theme: monokai }, presets: [ SwaggerUIBundle.presets.apis, SwaggerUIBundle.SwaggerUIStandalonePreset ], layout: StandaloneLayout }); }; lt;/scriptgt; /body /html上述完整示例展示了如何通过一份集中的 CSS 文件将 Swagger UI 从默认风格改造为具有企业品牌辨识度的界面。所有修改集中在style标签中便于维护和版本管理。6. 在 Spring Boot 项目中定制 Swagger UI 主题在 Java 后端项目中如果使用 SpringDoc OpenAPI 或 Springfox 集成 Swagger UI同样可以自定义主题。以下以 SpringDoc 为例说明。6.1 通过静态资源覆盖默认样式在src/main/resources/static/目录下创建swagger-custom.css文件/* src/main/resources/static/swagger-custom.css */ :root { --swagger-ui-color-primary: #059669; --swagger-ui-color-success: #10b981; --swagger-ui-color-error: #dc2626; } .swagger-ui .topbar { background-color: #064e3b; } .swagger-ui .topbar .download-url-wrapper .select-label span { color: #d1fae5; } .swagger-ui .info .title { color: #064e3b; font-weight: 700; } .swagger-ui .opblock.opblock-get .opblock-summary-method { background: #059669; }6.2 在 application.yml 中配置springdoc: swagger-ui: path: /swagger-ui.html enabled: true config-url: /v3/api-docs/swagger-config urls: - name: 用户服务 url: /v3/api-docs/user-service - name: 订单服务 url: /v3/api-docs/order-service # 如果需要在初始化时注入自定义 CSS 字符串 swagger-ui-config: customCss: .swagger-ui .topbar { background-color: #064e3b; } customSiteTitle: 企业微服务 API 文档 deepLinking: true6.3 通过配置类注入自定义资源import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; Configuration public class SwaggerUiConfig implements WebMvcConfigurer { Override public void addResourceHandlers(ResourceHandlerRegistry registry) { // 将自定义 CSS 映射到 Swagger UI 可访问路径 registry.addResourceHandler(/swagger-ui/custom-css/**) .addResourceLocations(classpath:/static/swagger-custom/); } }结合 SpringDoc 的自动配置上述方式可以在不修改任何 Swagger UI 原始文件的情况下实现主题样式的统一管理和版本迭代。7. 常见问题与注意事项7.1 样式不生效检查 CSS 优先级Swagger UI 默认样式使用了较高的选择器权重。如果你发现自定义样式没有生效可以通过以下方式提高优先级/* 使用多重选择器提高权重 */ .swagger-ui .wrapper .topbar .download-url-wrapper { background-color: #your-color !important; } /* 或者使用更具体的路径选择器 */ body .swagger-ui .opblock.opblock-post .opblock-summary { border-left-color: #your-color; }注意!important是最后手段优先尝试通过增加选择器层级解决问题。7.2 Swagger UI 版本差异不同版本的 Swagger UI 内部 DOM 结构可能不同Swagger UI 3.x顶部使用.topbar类信息区使用.information-container。Swagger UI 4.x / 5.x结构大体一致但部分类名有所调整建议使用浏览器开发者工具确认目标元素的准确选择器。7.3 避免影响功能在修改样式时不要隐藏或移除以下关键元素否则可能导致 Swagger UI 核心功能失效.download-url-wrapper接口地址输入区域。.try-out__btnTry it out 按钮涉及接口调试入口。.opblock-summary-control接口展开/折叠触发器。7.4 使用浏览器 DevTools 辅助定位在定制过程中强烈建议打开浏览器的开发者工具F12通过 Elements 面板查看 Swagger UI 的实时 DOM 结构再通过 Styles 面板实时调试 CSS 效果确认无误后再将样式写入最终的 CSS 文件或customCss配置中。8. 总结本文从四个层次介绍了 Swagger UI 主题样式的修改方案快速注入通过customCss属性直接写入少量覆盖样式。CSS 变量利用 Swagger UI 3.x 暴露的 CSS 自定义属性实现系统化配色。插件定制通过编写 Swagger UI 插件深度接管组件渲染。企业实战结合 Spring Boot 项目给出完整的工程化集成方案。推荐在日常开发中优先使用CSS 变量 customCss的组合方案既能覆盖 90% 以上的定制需求又不会引入过多维护成本。当需要替换 Logo、添加导航菜单或实现多套主题时再考虑插件方案。希望本文提供的代码示例能帮助你快速完成 Swagger UI 的品牌化改造。
返回列表