JSF <h:commandButton>使用Font Awesome图标是否存在限制?
你遇到的问题本质上和JSF组件的渲染行为有关,并非是<h:commandButton>的“限制”,而是它默认的渲染规则导致的:
为什么会出现这个问题?
标准HTML里的<input type="submit">是自闭合元素,不允许包含任何子元素(比如你的<i>标签)。而JSF的<h:commandButton>默认会被渲染成这种<input>类型的按钮,所以你放在它内部的<i class="fa fa-trash">并不会被当作DOM元素解析,而是会被当成按钮的文本值直接输出——这自然就无法触发Font Awesome的图标样式了。
而HTML原生的<button type="submit">是可以包含子元素的,这也是原生按钮能正常显示图标的原因。
解决方案:让<h:commandButton>渲染成
JSF 2.2及以后的版本已经支持将<h:commandButton>渲染为<button>标签(而非默认的<input>),这样就能完美容纳Font Awesome的图标标签了。你只需要稍微调整代码:
<h:commandButton styleClass="btn btn-default" action="#{myBean.name}" type="submit"> <i class="fa fa-trash" style="font-size: 1em"></i> </h:commandButton>
关键变化是明确指定type="submit",同时保留内部的<i>标签。此时JSF会自动将组件渲染为:
<button type="submit" class="btn btn-default" name="..." onclick="..."> <i class="fa fa-trash" style="font-size: 1em"></i> </button>
这样<i>标签就能正常被浏览器解析,Font Awesome图标也能显示了。
备选方案:用CSS伪元素实现图标(无需修改组件结构)
如果你不想调整组件的渲染类型,也可以通过CSS伪元素来为<h:commandButton>添加图标:
- 给按钮添加自定义类,并清空value:
<h:commandButton styleClass="btn btn-default fa-trash-btn" action="#{myBean.name}" value="" />
- 添加对应的CSS样式:
.fa-trash-btn::before { font-family: "Font Awesome 5 Free"; /* 根据你使用的Font Awesome版本调整 */ content: "\f1f8"; /* 垃圾桶图标的Unicode码,可从Font Awesome官网查询 */ font-weight: 900; /* 免费版本需要设置这个权重才能显示实心图标 */ /* 可添加padding、color等样式调整图标位置和外观 */ }
这种方法不需要修改组件内部结构,适合一些场景,但样式调整会稍微繁琐一点。
为什么<h:commandLink>可以?
因为<h:commandLink>默认被渲染成<a>标签,而<a>是可以包含子元素的行内元素,所以内部的<i>标签能正常解析——但正如你所说,用链接组件来做按钮确实不符合直觉,所以第一种渲染成<button>的方案是更贴合需求的选择。
内容的提问来源于stack exchange,提问作者gogogaga

