¿Cómo anulo el CSS predeterminado de PrimeFaces con estilos personalizados?
Quiero cambiar el tamaño de un componente PrimeFaces. Por ejemplo, un <p:orderList>
. Tiene una clase llamada ui-orderlist-list
que se define primefaces.css
con una dimensión fija de 200x200. No importa lo que haga en mi theme.css
, este atributo lo sobrescribe y no hay manera de que pueda hacer que el contenido forme parte de uno <p:orderList>
más amplio.
Para otros componentes, es posible que desee anular solo una instancia de un componente, no todas.
¿Alguien puede decirme cómo puedo hacer todo esto?
Hay varias cosas que debes tener en cuenta y cuál o más podrían ser relevantes para tu caso específico.
Cargue su CSS después de PrimeFaces one
Debe asegurarse de que su CSS esté cargado después del de PrimeFaces. Puede lograr esto colocando la <h:outputStylesheet>
referencia a su archivo CSS dentro <h:body>
en lugar de <h:head>
:
<h:head>
...
</h:head>
<h:body>
<h:outputStylesheet name="style.css" />
...
</h:body>
JSF reubicará automáticamente la hoja de estilo al final del HTML generado <head>
y esto garantizará que la hoja de estilo se cargue después de los estilos predeterminados de PrimeFaces. De esta manera, los selectores en su archivo CSS que son exactamente los mismos que en el archivo CSS PrimeFaces tendrán prioridad sobre el de PrimeFaces.
Probablemente también verás sugerencias para colocarlo, <f:facet name="last">
algo <h:head>
que entienden las aplicaciones específicas de PrimeFaces HeadRenderer
, pero esto es innecesariamente torpe y se rompería si tienes el tuyo propio HeadRenderer
.
Comprender la especificidad de CSS
También debe asegurarse de que su selector de CSS sea al menos tan específico como el selector de CSS predeterminado de PrimeFaces en el elemento en particular. Debe comprender la especificidad de CSS y las reglas de herencia y cascada . Por ejemplo, si PrimeFaces declara un estilo por defecto de la siguiente manera
.ui-foo .ui-bar {
color: pink;
}
y lo declaras como
.ui-bar {
color: purple;
}
y el elemento particular class="ui-bar"
tiene un elemento principal con class="ui-foo"
, entonces el de PrimeFaces seguirá teniendo prioridad porque es la coincidencia más específica.
Puede utilizar las herramientas de desarrollo del navegador web para encontrar el selector de CSS exacto. Haga clic derecho en el elemento en cuestión en el navegador web (IE9/Chrome/Firefox+Firebug) y elija Inspeccionar elemento para verlo.
anulación parcial
Si necesita anular un estilo solo para una instancia específica del componente y no para todas las instancias del mismo componente, agregue un estilo personalizado styleClass
y engánchelo. Es otro caso en el que se utiliza/aplica la especificidad. Por ejemplo:
<p:dataTable styleClass="borderless">
.ui-datatable.borderless tbody,
.ui-datatable.borderless th
.ui-datatable.borderless td {
border-style: none;
}
Si un componente no admite a styleClass
y está en jsf 2.2 o superior, también puede usar atributos de paso y agregar a pt:class
y hacer que termine en la salida.
<p:clock pt:class="borderless" />
¡Nunca uses! Importante
En caso de que no puedas cargar correctamente el archivo CSS en orden o no encuentres el selector de CSS correcto, probablemente encuentres la !important
solución alternativa. Esto es completamente incorrecto. Es una solución fea y no una solución real. Sólo confunde más tus reglas de estilo y a ti mismo a largo plazo. !important
Solo debe usarse para anular los valores codificados en el atributo del elemento HTML desde un archivo de hoja de estilo CSS (lo que a su vez también es una mala práctica, pero en algunos casos excepcionales, lamentablemente, es inevitable) .style
Ver también:
- ¿Cómo hacer referencia a CSS/JS/recurso de imagen en la plantilla Facelets?
- Mozilla Developer Network > CSS > Especificidad (excelente artículo, ¡debe leerse!)
- Comprender la precedencia de estilos en CSS: especificidad, herencia y cascada
puedes crear un nuevo archivo css, por ejemplo cssOverrides.css
y coloque todas las anulaciones que desee dentro de él, de esa manera la actualización de la versión Primefaces no le afectará.
y en tu h:head agrega algo así
<link href="../../css/cssOverrides.css" rel="stylesheet" type="text/css" />
Si no funciona intenta agregarlo al h:body
Para comprobar si funciona, pruebe este sencillo ejemplo dentro del archivo CSS.
.ui-widget {
font-size: 90% !important;
}
esto reducirá el tamaño de todos los componentes/texto de las caras principales
Estoy usando PrimeFaces 6.0. Aquí hay información que me hubiera gustado tener sobre esto:
Si usa <h:outputStylesheet/>
, funcionará, pero su CSS no se cargará al final, incluso si está al final en las <h:head></h:head>
etiquetas (otros archivos CSS se incluirán después). Un truco que puedes hacer y que aprendí aquí es colocarlo dentro <f:facet name="last"></f:facet>
, que debe ir dentro del cuerpo , así:
<h:body>
<f:facet name="last">
<h:outputStylesheet name="css/MyCSS.css" />
</f:facet>
...
Entonces tu CSS será el último cargado. Nota: aún deberá cumplir con las reglas de especificidad como se describe en BalusC.
Coloqué "MyCSS.css" en WebContent/resources/css/.
Más información sobre el orden de carga de recursos: http://www.mkyong.com/jsf2/primefaces/resource-ordering-in-primefaces
¿Cargar tu CSS después de PrimeFaces?
Aunque cargar su CSS después de PrimeFaces CSS anulará las reglas existentes, no creo que sea una buena idea. Es mejor crear reglas más específicas . Las reglas más específicas siempre "ganarán", sin importar cuál sea el orden. Si, por ejemplo, utilizaría un controlador de recursos combinado con PrimeFaces Extension LightSwitch
, el tema PrimeFaces cambiado se cargará en último lugar, lo que lo hará "ganar" con reglas iguales.
Cómo crear reglas más específicas
Las reglas de estilo utilizadas por PrimeFaces pueden ser bastante complejas. Un elemento puede recibir su estilo a partir de múltiples reglas CSS. Es bueno saber que puedes usar el filtrado en la pestaña de estilo del inspector DOM para buscar la propiedad que deseas personalizar:
Esta captura de pantalla se tomó con Chrome, pero el filtrado también está disponible en Firefox y Safari.
Cuando haya encontrado la regla que desea personalizar, simplemente puede crear una regla más específica poniéndole el prefijo html
. Por ejemplo, podrías anular .ui-corner-all
algo como:
html .ui-corner-all {
border-radius: 10px;
}
Usa un tema diferente
A veces es más fácil cambiar a un tema diferente y empezar desde allí. Eche un vistazo a los temas del escaparate .
También podría considerar comprar un tema premium (descargo de responsabilidad: no soy empleado de PrimeTek). También puede encontrar una descripción general de las plantillas en el escaparate.
Usando el style
atributo
Los componentes de PrimeFaces pueden representar HTML bastante complejo. Normalmente, el style
atributo solo se aplica al nodo HTML más externo que representa el componente. Además, style
no es reutilizable, por lo que es mejor establecer styleClass
y crear reglas CSS basadas en la clase que haya configurado. Esto también le permite diseñar los nodos HTML internos representados por el componente.
Usando el styleClass
atributo
PrimeFaces viene con temas (y plantillas) que tienen muchas clases integradas. Es posible que descubra que una clase existente ya realizará la personalización que tiene en mente. Por ejemplo, para eliminar los bordes de p:panelGrid
uno, simplemente puede aplicar la clase ui-noborder
. O las clases que agregamos recientemente a PrimeFaces 10 para diseñar botones, como ui-button-warning
.
Si está utilizando PrimeFlex , puede usar sus clases en componentes para aplicar ciertos estilos.
Ver:
- ¿Cómo eliminar el borde de PrimeFaces p:panelGrid específicos?
- https://www.primefaces.org/showcase/ui/button/commandButton.xhtml
Anular una instancia única de un componente
Si desea anular el estilo de una sola instancia, use el styleClass
atributo para agregar una clase CSS a esa instancia. Ahora puedes usar la clase CSS que agregaste en tus selectores de CSS para crear estilos.
Reemplazar los valores del tema usando unResourceHandler
Normalmente sólo quiero reemplazar algún color con otro valor. Como los colores se pueden utilizar en muchas reglas diferentes, puede resultar útil crear un archivo ResourceHandler
.
En el controlador, busque el tema PrimeFaces:
@Override
public Resource createResource(String resourceName,
String libraryName) {
if (isPrimeFacesTheme(resourceName, libraryName)) {
return new MyResource(super.createResource(resourceName, libraryName), this);
}
else {
return getWrapped().createResource(resourceName, libraryName);
}
}
protected boolean isPrimeFacesTheme(final String resourceName,
final String libraryName) {
return libraryName != null
&& libraryName.startsWith("primefaces-")
&& "theme.css".equals(resourceName);
}
En el recurso, reemplace el color:
private static String cache;
public MyResource(Resource wrapped, ResourceHandler handler) {
this.wrapped = wrapped;
this.handler = handler;
this.charset = Charset.forName(FacesContext.getCurrentInstance().getExternalContext().getRequestCharacterEncoding());
}
@Override
public InputStream getInputStream() throws IOException {
if (cache == null) {
cache = readInputStream(getWrapped().getInputStream());
// Replace values
cache = cache.replace("#007ad9", "#11dd99");
}
return new ByteArrayInputStream(cache.getBytes(charset));
}
Y regístrelo de la siguiente manera en faces-config.xml:
<application>
<resource-handler>com.example.MyResourceHandler</resource-handler>
</application>
Un controlador de recursos que reemplaza los colores de acento de los temas Arya, Saga y Vela con variables CSS está disponible en PrimeFaces Extension 10.0.1, consulte https://www.primefaces.org/showcase-ext/sections/utils/themeAccentColorResourceHandler.jsf .
Para obtener más información sobre los controladores de recursos, consulte:
- ¿Cómo cargar recursos dinámicos en JSF?