Как переопределить CSS PrimeFaces по умолчанию с пользовательскими стилями?

Я создал свою собственную тему как отдельный проект Maven, и она загружена правильно.

Теперь я хочу изменить размер компонента. Например, <p:orderList>. Он имеет класс ui-orderlist-list, который определен в primefaces.css с фиксированным размером 200x200. Независимо от того, что я делаю в моем theme.css, он перезаписывается этим атрибутом, и я никак не могу сделать контент частью <p:orderList> более широким.

Для других компонентов я мог бы хотеть переопределить только один экземпляр компонента, не все.

Может кто-нибудь сказать, пожалуйста, как я могу все это сделать?

Ответ 1

Есть несколько вещей, которые вы должны принять во внимание, какая из них может иметь отношение к вашему конкретному случаю

Загрузите ваш CSS после PrimeFaces one

Вы должны убедиться, что ваш CSS загружен после PrimeFaces. Вы можете добиться этого, поместив <h:outputStylesheet> со ссылкой на ваш файл CSS внутри <h:body> вместо <h:head>:

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

JSF автоматически переместит таблицу стилей в конец сгенерированного HTML <head>, что обеспечит загрузку таблицы стилей после стилей по умолчанию PrimeFaces. Таким образом, селекторы в вашем CSS файле, точно такие же, как в CSS файле PrimeFaces, получат приоритет над PrimeFaces.

Вы, вероятно, также увидите предложения поместить его в <f:facet name="last"> из <h:head>, что понимают специфичные для PrimeFaces HeadRenderer, но это излишне неуклюже и сломается, когда у вас будет свой собственный HeadRenderer.

Понимать специфику CSS

Вы также должны убедиться, что ваш селектор CSS по крайней мере так же специфичен, как и селектор CSS по умолчанию PrimeFaces для конкретного элемента. Вы должны понимать CSS Specificity и правила каскадирования и наследования. Например, если PrimeFaces объявляет стиль по умолчанию следующим образом

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

и вы объявляете его как

.ui-bar {
    color: purple;
}

и конкретный элемент с class="ui-bar" имеют родительский элемент с class="ui-foo", тогда элемент PrimeFaces все равно получит приоритет, потому что это наиболее конкретное совпадение!

Вы можете использовать инструменты разработчика веб-браузера, чтобы найти точный селектор CSS. Щелкните правой кнопкой мыши по рассматриваемому элементу в веб-браузере (IE9/Chrome/Firefox + Firebug) и выберите Inspect Element, чтобы увидеть его.

Частичное переопределение

Если вам нужно переопределить стиль только для конкретного экземпляра компонента, а не для всех экземпляров одного и того же компонента, добавьте пользовательский styleClass и вместо этого подключите его. Это еще один случай, когда специфичность используется/применяется. Например:

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

Если компонент не поддерживает styleClass и вы используете jsf 2.2 или выше, вы также можете использовать проходные атрибуты, добавить pt:class и получить его на выходе.

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

Никогда не используйте! Важный

В случае, если вам не удастся загрузить файл CSS по порядку или правильно выбрать селектор CSS, вы, вероятно, воспользуетесь обходным решением !important. Это просто неправильно. Это уродливый обходной путь, а не реальное решение. Это только сбивает с толку ваши правила стиля и себя больше в долгосрочной перспективе. !important следует использовать только для переопределения значений, жестко закодированных в атрибуте HTML-элемента style из файла таблицы стилей CSS (что, в свою очередь, также является плохой практикой, но в некоторых редких случаях, к сожалению, неизбежно).

Смотрите также:

Ответ 2

вы можете создать новый файл css, например cssOverrides.css

и поместите все переопределения, которые вы хотите в него, таким образом, обновление версии прайс-листов не повлияет на вас,

и в вашей h: head добавьте что-то вроде этого

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

если он не работает, попробуйте добавить его в h: body

чтобы проверить, работает ли этот простой пример внутри файла css

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

это уменьшит размер всех компонентов/текста

Ответ 3

Я использую PrimeFaces 6.0. Вот некоторая информация, которую мне хотелось бы по этому поводу:

Если вы используете <h:outputStylesheet/>, он будет работать, но ваш CSS не будет загружен последним, даже если он будет длиться в тегах <h:head></h:head> (позже будут добавлены другие файлы CSS). Трюк, который вы можете сделать, который я узнал из здесь, - это разместить его внутри <f:facet name="last"></f:facet>, , который должен войти в тело, например:

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

Затем ваш CSS будет последним загруженным. Примечание: вам все равно придется придерживаться правил специфичности, как описано в BalusC.

Я разместил "MyCSS.css" в WebContent/resources/css/.

Дополнительная информация о порядке загрузки ресурсов: http://www.mkyong.com/jsf2/primefaces/resource-ordering-in-primefaces

Ответ 4

Как создать более конкретные правила

Правила стиля, используемые PrimeFaces, могут быть довольно сложными. Элемент может получить свой стиль из нескольких правил CSS. Полезно знать, что вы можете использовать фильтрацию на вкладке стиля инспектора DOM для поиска свойства, которое вы хотите настроить:

Этот снимок экрана был сделан с использованием Chrome, но фильтрация также доступна в Firefox и Safari.

Когда вы нашли правило, которое хотите настроить, вы можете просто создать более конкретное правило, добавив к нему префикс html. Например, вы можете переопределить .ui-corner-all как:

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

Замените значения темы с помощью ResourceHandler

Я обычно просто хочу заменить один цвет другим значением. Поскольку цвета могут использоваться во многих различных правилах, полезно создать ResourceHandler.

В обработчике проверьте тему 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);
}

В ресурсе замените цвет:

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

И зарегистрируйте его следующим образом в face-config.xml:

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

Для получения дополнительной информации об обработчиках ресурсов см.: