web-dev-qa-db-fra.com

Comment remplacer les CSS PrimeFaces par défaut avec des styles personnalisés?

J'ai créé mon propre thème en tant que projet Maven distinct et il est chargé correctement.

Maintenant, je veux changer la taille d'un composant. Par exemple, un <p:orderList> . Il a une classe appelée ui-orderlist-list qui est défini dans primefaces.css avec une dimension fixe de 200x200. Peu importe ce que je fais dans mon theme.css, il est écrasé par cet attribut et je ne peux en aucune façon intégrer le contenu à un <p:orderList> plus large.

Pour d'autres composants, je souhaiterais peut-être remplacer une seule instance d'un composant, pas toutes.

Quelqu'un peut-il me dire s'il vous plaît comment puis-je faire tout cela?

60
Samuel Tian

Vous devez tenir compte de plusieurs facteurs dont un ou plusieurs pourraient vous être utiles.

Chargez votre CSS après PrimeFaces one

Vous devez vous assurer que votre CSS est chargé après celui de PrimeFaces. Vous pouvez y parvenir en plaçant le <h:outputStylesheet> Faisant référence à votre fichier CSS dans <h:body> Au lieu de <h:head>:

<h:head>
    ...
</h:head>
<h:body>
    <h:outputStylesheet name="style.css" />
    ...
</h:body>

JSF déplacera automatiquement la feuille de style à la fin du code HTML généré <head>, Ce qui garantira le chargement de la feuille de style après les styles par défaut de PrimeFaces. De cette façon, les sélecteurs de votre fichier CSS qui sont exactement les mêmes que dans le fichier CSS de PrimeFaces auront la priorité sur ceux de PrimeFaces.

Vous verrez probablement aussi des suggestions pour le mettre dans <f:facet name="last"> Sur <h:head>, Qui est compris par HeadRenderer, spécifique à PrimeFaces, posséder HeadRenderer.

Comprendre la spécificité CSS

Vous devez également vous assurer que votre sélecteur CSS est au moins aussi spécifique que le sélecteur CSS par défaut de PrimeFaces sur l'élément en question. Vous devez comprendre spécificité CSS et règles de cascade et d'héritage . Par exemple, si PrimeFaces déclare un style par défaut comme suit

.ui-foo .ui-bar {
    color: pink;
}

et vous le déclarez comme

.ui-bar {
    color: purple;
}

et l'élément particulier avec class="ui-bar" ayant un élément parent avec class="ui-foo", celui de PrimeFaces aura toujours la priorité car c'est le match le plus spécifique!

Vous pouvez utiliser les outils de développement Webbrowser pour trouver le sélecteur CSS exact. Cliquez avec le bouton droit sur l'élément en question dans le navigateur Web (IE9/Chrome/Firefox + Firebug) et choisissez Inspecter élément pour le voir.

Dépassement partiel

Si vous devez remplacer un style pour une occurrence spécifique du composant et non pour toutes les occurrences du même composant, ajoutez un styleClass personnalisé et accrochez-le à la place. C'est un autre cas où la spécificité est utilisée/appliquée. Par exemple:

<p:dataTable styleClass="borderless">
.ui-datatable.borderless tbody,
.ui-datatable.borderless th
.ui-datatable.borderless td {
    border-style: none;
}

Si un composant ne prend pas en charge styleClass et que vous utilisez jsf 2.2 ou version ultérieure, vous pouvez également utiliser attributs de substitution et ajouter un pt:class Et le renvoyer. sur la sortie.

<p:clock pt:class="borderless" />

Ne jamais utiliser! Important

Si vous ne parvenez pas à charger correctement le fichier CSS dans l’ordre ou à choisir le bon sélecteur CSS, vous obtiendrez probablement la solution de contournement !important. C'est tout simplement faux. C'est une solution de contournement moche et pas une vraie solution. Cela confond seulement vos règles de style et vous-même plus à long terme. Le !important Devrait seulement être utilisé afin de remplacer les valeurs codées en dur dans l'attribut style de l'élément HTML à partir d'une feuille de style CSS fichier sur (ce qui est également une mauvaise pratique, mais dans de rares cas, malheureusement inévitable).

Voir également:

113
BalusC

vous pouvez créer un nouveau fichier css, par exemple cssOverrides.css

et placez tous les remplacements que vous voulez dedans, de cette façon la mise à jour de la version de primefaces ne vous affectera pas,

et dans votre h: tête ajouter quelque chose comme ça

<link href="../../css/cssOverrides.css" rel="stylesheet" type="text/css" />

si cela ne fonctionne pas, essayez de l'ajouter au h: body

afin de vérifier si son fonctionnement essayez cet exemple simple à l'intérieur du fichier css

.ui-widget {
   font-size: 90% !important;
}

cela réduira la taille de tous les composants/texte de primefaces

4
Daniel

J'utilise PrimeFaces 6.0. Voici quelques informations que j'aurais aimé avoir à ce sujet:

Si vous utilisez <h:outputStylesheet/>, Cela fonctionnera, mais votre CSS ne sera pas chargé en dernier même s'il est conservé en dernier dans les balises <h:head></h:head> (Les autres fichiers CSS seront ensuite inclus). Un truc que vous pouvez faire et que j’ai appris de ici est de le placer à l’intérieur de <f:facet name="last"></f:facet>, qui doit aller à l’intérieur du corps , ainsi:

<h:body>
  <f:facet name="last">
    <h:outputStylesheet name="css/MyCSS.css" />
  </f:facet>
...

Ensuite, votre CSS sera le dernier chargé. Remarque: vous devrez toujours respecter les règles de spécificité décrites dans BalusC.

J'ai placé "MyCSS.css" dans WebContent/resources/css /.

Plus d'informations sur l'ordre de chargement des ressources: http://www.mkyong.com/jsf2/primefaces/resource-ordering-in-primefaces

3
Andrew

Comment créer des règles plus spécifiques

Les règles de style utilisées par PrimeFaces peuvent être assez complexes. Un élément peut recevoir son style à partir de plusieurs règles CSS. Il est bon de savoir que vous pouvez utiliser le filtrage dans l'onglet Style de l'inspecteur DOM pour rechercher sur la propriété que vous souhaitez personnaliser:

Cette capture d'écran a été prise avec Chrome, mais le filtrage est également disponible dans Firefox et Safari.

Lorsque vous avez trouvé la règle que vous souhaitez personnaliser, vous pouvez simplement créer une règle plus spécifique en la préfixant par html. Par exemple, votre pourrait remplacer .ui-corner-all comme:

html .ui-corner-all {
  border-radius: 10px;
}

Remplacer les valeurs de thème en utilisant un ResourceHandler

D'habitude, je veux juste remplacer une couleur par une autre valeur. Comme les couleurs peuvent être utilisées dans de nombreuses règles différentes, il peut être utile de créer un ResourceHandler .

Dans le gestionnaire, recherchez le thème 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);
}

Dans la ressource, remplacez la couleur:

public MyResource(Resource wrapped, ResourceHandler handler) {
  this.wrapped = wrapped;
  this.handler = handler;
  this.charset = Charset.forName(FacesContext.getCurrentInstance().getExternalContext().getResponseCharacterEncoding());
}

@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));
}

Et enregistrez-le comme suit dans le fichier faces-config.xml:

<application>
  <resource-handler>com.example.MyResourceHandler</resource-handler>
</application>

Pour plus d'informations sur les gestionnaires de ressources, voir:

1
Jasper de Vries