资讯详情

Gradio 主题引擎完整指南:内置主题、CSS 变量体系与自定义主题发布

📅 2026/9/9 21:06:53 | 华诺云谱 👁 阅读
Gradio 主题引擎完整指南:内置主题、CSS 变量体系与自定义主题发布
Gradio 主题引擎完整指南内置主题、CSS 变量体系与自定义主题发布【免费下载链接】gradioBuild and share delightful machine learning apps, all in Python. Star to support our work!项目地址: https://gitcode.com/GitHub_Trending/gr/gradio本文是 Gradio 官方主题Theming指南的深度讲解版系统覆盖 Gradio 内建的主题引擎如何为Blocks/Interface应用gr.themes.*内置主题如何借助 Theme Builder 可视化调参如何通过构造函数 8 个核心参数3 个色相、3 个尺寸、2 个字体与.set()方法直接操控数百个 CSS 变量并最终从零构建、打包并上传属于自己的主题到 Hugging Face Hub。阅读完你不仅能给 App 一键换肤还能写出可在版本间共享、支持语义化版本锁定的可复用主题。本文内容以官方指南 guides/11_other-tutorials/theming-guide.md 为主线并结合仓库中 gradio/themes/ 目录下的真实源码base.py、monochrome.py、soft.py、utils/colors.py、utils/sizes.py、utils/fonts.py等进行印证便于读者边读边对照源码。主题入门如何应用一个主题Gradio 内置了一套主题引擎让你可以完全自定义 App 的外观。你可以选用现成主题也可以创建自己的主题。使用方法非常简单把theme参数传给Blocks或Interface的launch()方法也可以在gr.Blocks(theme...)构造时直接传入两种写法规格一致with gr.Blocks() as demo: ... # your code here demo.launch(themegr.themes.Soft())从源码实现看Blocks.launch()最终会经过 gradio/utils.py 中的get_theme()对主题对象做归一化处理当theme为None时回退到默认主题DefaultTheme当theme为字符串时先与BUILT_IN_THEMES见 gradio/utils.py中的内置主题名匹配若匹配不上则会尝试走Theme.from_hub()从 Hugging Face Hub 加载远端主题。这也意味着“直接传主题名字符串”与“传主题实例”在底层是等价的。Gradio 附带了一系列预置主题可通过gr.themes.*直接加载主题类名称与外观特征gr.themes.Base()base主题主色为蓝色除此之外几乎不带额外样式非常适合作为创建自定义主题的“地基”gr.themes.Default()default主题即 Gradio 5 的默认主题主色为明快的橙色colors.orange辅助色为灰色gr.themes.Origin()origin主题最接近 Gradio 4 的观感颜色尤其是亮色模式比 Gradio 5 默认主题更柔和克制gr.themes.Citrus()citrus主题黄色主色突出处于聚焦状态的表单元素按钮点击时带有有趣的 3D 效果gr.themes.Monochrome()monochrome主题黑色主色、白色辅助色并使用衬线字体呈现黑白报纸的观感gr.themes.Soft()soft主题紫色系主色、白色辅助色增大了按钮与表单元素的圆角半径并强化了标签的高亮gr.themes.Glass()glass主题蓝色主色、半透明灰辅助色利用纵向渐变营造玻璃质感gr.themes.Ocean()ocean主题蓝绿色主色、灰色辅助色大量使用横向渐变尤其是按钮和部分表单元素此外在当前仓库的 gradio/themes 目录中还可以看到cyberpunk.py、ember.py、neon.py、mario.py等更多主题模块它们都已在 gradio/themes/init.py 中导出其中mario同样被注册进了BUILT_IN_THEMES字典可直接通过字符串名如mario加载。值得强调的是每一个预置主题都只是数百个 CSS 变量的取值集合。所有预置主题的类定义都在 gradio/themes 目录下例如 monochrome.py 中Monochrome 通过重写构造函数默认值 调用super().set(...)一次性覆盖几十个变量而成型。你可以以预置主题为起点改造也可以完全从零打造主题下面逐一展开。使用 Theme Builder 可视化构建主题构建主题最快的方式是使用官方 Theme Builder可视化主题编辑器。在本机启动只需运行import gradio as gr gr.themes.builder()从源码看gradio/themes/init.py 中的builder()本质是启动位于 gradio/themes/builder_app.py 的 Gradio Demo并强制套用Base()主题与一段控制面板布局用的 CSS。因此它虽然也可以在 Spaces 上运行但在本地通过gr.themes.builder()启动会快得多。在 Theme Builder 中编辑参数时右侧画布会实时预览更新效果完成后可以直接下载“生成该主题的 Python 代码”稍作整理即可放进任何 Gradio App 使用。接下来的章节我们介绍纯代码方式构建主题。通过构造函数扩展主题8 个核心变量虽然每个主题都有数百个 CSS 变量但其中绝大多数变量的取值都来自 8 个“核心变量”。这 8 个核心变量恰好是每个预置主题构造函数的参数修改它们就能快速改变整个 App 的观感。以 gradio/themes/base.py 中Base.__init__的签名为准它们分别是3 个颜色参数primary_hue/secondary_hue/neutral_hue3 个尺寸参数spacing_size/radius_size/text_size以及 2 个字体参数font/font_mono。核心颜色前 3 个参数前 3 个构造函数参数设置主题的颜色类型为gradio.themes.Color对象。从 gradio/themes/utils/colors.py 的源码可见每个Color对象内部保存了单一色相的 11 个亮度值c50、c100、c200……c900、c950并通过Color.all注册表管理。主题中其余 CSS 变量都从这 3 个颜色派生而来primary_hue主题中最抓眼球的强调色。默认主题中设为gradio.themes.colors.orange。secondary_hue用于次要元素的颜色。默认主题中设为gradio.themes.colors.blue。neutral_hue用于文字等中性元素的颜色。默认主题中设为gradio.themes.colors.gray。修改时既可以使用字符串快捷写法with gr.Blocks() as demo: ... # your code here demo.launch(themegr.themes.Default(primary_huered, secondary_huepink))也可以直接使用Color对象with gr.Blocks() as demo: ... # your code here demo.launch(themegr.themes.Default(primary_huegr.themes.colors.red, secondary_huegr.themes.colors.pink))字符串快捷写法之所以能生效是因为Base.__init__中的expand_shortcut()见 gradio/themes/base.py会把字符串名与Color.all中的实例逐一匹配并替换为对应的Color对象如果名字不存在则抛出ValueError。官方预置的颜色名包括slate、gray、zinc、neutral、stone、red、orange、amber、yellow、lime、green、emerald、teal、cyan、sky、blue、indigo、violet、purple、fuchsia、pink、rose。这些色板全部以 11 级亮度值定义在 gradio/themes/utils/colors.py 中。例如Monochrome主题的三个色相参数默认均为colors.neutral从而得到纯粹的黑白灰体系见 monochrome.py。你也可以仿照Color的构造方式创建自定义颜色对象传入内部亮度级别需要c50到c950完整提供。核心尺寸中间 3 个参数接下来的 3 个构造函数参数设置主题的尺寸类型为gradio.themes.Size对象。从 gradio/themes/utils/sizes.py 可见Size对象内部保存了从xxs到xxl共 7 档像素值其余 CSS 变量都由这 3 个尺寸派生spacing_size设置元素内部 padding 与元素之间的间距。默认主题为gradio.themes.sizes.spacing_md。radius_size设置元素圆角的圆润程度。默认主题为gradio.themes.sizes.radius_md。text_size设置文字字号。默认主题为gradio.themes.sizes.text_md。同样支持字符串快捷写法with gr.Blocks() as demo: ... # your code here demo.launch(themegr.themes.Default(spacing_sizesm, radius_sizenone))以及Size对象写法with gr.Blocks() as demo: ... # your code here demo.launch(themegr.themes.Default(spacing_sizegr.themes.sizes.spacing_sm, radius_sizegr.themes.sizes.radius_none))预置的尺寸对象包括圆角radius_none、radius_sm、radius_md、radius_lg间距spacing_sm、spacing_md、spacing_lg字号text_sm、text_md、text_lg这些对象的具体取值定义在 sizes.py 中。例如radius_md的 7 档为1px / 2px / 4px / 6px / 8px / 12px / 22pxradius_none全部为0pxspacing_sm为1px / 1px / 2px / 4px / 6px / 9px / 12pxspacing_md为1px / 2px / 4px / 6px / 8px / 10px / 16pxtext_sm为8px / 9px / 11px / 13px / 16px / 20px / 24px。也就是说当你选择radius_sizelg时实际是把整套radius_lg的 7 档像素值应用到派生变量上。同样地你也可以自定义Size对象传入。核心字体最后 2 个参数最后 2 个构造函数参数设置主题字体。每个参数都可以传入一个字体列表浏览器会按顺序回退。若传入字符串会被当作系统字体使用若传入gradio.themes.GoogleFont则字体会从 Google Fonts 加载。font设置主题主字体。默认主题为gradio.themes.GoogleFont(IBM Plex Sans)。font_mono设置等宽字体用于代码。默认主题为gradio.themes.GoogleFont(IBM Plex Mono)。例如混合 Google 字体与系统字体作为回退链with gr.Blocks() as demo: ... # your code here demo.launch(themegr.themes.Default(font[gr.themes.GoogleFont(Inconsolata), Arial, sans-serif]))补充一个从 gradio/themes/utils/fonts.py 得到的实现细节GoogleFont在内部会先检查gradio/templates/frontend/static/fonts中是否已随包捆绑了同名字体.woff2若有则直接走本地font-faceLocalFont而不再请求远程否则才回退到 Google Fonts 的css2样式表链接见 fonts.py。Base.__init__里会根据font与font_mono列表生成_font_css/_stylesheets最终注入到生成的主题 CSS 中base.py。自定义 CSS当主题变量无法满足某些定制需求时可以通过theme.custom_css属性追加自定义 CSS。该 CSS 会捆绑进主题因此在把主题上传/下载到 Hub 时会一并被携带theme gr.themes.Default() theme.custom_css button.primary { background: linear-gradient(135deg, var(--primary-400), var(--primary-600)); transition: transform 0.15s ease, box-shadow 0.15s ease; } button.primary:hover { transform: translateY(-2px); box-shadow: 0 4px 12px color-mix(in srgb, var(--primary-500) 40%, transparent); } with gr.Blocks(themetheme) as demo: gr.Textbox(labelInput) gr.Button(Submit, variantprimary) demo.launch()从源码看custom_css会在_get_theme_css()生成主题时被追加在所有由 CSS 变量生成的样式之后base.py保证它可以安全地引用--primary-*这类变量。通过.set()方法细化覆盖 CSS 变量除了构造函数之外你还可以在主题对象加载完成后随时用主题的.set()方法修改 CSS 变量的值。例如theme gr.themes.Default(primary_hueblue).set( loader_color#FF0000, slider_color#FF0000, ) with gr.Blocks() as demo: ... # your code here demo.launch(themetheme)上例中尽管整体的primary_color使用蓝色色板我们仍单独把loader_color请求进行中的加载动画颜色和slider_color滑杆颜色设成了#FF0000。主题里定义过的任何 CSS 变量都可以用这种方式修改。.set()的完整签名定义在 base.py按用途分组为Body 属性整体背景、文字颜色/字号、元素颜色背景、边框、强调色、文字链接、正文、代码块、阴影、布局原子block、block_label、panel、container等、组件原子checkbox、input、table、loader、slider、error以及按钮button_primary/button_secondary/button_cancel各自的背景、边框、文字、阴影及其 hover/active/dark 变体。IDE 的类型提示会帮助你浏览这些变量名。由于变量数量庞大下面介绍它们的命名与组织规律。CSS 变量的命名约定CSS 变量名可能很长比如button_primary_background_fill_hover_dark。但所有变量都遵循统一的下划线命名约定按序由以下 5 部分拼成理解后可轻松定位目标变量目标元素例如button、slider、block目标元素的类型或子元素例如button_primary、block_label具体属性例如button_primary_background_fill、block_label_border_width相关状态如有例如button_primary_background_fill_hover若该值在深色模式下不同追加后缀_dark。例如input_border_color_focus_dark。当然很多变量比这短得多例如table_border_color、input_shadow就只含“元素 属性”两段。CSS 变量的组织方式虽然存在数百个 CSS 变量但它们不必一一显式取值。变量之间通过“引用核心变量”和“互相引用”来取值这正是“改少数几个变量即可改全身同时又能对单个元素做精细控制”的机制根源。真实的 CSS 生成逻辑在ThemeClass._get_theme_css()base.py中主题对象的所有公开属性下划线开头的内部属性除外会逐个被渲染为:root { --var: value; }块带_dark后缀的属性会被拆进.dark作用域且未显式定义 dark 值的光照变量会自动沿用亮色值base.py。引用核心变量要引用某个核心构造函数变量需要在变量名前加星号*。引用核心颜色用*primary_/*secondary_/*neutral_前缀 亮度值theme gr.themes.Default(primary_hueblue).set( button_primary_background_fill*primary_200, button_primary_background_fill_hover*primary_300, )上例把主按钮背景设置成了蓝色主色色板的 200/300 亮度值对应 colors.py 中的c200/c300。引用核心尺寸同理用*spacing_/*radius_/*text_前缀 档位theme gr.themes.Default(radius_sizemd).set( button_primary_border_radius*radius_xl, )这里*radius_xl会解析为中号圆角体系radius_md中的xl档像素值12px。引用其他变量CSS 变量也可以互相引用。例如下面这段代码需要重复写三次颜色比较繁琐theme gr.themes.Default().set( button_primary_background_fill#FF0000, button_primary_background_fill_hover#FF0000, button_primary_border#FF0000, )更优雅的做法是让后两个变量引用第一个变量同样使用*前缀theme gr.themes.Default().set( button_primary_background_fill#FF0000, button_primary_background_fill_hover*button_primary_background_fill, button_primary_border*button_primary_background_fill, )之后一旦修改button_primary_background_fillbutton_primary_background_fill_hover与button_primary_border会自动跟随变化。如果你打算把主题共享出去这种写法会让他人“一处修改、处处生效”非常有用。解析引用时的底层行为是_get_theme_css()通过正则把*xxx编译成var(--xxx-xxx)base.py而_get_computed_value()base.py会递归展开引用以算出最终值并在出现循环引用深度超过 100时给出告警。需要特别留意深色模式变量的自动引用规则深色变量总是自动引用同名变量的_dark版本。例如theme gr.themes.Default().set( button_primary_background_fill#FF0000, button_primary_background_fill_dark#AAAAAA, button_primary_border*button_primary_background_fill, button_primary_border_dark*button_primary_background_fill_dark, )这里的button_primary_border_dark会从button_primary_background_fill_dark#AAAAAA取值而不是亮色版的#FF0000。与引用规则配套的还有几条硬性校验非 dark 变量不能被设为None被引用处不允许写_dark后缀dark 引用是自动的若 dark 与 light 取值相同应把 dark 版本置为None而非引用自身见 base.py 的ValueError分支。CSS 变量完整参考主题所有可用的 CSS 变量完整列表见仓库内 guides/11_other-tutorials/css-variables-reference.md。需要快速上手时也可以打开浏览器的开发者工具Inspector选中界面上的某个元素在样式面板中直接查看它当前命中了哪些--*变量。从零构建一个完整主题Seafoam 实战假设你要完全从零创建一个主题。下面一步步来仓库中每个预置主题的源码都在 gradio/themes 目录例如黑白报纸风格的 monochrome.py 就是很好的参考范本。我们的新主题类将继承自gradio.themes.Base—— 一个已设置大量便利默认值的基础主题。我们创建名为Seafoam的主题并写一个使用它的小应用。完整可运行代码位于 demo/theme_new_step_1/run.py核心骨架如下import gradio as gr from gradio.themes.base import Base import time class Seafoam(Base): pass seafoam Seafoam() with gr.Blocks() as demo: textbox gr.Textbox(labelName) slider gr.Slider(labelCount, minimum0, maximum100, step1) with gr.Row(): button gr.Button(Submit, variantprimary) clear gr.Button(Clear) output gr.Textbox(labelOutput) def repeat(name, count): time.sleep(3) return name * count button.click(repeat, [textbox, slider], output) if __name__ __main__: demo.launch(themeseafoam)Base主题非常素净主色是gr.themes.Blue—— 你会看到主按钮与加载动画都因此呈现蓝色。下面覆盖构造函数的默认核心参数见 demo/theme_new_step_2/run.py把主色换成gr.themes.Emerald辅助色与中性色设为gr.themes.Blue字号放大到text_lg并从 Google Fonts 加载Quicksand作为默认字体from __future__ import annotations from typing import Iterable import gradio as gr from gradio.themes.base import Base from gradio.themes.utils import colors, fonts, sizes class Seafoam(Base): def __init__( self, *, primary_hue: colors.Color | str colors.emerald, secondary_hue: colors.Color | str colors.blue, neutral_hue: colors.Color | str colors.gray, spacing_size: sizes.Size | str sizes.spacing_md, radius_size: sizes.Size | str sizes.radius_md, text_size: sizes.Size | str sizes.text_lg, font: fonts.Font | str | Iterable[fonts.Font | str] ( fonts.GoogleFont(Quicksand), ui-sans-serif, sans-serif, ), font_mono: fonts.Font | str | Iterable[fonts.Font | str] ( fonts.GoogleFont(IBM Plex Mono), ui-monospace, monospace, ), ): super().__init__( primary_hueprimary_hue, secondary_huesecondary_hue, neutral_hueneutral_hue, spacing_sizespacing_size, radius_sizeradius_size, text_sizetext_size, fontfont, font_monofont_mono, )此时主按钮与加载动画已变成绿色——因为这些 CSS 变量都与primary_hue绑定。接着用.set()更直接地覆盖变量可以写任意 CSS 逻辑并用*前缀引用核心构造函数变量完整版见 demo/theme_new_step_3/run.pysuper().set( body_background_fillrepeating-linear-gradient(45deg, *primary_200, *primary_200 10px, *primary_50 10px, *primary_50 20px), body_background_fill_darkrepeating-linear-gradient(45deg, *primary_800, *primary_800 10px, *primary_900 10px, *primary_900 20px), button_primary_background_filllinear-gradient(90deg, *primary_300, *secondary_400), button_primary_background_fill_hoverlinear-gradient(90deg, *primary_200, *secondary_300), button_primary_text_colorwhite, button_primary_background_fill_darklinear-gradient(90deg, *primary_600, *secondary_800), slider_color*secondary_300, slider_color_dark*secondary_600, block_title_text_weight600, block_border_width3px, block_shadow*shadow_drop_lg, button_primary_shadow*shadow_drop_lg, button_large_padding32px, )仅仅改动少量变量主题外观就焕然一新。可以多对照 gradio/themes 下其它预置主题的实现看它们如何基于Base二次加工也可以借助浏览器 Inspector 选中界面元素在样式面板观察具体生效的 CSS 变量。分享主题上传到 Hugging Face Hub主题创建完成后可以上传到 Hugging Face Hub让别人浏览、使用并在此基础上继续二次开发。上传主题的两种方式以下均以刚才创建的seafoam主题为例。方式一通过主题实例上传。每个主题实例都有push_to_hub方法seafoam.push_to_hub(repo_nameseafoam, version0.0.1, tokentoken)方式二通过命令行上传。先把主题保存到磁盘seafoam.dump(filenameseafoam.json)再调用upload_theme命令upload_theme\ seafoam.json\ seafoam\ --version 0.0.1\ --token token命令行入口的实现见 gradio/themes/upload_theme.py其底层同样读取 JSON 后委托给theme.push_to_hub()。序列化环节由ThemeClass.to_dict()/dump()完成base.py主题变量会被写成{theme: {...}, gradio_version: ...}的 JSON 结构字体对象则通过FontEncoder/as_font编解码见 utils/fonts.py保证GoogleFont等对象往返无损。上传主题需要一个 Hugging Face 账号并把 Access Token 作为token参数传入。不过如果你通过随gradio一起安装的 Hugging Face 命令行完成过登录则可以省略token参数——push_to_hub内部会调用whoami()识别当前用户base.py。version参数用于指定合法的语义化版本号semantic version。这样使用者可以精确指定要使用哪个版本的主题你也可以在不影响既有 App 外观的前提下发布更新。该参数可选省略时若目标 Space 已存在则自动生成下一个 patch 版本否则默认为0.0.1见 base.py。上传时会自动创建/更新一个 Space其中包含三样资产themes/theme_schema{version}.json主题定义文件、README.md与一个用于预览的app.pybase.py。主题预览与主题画廊调用push_to_hub或upload_theme后主题资源会被存放到一个 Hugging Face Space 中作为该主题的在线预览页。Gradio 官网的 Theme Gallery 汇总了官方与社区的全部主题支持按官方/社区过滤并可实时预览每个主题的颜色、字体与在线 Demo。社区主题收录于 Hugging Face 上的gradio/theme-gallery数据集要把自己的主题加入画廊需要向该数据集的manifest.json提交包含主题元数据的 Pull Request。下载使用 Hub 上的主题要使用 Hub 上的主题用ThemeClass的from_hub方法获取后传入 Appmy_theme gr.Theme.from_hub(gradio/seafoam) with gr.Blocks() as demo: ... # your code here demo.launch(thememy_theme)也可以直接把主题字符串传给Blocks或Interface的launch()例如demo.launch(themegradio/seafoam)。这条路径对应前文提到的get_theme()字符串先匹配内置主题名匹配不上再走Theme.from_hub()下载utils.py。from_hub支持形如author/theme-namesemver-expression的仓库名从 Space 中查找匹配版本的theme_schema...json并下载base.py。你还可以用语义化版本表达式把 App 锁定到某个上游主题版本区间。例如下面写法保证加载的seafoam主题版本介于0.0.1与0.1.0之间with gr.Blocks() as demo: ... # your code here demo.launch(themegradio/seafoam0.0.1,0.1.0)版本兼容性提示当你用theme.dump()保存或用theme.push_to_hub()上传主题时会自动写入当前的 Gradio 版本号。当别人用不同 major/minor 版本的 Gradio 加载该主题时会看到一条警告UserWarning: This theme was created for Gradio 5.0.0, but you are using Gradio 5.1.0. Some styles may not work as expected.版本差异如5.0.0与5.0.1不会触发警告只有 major/minor 版本不一致才提示。该逻辑实现在from_dict()加载入口base.py它用加载时的gradio.__version__与主题 JSON 中记录的版本做比较——因为主题依赖的 CSS 变量集合可能随 Gradio 主版本演进而增减提前警告能避免不明所以的样式错乱。此外为了保证旧主题能被当前版本正常加载from_dict还会把Base主题中新增的变量自动回填进旧主题base.py从而实现向后兼容。掌握了这些机制你就可以放心地创建并发布自己的主题了——从 8 个核心参数快速配色到.set()精确控制每个组件的细节变量再到打上语义化版本共享给整个社区。建议在动手前先跑一遍本地 Theme Builder再对着 css-variables-reference.md 与预置主题源码逐项调整体验“改一个变量、全局联动”的 Gradio 主题设计工作流。【免费下载链接】gradioBuild and share delightful machine learning apps, all in Python. Star to support our work!项目地址: https://gitcode.com/GitHub_Trending/gr/gradio创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。