【问题标题】:In Vaadin how can I set a style within a Label and NOT have it affect the whole page在 Vaadin 中,如何在标签中设置样式而不影响整个页面
【发布时间】:2017-11-20 09:24:52
【问题描述】:

例如,我在Label 中设置了以下 html 代码:

Label label = new Label();
label.setContentMode(ContentMode.HTML);
label.setValue("<style> * { font-size: 12px; font-family: Arial; } </style> hello world");

上述代码的问题在于它将整个页面设置为 Arial 而不仅仅是 Label。如果我使用RichTextArea,那么它只会将样式设置为该组件,但无论出于何种原因,Label 中定义的任何 CSS 样式都会应用于整个页面...

仅供参考 - 如果您将 RichTextArea 设置为只读,您会遇到完全相同的问题...

【问题讨论】:

  • 您必须使用正确的 css 选择器。在你的 css 中使用 * 将该样式应用于所有 html 标签 -> 整个页面。无论如何,在 html 模式下使用标签然后在其中使用 html 和 css 是一个奇怪的想法。有不同的方法可以为特定标签设置内容和 css
  • 这是一个用户生成的报告。基本上,我不想将它放到 RichTextArea (可以做到这一点)上,而是想通过管道让它看起来好像是页面的一部分。这一切都是使用模板自包含的,因为 html sn-p 以后可以转换为 PDF 文件等。
  • 如果您使用这样的内联样式,它是否有效:&lt;span style="font-size: 12px; font-family: Arial;"&gt;
  • 是的,style 会起作用。我希望 OP 知道这是一个黑客攻击,现在他们有责任在该标签中防止 XSS。
  • 这就是为什么我想让它像 RichTextArea 组件一样完全独立。这就是为什么我什至用 setReadOnly(true) 尝试了 RichTextArea 但这导致了基本上相同的时间。如果它不是只读的,那么组件中似乎包含任何 CSS

标签: java vaadin vaadin8


【解决方案1】:

而不是添加样式内联。使用挂在 Vaadin 组件上的 addStyleName 方法。

示例

Java:

Label label = new Label();
label.addStyleName("my-custom-style");

CSS:

.my-custom-style {
    font-size: 12px:
    font-family: Arial;
}

包含自定义样式表。

  • @StyleSheet("my-style-sheet.css") 添加到您的班级/用户界面的顶部
  • 在相同包结构下的资源文件夹中创建 CSS 文件。

编辑:

由于这是在生成的报告中使用,因此您不能使用上述解决方案:

而不是像你一样使用样式标签。如果您将文本包装在跨度标记中,则可以使用内联样式将其专门应用于该标签:

label.setValue("<span style=\"font-size: 12px; font-family: Arial;\">Your text here</span>");

注意:请注意使用方法。您正在为潜在的 HTML 注入敞开心扉,需要采取一些措施来防止这种情况发生。

【讨论】:

  • 很遗憾我不能这样做,因为它是用户生成的报告
【解决方案2】:

在 HTML 树中隔离某些元素并不是真正的 Vaadin 问题。在 HTML5 中解决此问题的一种方法是使用带有 srcdoc 属性的 iframe(或 src="data:...")。

这是一个如何将它与 Vaadin8 一起使用的示例,但请注意:一旦您在 Label 中处理 HTML,有责任正确引用/编码那里的所有内容 - - 特别是,既然你提到了,所有这些内容都来自用户!

// run with `spring run --watch <file>.groovy`
@Grapes([
@Grab('com.vaadin:vaadin-spring-boot-starter:2.0.1'),
@Grab('com.vaadin:vaadin-server:8.1.6'),
@Grab('com.vaadin:vaadin-client-compiled:8.1.6'),
])

import com.vaadin.ui.*
import com.vaadin.ui.themes.*
import com.vaadin.shared.*
import com.vaadin.shared.ui.ContentMode


@com.vaadin.spring.annotation.SpringUI
@com.vaadin.annotations.Theme("valo")
class MyUI extends UI {
        protected void init(com.vaadin.server.VaadinRequest request) {
        setContent(new VerticalLayout(
            new Label("<h1>Hello</h1><p>Lorem Ipsum</p>", ContentMode.HTML),
            new Label("""
                <iframe srcdoc="
                    <style type='text/css'>* { font-family: monospace; font-size: 36pt; background-color: green; }</style>
                    <h1>Test</h1>
                    <p>Lorem Ipsum</p>
                "></iframe>
            """, ContentMode.HTML),
            new Label("<h1>Hello</h1><p>Lorem Ipsum</p>", ContentMode.HTML),
        ))  
    }
}

【讨论】:

    【解决方案3】:

    通常,您不应该将样式内联添加到 Vaadin 组件。您应该在主题或自定义 CSS 文件中的 CSS 文件中添加样式定义,并将它们作为@Jay 提到的。

    如果你真的想使用内联样式定义,那么你必须使用CssLayout

    https://vaadin.com/docs/v8/framework/layout/layout-csslayout.html

    【讨论】:

    • 这是一个用户生成的报告,可以包含样式
    • 在这种情况下,正如我所说,请查看CssLayout。文档中有一个示例展示了如何为您的元素注入自定义 CSS。
    【解决方案4】:

    我最终使用的是 BrowserFrame。唯一的问题是 BrowserFrame 的高度不能像带有 -1px 的标签那样动态调整大小。

    【讨论】:

      猜你喜欢
      • 2019-03-22
      • 1970-01-01
      • 2020-02-08
      • 2016-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多