I want to change the size of a PrimeFaces component. For example, a <p:orderList>. It has a class called ui-orderlist-list which is defined in primefaces.css with a fixed 200x200 dimension. No matter what I do in my theme.css, it is overwritten by this attribute and there is no way I can make the content part of a <p:orderList> wider.
For other components I might want to override just one instance of a component, not all.
Can anyone please tell me how can I do all this?
There are several things you need to take into account of which one or more might be relevant you your specific case
Load your CSS after PrimeFaces one
You need to ensure that your CSS is loaded after the PrimeFaces one. You can achieve this by placing the <h:outputStylesheet> referencing your CSS file inside <h:body> instead of <h:head>:
<h:head>
...
</h:head>
<h:body>
<h:outputStylesheet name="style.css" />
...
</h:body>
JSF will automatically relocate the stylesheet to the end of the generated HTML <head> and this will thus ensure that the stylesheet is loaded after the PrimeFaces' default styles. This way the selectors in your CSS file which are exactly the same as in PrimeFaces CSS file will get precedence over the PrimeFaces one.
You'll probably also see suggestions to put it in <f:facet name="last"> of <h:head> which is understood by PrimeFaces-specific HeadRenderer, but this is unnecessarily clumsy and would break when you have your own HeadRenderer.
Understand CSS specificity
You also need to ensure that your CSS selector is at least as specific as the PrimeFaces' default CSS selector on the particular element. You need to understand CSS Specificity and Cascading and Inheritance rules. For example, if PrimeFaces declares a style by default as follows
.ui-foo .ui-bar {
color: pink;
}
and you declare it as
.ui-bar {
color: purple;
}
and the particular element with class="ui-bar" happen to have a parent element with class="ui-foo", then the PrimeFaces' one will still get precedence because that's the most specific match!
You can use the webbrowser developer tools to find the exact CSS selector. Rightclick the element in question in the webbrowser (IE9/Chrome/Firefox+Firebug) and choose Inspect Element to see it.
Partial overriding
If you need to override a style for only a specific instance of the component and not all instances of the same component, then add a custom styleClass and hook on that instead. It is another case where specificity is used/applied. For example:
<p:dataTable styleClass="borderless">
.ui-datatable.borderless tbody,
.ui-datatable.borderless th
.ui-datatable.borderless td {
border-style: none;
}
If a component does not support a styleClass and you are on jsf 2.2 or up, you can also use passtrough attributes and add a pt:class and have it end-up on the output.
<p:clock pt:class="borderless" />
Never use !important
In case you fail to properly load the CSS file in order or to figure the right CSS selector, you'll probably grab the !important workaround. This is Plain Wrong. It's an ugly workaround and not a real solution. It only confuses your style rules and yourself more in long term. The !important should only be used in order to override the values hardcoded in HTML element's style attribute from a CSS stylesheet file on (which is in turn also a bad practice, but in some rare cases unfortunately unavoidable).
See also:
How to reference CSS / JS / image resource in Facelets template?
Mozilla Developer Network > CSS > Specificity (great article, a must read!)
Understanding Style Precedence in CSS: Specificity, Inheritance, and the Cascade
you can create a new css file for example cssOverrides.css
and place all the overrides you want inside it, that way upgrading the primefaces version wont affect you ,
and in your h:head add something like that
<link href="../../css/cssOverrides.css" rel="stylesheet" type="text/css" />
if it wont work try adding it to the h:body
in order to check if its working try this simple example inside the css file
.ui-widget {
font-size: 90% !important;
}
this will reduce the size of all primefaces components /text
I'm using PrimeFaces 6.0. Here's some information I would have liked to have regarding this:
If you use <h:outputStylesheet/>, it will work, but your CSS will not be loaded last even if it's last in the <h:head></h:head> tags (other CSS files will be included afterwards). A trick you can do which I learned from here is to place it inside <f:facet name="last"></f:facet>, which must go inside the body, like so:
<h:body>
<f:facet name="last">
<h:outputStylesheet name="css/MyCSS.css" />
</f:facet>
...
Then your CSS will be the last loaded. Note: you will still have to adhere to the specificity rules as BalusC outlined.
I placed "MyCSS.css" in WebContent/resources/css/.
More information on the resource loading order: http://www.mkyong.com/jsf2/primefaces/resource-ordering-in-primefaces
Load your CSS after PrimeFaces?
Although loading your CSS after the PrimeFaces CSS will override existing rules, I don't thinks it's a good idea. It's better to create more specific rules. More specific rules will always "win", no matter what the order is. If you for example would be using a combined resources handler in combination with PrimeFaces Extension LightSwitch, the switched PrimeFaces theme will be loaded last, making it "win" with equal rules!
How to create more specific rules
The style rules used by PrimeFaces can be quite complex. An element can receive its styling from multiple CSS rules. It's good to know you can use filtering in the DOM inspector's style tab to search on the property you want to customize:
This screenshot was taken using Chrome, but filtering is also available in Firefox and Safari.
When you have found the rule you want to customize, you can simply create a more specific rule by prefixing it with html. For example, your could override .ui-corner-all like:
html .ui-corner-all {
border-radius: 10px;
}
Use a different theme
Sometimes it's just easier to switch to a different theme and start from there. Have a look at the themes in the showcase.
You might also consider buying a premium theme (disclaimer: I'm not employed by PrimeTek). You can find an overview of templates in the showcase as well.
Using the style attribute
PrimeFaces components can render quite complex HTML. Normally, the style attribute is only applied to the most outer HTML node that the component renders. Also, style is not reusable, so it is better to set a styleClass and create CSS rule(s) based on the class you've set. This also allows you to style inner HTML nodes rendered by the component.
Using the styleClass attribute
PrimeFaces comes with themes (and templates) which have many built in classes. You might find that an existing class will already do the customization you has in mind. For example to remove borders from a p:panelGrid one can simply apply the class ui-noborder. Or the classes that we recently added to PrimeFaces 10 to style buttons, like ui-button-warning.
If you are using PrimeFlex, you can use its classes on components to apply certain styles.
See:
How to remove border from specific PrimeFaces p:panelGrid?
https://www.primefaces.org/showcase/ui/button/commandButton.xhtml
Override a single instance of a component
If you want to override the style of a single instance, use the styleClass attribute to add a CSS class to that instance. You can now use the CSS class you've added in your CSS selectors to create styles.
Replace theme values using a ResourceHandler
I usually just want to replace some color with another value. As colors can be used in many different rules it can be useful to create a ResourceHandler.
In the handler check for the PrimeFaces theme:
#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);
}
In the resource, replace the 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));
}
And register it as follows in the faces-config.xml:
<application>
<resource-handler>com.example.MyResourceHandler</resource-handler>
</application>
A resource handler which replaces the accent colors of the Arya, Saga and Vela themes with CSS variables is available in PrimeFaces Extension 10.0.1, see https://www.primefaces.org/showcase-ext/sections/utils/themeAccentColorResourceHandler.jsf.
For more information on resource handlers see:
How to load dynamic resources in JSF?
Following the same idea of the accepted answer but without using
<h:outputStylesheet>
and using templates and I must to achieve the goal of load the .css files after the own of Primefaces but at the header block of the page.
template.xhtml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
<h:head>
<title><ui:insert name="title">TEST</ui:insert></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<ui:insert name="headcontent"></ui:insert>
</h:head>
<h:body>
<div id="content">
<ui:insert name="content"></ui:insert>
</div>
<div id="bottom">
<ui:insert name="bottom"></ui:insert>
</div>
</h:body>
</html>
main.xhtml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition template="template.xhtml"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
xmlns:fn="http://xmlns.jcp.org/jsf/jstl/functions">
<ui:define name="title">TEST</ui:define>
<ui:define name="headcontent">
<link type="text/css" rel="stylesheet" href="../resources/css/index.css"/>
</ui:define>
<ui:define name="content">
...
</ui:define>
<ui:define name="bottom">
...
</ui:define>
</ui:composition>
These is an example of how to insert source .css or .scripts files using
<ui:insert>
and
<ui:define>
and as a result the custom .css or .js files are loaded after Primefaces ones and if you look the page info at the browser you can see that these lines are inserted at the end of the header block of the page.
Related
I have this CSS code:
td[data-date='2016-03-08']{
background-color: #F7F7F7;
}
I want to apply it on several dates that I want to load from a database. All this could happen inside my JSF managed bean where I generate the CSS code.
So my question is, how can I apply the CSS that I'm gonna get from my JSF managed bean?
One way is to print it as body of HTML <style> tag which you put in HTML head.
<h:head>
...
<style>#{bean.css}</style>
</h:head>
I'm using twbs bootstrap 3.3.6 with Meteor and trying to style a <fieldset>.
However when I use the Chrome inspector it says that the style is coming from bootstrap.css even though I have tried using class-specific and id-specific css.
My style sheet is in the application root, as suggested by some answers.
I'm very new to meteor and css so I could be making a novice error.
Otherwise, what's the best practice to override bootstrap css settings?
Generally if you want to override the css you should put your css file after all of the other files like the bootstrap css because css starts from top to bottom so the bottom lines are the ones that will be executed, example:
<link rel="stylesheet" href="css/bootstrap.min.css" />
<link rel="stylesheet" href="css/your-css.css" />
Also you can add !important at the end of every css line to give that style the top priority no matter of the line index, example:
.someclass {
color: red!important;
}
You can either override the specific property on the same class in your css...
.btn {
background-color: #fff !important;
}
...create an inheritance map so that it only applies to the element inside another specific element...
div.classForSpecificContainer btn {
background-color: #fff !important;
}
or specify your own class and add it to the element in question
myOverrideClass {
background-color: #fff !important;
}
The.. important part is that you use !important; to prevent Bootstrap from overriding it. That will generally solve the problem even if the CSS files load in the incorrect order, but not always. I have made a habit of prefixing my CSS files in the same folder with z- to make sure they get loaded last if I'm using something like Meteor that merges and compresses the CSS.
This seems to be a common problem in Meteor because of the way their build injects the merged stylesheet into the top of the html <header> instead of the bottom. There is a merged PR that looks like it will be available in 1.6.2 that allows you to put a pseudo tag anywhere in the <head> you want the merged css injected.
Example: proposed availability in 1.6.2 - PR already merged
<head>
<link rel='stylesheet' type='text/css' href='some-cdn.bootstrap.css'/>
<meteor-bundled-css/>
</head>
That will work once the merged PR is included in the next build.
Until then...
SOLUTION 1: If you're using the bootstrap LESS or SCSS files, you can just import it into your client/main.less or client/main.scss file and then import your override file after this. It looks like you're using pre=compiled css though, so move to SOLUTION 3.
SOLUTION 2: Use !important on the end of your lines... BAD not recommended practice. If you use important you break the cascade.
SOLUTION 3: Put you third-party library overrides files in your public folder and manually <link> it below the bootstrap <link> in your head. I suggest this for now.
I have been given an external stylesheet (.css file) that may not altered in any way whatsoever. However I need to apply this stylesheet to a single div and therefore the contents of the div in my already existing webpage. I am currently reading the contents of the stylesheet as text into a blank style tag (using .innerHTML) within the div I need to affect but this still affects the entire web page rather than just the single div. Could someone please help with this?
The IFRAME solution works like this:
In your main HTML file, you'll have your DIV:
<div id="myspecialdiv">
<iframe width="100%" height="100%" frameborder="0" src="divcontent.html"></iframe>
</div>
Style that as you need it. The divcontent.html file should be a complete HTML file, including the content of the DIV tag, and a LINK using your external stylesheet:
<html>
<head>
<link rel="stylesheet" href="path/to/external/stylesheet.css" />
</head>
<body>
<!-- The contents of your DIV -->
</body>
</html>
If you can work with HTML5, you could try using scoped styles. You could include the CSS inside the div, having it affect only its parent:
<div>
<style scoped>
// Styles here
</style>
</div>
This will helps you a lot:
http://css-tricks.com/saving-the-day-with-scoped-css/
Applies only style to a certain delimited escope. Good luck!
IMHO better than the iframe solution..
related: Limit scope of external css to only a specific element?
If you have access to server-side scripting (eg: PHP), you could create a script that loads the external stylesheet, and appends a class name in front of every entry. Then apply this class to your DIV tag. So, if the CSS includes:
p { font-size: 12px; }
You'd modify that to:
.mydiv p { font-size: 12px; }
And format your DIV as
<div class="mydiv">...</div>
You would then load the script as a stylesheet, rather than the external stylesheet directly.
<link rel="stylesheet" href="path/to/internal/script.php" />
I suggest you can leave the external style sheet as it is and create an internal style sheet with the classes that you want from the external stylesheet to affect your single div and just rename it and apply those renamed classes to the div. The renaming is because the attributes of those classes may affect elements already existing on the page from external stylesheets.
<style>
.xxx {...} /* The renamed class from this internal css that should apply to your div */
</style>
Hope this helps.
I assume that the style specifications inside the external file are not contained in classes or IDs, but are they blanket adjustments to tags like <p> (and thus it cannot be included in your page headers). Include your div in a <style scoped> tag and import the .css file there. See: http://css-tricks.com/saving-the-day-with-scoped-css/
You could assign a CSS prefix to target the section of your document you want to style.
scoped is a good idea, but has browser compatible issue.
I solve this problem by adding pre-class before all selector in css file:
https://github.com/ericf/grunt-css-selectors
Is it possible to load external Style Sheet after Internal (or embedded) styles get loaded. I mean, say I have a div with Yellow background color, set using embedded style in a page, like;
<style type="text/css">
div{
background-color: yellow;
}
</style>
And can I change the background color to green using an external style sheet like;
<link rel="stylesheet" href="style.css" type="text/css" />
If this is possible, show me an example.
I know this is possible with inline style, but I don't want to use that.
Yes.
Just put the <link> tag after the <style> tag, or make the selector in the external stylesheet more specific.
To answer your question, yes you can. The styles will be applied in a specific order. See here for precedence rules in CSS.
if you want to overwrite a css with same class, you can use 'important' in that class. Study more about important in css.
offcourse you can just place the external style sheet after the internal style sheet in HTML head section to override the internal style sheet!
CSS ORDER
What style will be used when there is more than one style specified for an HTML element?
Generally speaking we can say that all the styles will "cascade" into a new "virtual" style sheet by the following rules, where number four has the highest priority:
1. Browser default
2. External style sheet
3. Internal style sheet (in the head section)
4. Inline style (inside an HTML element)
I have some html files with their own css. I want to use them in a gwt application so i copied the html and the css files in the application.
The problem is when i open the html it uses the gwt theme style. For example in my css the html 'body' background color is black, but it looks white unless i deactivate the theme.
How could I override the gwt theme style and use my css styles?
This post on the GWT mailing list describes an alternative solution. You have to create a new ClientBundle which references your CSS file:
import com.google.gwt.core.client.GWT;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.CssResource;
public interface Resources extends ClientBundle {
public static final Resources INSTANCE = GWT.create(Resources.class);
#Source("style.css")
#CssResource.NotStrict
CssResource css();
}
And then inside your onModuleLoad() method you have to inject the CSS file:
public class YourApp implements EntryPoint {
public void onModuleLoad() {
//...
Resources.INSTANCE.css().ensureInjected();
//...
}
In my opinion this is the cleanest and easiest way to override the styles.
Like Sarfaz said - !important should be your last resort as it kind of defeats the whole concept of Cascading Style Sheets.
Anyway, in GWT, in order to easily override the core GWT styles contained in the theme you selected, you should locate your module file (the one that has a file name ending on *.gwt.xml), then locate the line where you declare your theme and put your custom/whatever stylesheet after it, like this:
<inherits name='com.google.gwt.user.theme.standard.Standard' />
<stylesheet src="CustomStylesheet.css" />
Note, however, that for GWT 2.0 CssResource and UiBinder is recommended.
Be sure to read the appropriate section of the docs for more pointers.
You can override the styles of GWT by using the keyword !important in all your css of the html files, for example, if one of your html file contains this css:
background-color:#000000;
Then you should write it like this:
background-color:#000000 !important;
Do the same for all your styles in html files.
Note that using !important is not the best way, if you can find any better alternatives you should go for them first.
In addition to using !important you can also rely on CSS Selector Specificity.
Most (all?) of the GWT styles are stated using just class eg:
.gwt-DisclosurePanel .header {
color: black;
cursor: pointer;
text-decoration: none;
}
To override this you can use !important or you can be more specific in your selectors eg:
table.gwt-DisclosurePanel .header {
text-decoration: underline;
}
How does this work? This works because adding the element name (table) to the class in the selector makes it more specific than just the class alone. This will override other styles even from stylesheets listed lower in the header.
Giving your widgets IDs and using those is even more specific.
I know it's not very elegant but I found it rather effective to replace the standard.css file in the output files generated by GWT with an empty file.
(Maven can take care of that reliably.)
The solution <stylesheet src="CustomStylesheet.css" /> is deprecated and did not work with the new superdevmode.
A solution that worked for me (using GWT 2.7) was to create a new custom theme:
projectPackage/themes/MyCustomTheme/MyCustomTheme.gwt.xml
<module>
<stylesheet src="gwt/MyCustomTheme/MyCss.css"/>
</module>
projectPackage/themes/MyCustomTheme/MyCustomThemeRessources.gwt.xml
</module>
projectPackage/themes/MyCustomTheme/public/gwt/MyCustomTheme/MyCss.css
(Note: removing the gwt/MyCustomTheme/ part of the path worked in devmode but didn't work in deployed version, of cause you can still rename 'MyCustomTheme' to something of your liking)
The css file you want to use
Project.gwt.xml
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 2.0//EN"
"http://google-web-toolkit.googlecode.com/svn/releases/2.0/distro-source/core/src/gwt-module.dtd">
<module rename-to="Project">
(...)
<!-- Inherit GWT theme. e.g. the Clean theme -->
<inherits name='com.google.gwt.user.theme.clean.Clean'/>
<!-- Our custom theme -->
<inherits name='projectPackage.themes.MyCustomTheme.MyCustomTheme'/>
(...)
</module>
Note: You can get a sample custom theme using http://gwt-theme-generator.appspot.com/ and extracting the downloaded .jar file.
That's easy. Just put your CSS link under the GWT's module script:
<script type="text/javascript" src="myapp/myapp.nocache.js"></script>
<link rel="stylesheet" href="myapp.css" type="text/css">