自定义 JS 和 CSS

本指南介绍了如何更灵活地设置块样式,以及如何将 Javascript 代码添加到事件侦听器。

This guide covers how to style Blocks with more flexibility, as well as adding Javascript code to event listeners.

警告不能保证在自定义 JS 和 CSS 中使用查询选择器可以跨 Gradio 版本工作,因为 Gradio HTML DOM 可能会更改。 我们建议谨慎使用查询选择器。

Warning: The use of query selectors in custom JS and CSS is not guaranteed to work across Gradio versions as the Gradio HTML DOM may change. We recommend using query selectors sparingly.

自定义 CSS

Gradio 主题是自定义应用程序外观的最简单方法。 你可以从各种主题中进行选择,也可以创建自己的主题。 为此,将 theme= kwarg 传递给 Blocks 构造函数。 例如:

Gradio themes are the easiest way to customize the look and feel of your app. You can choose from a variety of themes, or create your own. To do so, pass the theme= kwarg to the Blocks constructor. For example:

with gr.Blocks(theme=gr.themes.Glass()):
    ...

Gradio 带有一组预构建的主题,你可以从 gr.themes.* 加载这些主题。 你可以扩展这些主题或从头开始创建你自己的主题 - 有关更多详细信息,请参阅主题指南

Gradio comes with a set of prebuilt themes which you can load from gr.themes.*. You can extend these themes or create your own themes from scratch - see the Theming guide for more details.

对于额外的样式功能,你可以使用 css= kwarg 将任何 CSS 传递到你的应用程序。

For additional styling ability, you can pass any CSS to your app using the css= kwarg.

Gradio 应用程序的基类是 gradio-container ,下面是一个更改 Gradio 应用程序背景颜色的示例:

The base class for the Gradio app is gradio-container, so here's an example that changes the background color of the Gradio app:

with gr.Blocks(css=".gradio-container {background-color: red}") as demo:
    ...

如果你想在 css 中引用外部文件,请在文件路径(可以是相对路径或绝对路径)前加上 "file=" ,例如:

If you'd like to reference external files in your css, preface the file path (which can be a relative or absolute path) with "file=", for example:

with gr.Blocks(css=".gradio-container {background: url('file=clouds.jpg')}") as demo:
    ...

你还可以将 CSS 文件的文件路径传递给 css 参数。

You can also pass the filepath to a CSS file to the css argument.

elem_idelem_classes 参数

你可以使用 elem_id 向任何组件添加 HTML 元素 id ,使用 elem_classes 添加类或类列表。 这将允许你使用 CSS 更轻松地选择元素。 这种方法也更有可能在 Gradio 版本中保持稳定,因为内置类名或 ID 可能会更改(但是,如上面警告中所述,如果你使用自定义 CSS,我们不能保证 Gradio 版本之间完全兼容,因为 DOM 元素可能自己改变)。

You can elem_id to add an HTML element id to any component, and elem_classes to add a class or list of classes. This will allow you to select elements more easily with CSS. This approach is also more likely to be stable across Gradio versions as built-in class names or ids may change (however, as mentioned in the warning above, we cannot guarantee complete compatibility between Gradio versions if you use custom CSS as the DOM elements may themselves change).

css = """
#warning {background-color: #FFCCCB} 
.feedback textarea {font-size: 24px !important}
"""

with gr.Blocks(css=css) as demo:
    box1 = gr.Textbox(value="Good Job", elem_classes="feedback")
    box2 = gr.Textbox(value="Failure", elem_id="warning", elem_classes="feedback")

CSS #warning 规则集将只针对第二个文本框,而 .feedback 规则集将同时针对这两个文本框。 请注意,在定位类时,你可能需要放置 !important 选择器来覆盖默认的渐变样式。

The CSS #warning ruleset will only target the second Textbox, while the .feedback ruleset will target both. Note that when targeting classes, you might need to put the !important selector to override the default Gradio styles.

自定义 JS

事件侦听器有一个 _js 参数,可以将 Javascript 函数作为字符串并将其视为 Python 事件侦听器函数。 你可以同时传递 Javascript 函数和 Python 函数(在这种情况下,首先运行 Javascript 函数)或仅传递 Javascript(并将 Python fn 设置为 None )。 看看下面的代码:

Event listeners have a _js argument that can take a Javascript function as a string and treat it just like a Python event listener function. You can pass both a Javascript function and a Python function (in which case the Javascript function is run first) or only Javascript (and set the Python fn to None). Take a look at the code below:

import gradio as gr

blocks = gr.Blocks()

with blocks as demo:
    subject = gr.Textbox(placeholder="subject")
    verb = gr.Radio(["ate", "loved", "hated"])
    object = gr.Textbox(placeholder="object")

    with gr.Row():
        btn = gr.Button("Create sentence.")
        reverse_btn = gr.Button("Reverse sentence.")
        foo_bar_btn = gr.Button("Append foo")
        reverse_then_to_the_server_btn = gr.Button(
            "Reverse sentence and send to server."
        )

    def sentence_maker(w1, w2, w3):
        return f"{w1} {w2} {w3}"

    output1 = gr.Textbox(label="output 1")
    output2 = gr.Textbox(label="verb")
    output3 = gr.Textbox(label="verb reversed")
    output4 = gr.Textbox(label="front end process and then send to backend")

    btn.click(sentence_maker, [subject, verb, object], output1)
    reverse_btn.click(
        None, [subject, verb, object], output2, _js="(s, v, o) => o + ' ' + v + ' ' + s"
    )
    verb.change(lambda x: x, verb, output3, _js="(x) => [...x].reverse().join('')")
    foo_bar_btn.click(None, [], subject, _js="(x) => x + ' foo'")

    reverse_then_to_the_server_btn.click(
        sentence_maker,
        [subject, verb, object],
        output4,
        _js="(s, v, o) => [s, v, o].map(x => [...x].reverse().join(''))",
    )

demo.launch()