How to reference JSF image resource as CSS background image url - css

I often, change the images of my buttons using the image attribute, but someone told me that it is a good practice to do it using .css
I tried but i cant, what i am doing wrong? This is what i did:
1-The resources of my project are stored like this:
2-This is how i created the style.css for accessing the image
.c2 {
background: url(/resources/images/smiley.jpg);
}
3-This is how i access the css from the body of my page(Im sure this is correct because other classes in the same document works in other tags in this page)
<h:outputStylesheet library="css" name="style.css" />
4-This is how create a sample commandButton that uses the appropiated css class
<h:commandButton styleClass="c2"/>
I think the problem is in the .css, i tried a few combinations but none worked:
background-image: url(/resources/images/smiley.jpg);
background: url(resources/images/smiley.jpg);
background: url(smiley.jpg);
background: url(../smiley.jpg);
Where is the mistake?
update
I managed to make it work by the following code:
.c2 {
background: url("#{resource['images:smiley.jpg']}");
}
Notice the difference when i use css(right) and when i use image attribute(left)
How could i solve this so the hold image is shown?

When importing CSS stylesheets by <h:outputStylesheet>, the stylesheet is imported and processed by the FacesServlet through /javax.faces.resource/*. Look at the generated <link> element pointing to the stylesheet in question and you'll understand.
You have to change all url() dependencies to use #{resource['library:location']} instead. JSF will then auto-substitute it with the right path. Given your folder structure, you need to replace
.c2 {
background: url("/resources/images/smiley.jpg");
}
by
.c2 {
background: url("#{resource['images/smiley.jpg']}");
}
Assuming that your webapp context name is playground and that your FacesServlet is mapped on *.xhtml, then the above should end up in the returned CSS file as follows
.c2 {
background: url("/playground/javax.faces.resource/images/smiley.jpg.xhtml");
}
Noted should be that the JSF implementation will for determine only during the first request on the CSS file if it contains EL expressions. If it doesn't then it will for efficiency not anymore attempt to EL-evaluate the CSS file content. So if you add an EL expression to a CSS file for the first time, then you'd need to restart the whole application in order to get JSF to re-check the CSS file.
In case you wanted to reference a resource from a component library such as PrimeFaces, then prefix the library name, separated with :. E.g. when you're using PrimeFaces "Start" theme which is identified by primefaces-start
.c2 {
background: url("#{resource['primefaces-start:images/ui-bg_gloss-wave_50_6eac2c_500x100.png']}");
}
This will be generated as
.c2 {
background: url("/playground/javax.faces.resource/images/ui-bg_gloss-wave_50_6eac2c_500x100.png.xhtml?ln=primefaces-start");
}
See also:
How to reference CSS / JS / image resource in Facelets template?
Changing JSF prefix to suffix mapping forces me to reapply the mapping on CSS background images
Unrelated to the concrete problem, the way how you use the library is not entirely right. It's meant to be the common identifier/subfolder of all related CSS/JS/image resources. The key idea is to be able to change the entire look'n'feel by just changing the library (which can be done by EL). You seem however to be relying on the default library. In that case, you could just omit the library from your <h:outputStylesheet> and #{resource}.
<h:outputStylesheet name="css/style.css" />
See also:
What is the JSF resource library for and how should it be used?

Since I struggled with this a little bit and while BalusC has already answered the question but might be able to comment as to why this is happening. I have 5 EAR projects consisting of a bundled WAR and EJB projects. I then have one standalone WAR project deployed on its own. The following code worked perfect with all the EAR's:
<h:head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Super FIPS Calculator PRO</title>
<style>
.Bimage{background-image:url(#{request.contextPath}/img/phonetoolsBackground.png);}
</style>
</h:head>
<h:body styleClass="Bimage">
.
.
.
Where the "img" folder was within the WEB-INF folder but for the EAR project, it would not work and it wouldnt even load the picture in the browser by manually typing in the URL. I verified the resulting html was 100% accurate. So all the talk of "resources" got me thinking that maybe it was a ?security? issue of some sort which doesnt seem to make sense between the WAR and EAR deployments so I created a "resources" folderin the root of the web application, e.g. in Eclipse its parent would be WebContent, then added a subfolder to resources called "img", placed my image in there.
The code now looks like this:
<h:head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Super FIPS Calculator PRO</title>
<style>
.Bimage{background-image:url(#{request.contextPath}/resources/img/phonetoolsBackground.png);}
</style>
</h:head>
<h:body styleClass="Bimage">
.
.
.
And now the image is displayed. Again not trying to hijack balusc's thorough answer, I just wanted to bring it up in case anyone ran into a similar issue. If someone wants me to open a separate Q and A I will!
Ahh yes, this was on JBoss EAP 7, Servlet API 3.1, Facelets 2.2, Rich Faces 4.5.17 Java 1.8.
Edit #Basil-Bourque answer What is WEB-INF used for in a Java EE web application seems fairly relevant
But its still a little confusing in that how can a WAR within an EAR access that location but not a standalone WAR?

Related

AEM 6.5: Is there an HTL way to output Webpack-generated CSS within <style> tags from an AEM clientlib category?

Goal:
I have a specific clientlib ready with "critical CSS" that I would like to add to a page template in <style> tags, per Google's performance recommendations on a high-traffic e-Commerce site.
Problem:
We all know how to add a file reference in HTL:
<sly data-sly-use.clientlib="/libs/granite/sightly/templates/clientlib.html" data-sly-call="${clientlib.css # categories='template.noncritical'}"/>
but how would I output plain generated CSS styles on the page via HTL? Is there some other HTL property I could use?
I want this:
<style>
/* contents of AEM clientlib CSS here */
</style>
Tried:
I have Googled, searched StackOverflow, and looked in the AEM docs about clientlibs, but haven't found anything about inlining styles, except to
use a third-party script to inline critical CSS. (don't want to do)
modify HTML Library Manager OSGi configuration to inline all styles by default (don't want to do)
I am looking for something AEM-native that can be turned "on" or "off" in HTL. Thanks for reading and offering any solutions you may have.
You can try https://github.com/dmantsevich/aem-critical-css
It will generate CSS files and "integrate" with AEM. You can use it for extract small component CSS.
Some features:
CSS will be loaded only, if component presents on the page
Supports 2 injection types: <style /> and <link />
Supports less, css, scss.
CSS will be injected only once
Example:
MyComponentTemplate.html
<sly data-sly-use.aemCriticalCSS="${'./_aem-critical-css.js'}"
#aem-critical-css="my-component/my-component.scss">${aemCriticalCSS.inject # context="unsafe"}</sly>
Where my-component/my-component.scss is a path to css (related to ui.frontend/src/ folder). We used it on several projects and it helps to improve rendering performance. (path can be configured)
You can use the Core Components functionality https://experienceleague.adobe.com/docs/experience-manager-core-components/using/developing/including-clientlibs.html?lang=en#inlining
<style type="text/css"
data-sly-use.clientlibs="${'com.adobe.cq.wcm.core.components.models.ClientLibraries' # categories='wknd.base'}">
${clientlibs.cssInline # context="unsafe"}
</style>

Keeping CSS out of JS in Angular 2/Angular-CLI

By default, Angular 2 compiles the CSS into JavaScript, especially when using WebPack as in Angular-CLI. I would rather this not happen for a couple of reasons.
The first reason is that when I'm developing, I find it really helps to be able to see in the developer tools exactly what style sheet a specific style rule was coming from and what line number it was on. The second reason is that I think compiling CSS into the code kind of misses the point of good CSS, which is that you can apply a different style sheet and have an entirely different look and feel with the same markup.
Is there a flag somewhere that I can set to leave the CSS in .css files, where IMO it belongs?
This is the whole point of encapsulated components.
A component should have it's own styles encapsulated with it so it can be shipped with the styles.
Imagine you want to publish one of your components to be used by others, shouldn't it have its own styles with it ?
That means Angular needs a way to link those css to the component , thus seperates them into chunks and injects them into head tag.
To solve your problem though , you have couple of options :
1- Not using the Emulated Encapsulation :
Components by default have a property called encapsulation which is set to Emulated , you need to change it to None:
#Component({
encapsulation:ViewEncapsulation.None
})
Then , you can put all you css in the head tag your self like you'd do with a normal html page.
2- If the problem is theme ing , you can make your component themeable .
You can have a theme attribute for your component and then based on that change the styleing :
#Component({
selector:'my-component',
styles:[
`
:host{
[theme="blue"]{
change what ever you want :
h1{
color:blue;
}
}
}
`
]
})
And then , using this component would be like :
<my-component [attr.theme]='"blue"'></my-component> // would be blue theme
<my-component></my-component> // would be default
Go to your base Html file(where the root module, main app is injected) and link the CSS stylesheets in your header section.
Webpack will not include it in it's compiled/combined css file which is injected into the page. The css file will still be included at run time in the browser.
<html>
<head>
<base href="/">
<meta charset="utf-8">
<title>dummy</title>
<meta name="viewport" content="width=device-width">
//was not injected/modified by webpack
<link rel="apple-touch-icon" sizes="57x57" href="app/images/apple-icon-57x57.png">
//webpack's injected this below from other components's imported/inline css rules
<link href="index-c2cacb5fa3dfbca6116f4e4e63d5c3c7.css" rel="stylesheet"></head>
With angular-cli 1.6.5 you can do this:
ng serve --extract-css
You will still have the style-encapsulation features, but devtools will now point to the component css source file.
I use the angular-cli as well (v1.0.0-beta.22). When I am ready to build for production I run the following command:
ng build -prod -aot
This generates all my production-ready files (bundled, tree-shaken and minified etc). Of particular note is that it will generate two versions of the style sheets.
One in js:
styles.b2328beb0372c051d06d.bundle.js
And another version is plain css:
styles.4cec2bc5d44c66b4929ab2bb9c4d8efa.bundle.css
I run some post-processing on the css file with gulp and use the css version for my production build. I am not sure if the same holds true for lazy loading (where the cli will produced different chunks), but it works for sure when lazy loading is not being used (I haven't launched a production-ready project yet with lazy loading).
I also tried a build with JiT compilation:
ng build -prod
It also produced the raw/minified version of the css style sheet.
Now, I know for sure the folowing does NOT work:
ng build
This will produce all the css embedded within js file, styles.bundle.js.
Since you want to use the raw css file during development, the only workaround I can think of is that you run ng build -prod in order to get the css file. Copy/paste this manually into your assets folder. Run "format" on the file to un-minify the file. Then do a normal build with a modified index.html file referencing your raw css file, and removing the styles.bundle.js script reference. Not pretty, but it might work.
Put a wrapper class in html example-
<div class="component-1-wrapper">
all yout html here inside component-1-wrapper
</div>
Structure your sass(scss) in the following way. Since your styles are wrapped inside component-1-wrapper, therefore it will apply only to component-1-wrapperclass
.component-1-wrapper{
// all the styles for component-1 here
.class-hello{
// styles
}
}
You can compile your css with sass and put all the css(seperated by modules) in seperate folder.Start the filenames by _, sass can import them:
You can refer your styles-main.scss in app.ts file
#component({
styleUrls:['styles/styles-main.scss']})
The style-sheets will be structured this way and individual component's class styles will be applied to particular component since there is a wrapper class in html
Hope it helps!!!!!!

Basic HTML: External Stylesheet not linking

Just starting up a new HTML project and learning as I go, but I can't seem to figure out why my code isn't linking up. I'm trying to make my picture 100% width of the screen, and I'm realizing that my code just isn't lining up.
Any advice please?
This is my HTML:
<!DOCTYPE html>
<html>
<head>
<title>liz project</title>
<LINK rel="stylesheet" type="text/css" href="stylesheet.css" media="screen">
</head>
<body>
<h1>my first project</h1>
<p> welcome to the best site on the planet woohoo <br>
<img class="bg" src="http://blissmakedesign.com/wp-content/uploads/2012/11/livingroom1.jpg"> </p>
This is my CSS:
h1 {font-family: arial; color: red }
.bg {width: 100%; margin-right: auto; margin-left: auto }
Super basic, just started. Thanks so much!
I would recommend you to learn about using the file path.
quick reminder about file path
Starting with "/" returns to the root directory and starts there
Starting with "../" moves one directory backwards and starts there
Starting with "../../" moves two directories backwards and starts
there (and so on...)
To move forward, just start with the first subdirectory and keep
moving forward
So, make sure your file path is in correct direction.
You've got pretty much everything right there, like others have said it's going to be something like the CSS file just can't be found. This could be maybe because it's inside a folder and not at the root of your HTML file?
In this case, you would just need to change the link to your CSS file to reflect the folder it's in
<link rel="stylesheet" type="text/css" href="/[folder name]/stylesheet.css">
Note I have removed media="screen" as generally, for a basic tutorial, you wouldn't really need it so I wouldn't worry about it.
Also note at the start I've used lowecase for link. I don't know if this was causing your issues, but it's worth trying to stick with lowercase for everything, unless you need uppercase.
And one last point, I'm not sure you really need margin-left:auto and margin-right:auto as your image is classed to take up 100% of the width, so there won't be any margins available. You could remove those declarations in your CSS file if you wish.
Are you able to show us a brief example of how your files and folders are layed out?
I agree with Lee and C-link Nepal. It's probably a path error, so make sure your stylesheet is in the same directory as your html page. In the future, you can inspect a page with issues on your browser by right clicking on an element and selecting "Inspect Element" or something similar. In the inspection pane you can check if any files weren't found, which may point you in the right direction.

Less css background image not found when static files are served off a sub URI

For those that are interested I'm running a Django 1.3 setup making use of the lovely static files integration and less.js.
The issue I am running into is this:
In my HTML I have:
<link rel="stylesheet/less" type="text/css" href="{{ STATIC_URL }}less/style.less">
<script src="{{ STATIC_URL }}js/less.js" type="text/javascript"></script>
In this case STATIC_URL is /static/ so when the HTML is processed the links become /static/less/style.less and /static/js/less.js respectively.
Now in my LESS file I have the following (simplified) code:
body {
background: url('../img/bkgnd.png');
}
The problem is that LESS to me appears to deal with this stupidly, unless i'm being stupid, just as likely :-)
The less JS file is grabbed as http://localhost:8000/static/js/less.js and then grabs the css file at http://localhost:8000/static/less/style.less
Now I would expect that less should know the location of style.less and therefore when compiling to CSS would look for the background image at http://localhost:8000/static/less/../img/bkgnd.png which obviously is just http://localhost:8000/static/img/backgnd.png
Instead however it seems to ignore the location and just look for the background image at http://localhost:8000/img/backgnd.png.
Does anyone have an explanation why this happens?
I have added a temporary fix by setting a javascript variable containing the static url and prepending it to the image url in the css file. This is fine for development, but I want to compile the code using lessc in production and less doesn't allow me to pass in javascript variables as far as I can see (which would be nice).
Any help would be greatly appreciated, this is driving me crazy :-)
It's looking for a img file in relations to the document you are viewing, not in relation to the css file.
So change your css to this:
body {
background: url('/static/img/bkgnd.png');
}

Why is my CSS file overridden with another stylesheet?

I developed an application, and I used header and footer from another app. I created a separate style sheet for my app, called TestStyleapp.css. When I run my new application, the stylesheet I used from the other app is overriding my new CSS file.
Is there a way to include/reference the Teststyleapp.css (I tried calling it last) other than using !important in front of all the elements in teststyleapp.css?
When I use FireBug, I do not see Teststyleapp.CSS at all.
Even if it is LAST, if it is NOT more SPECIFIC (the other page items are more specific) it will not override what is above it in the stack.
Example:
div .myclass (background-color: red);
other (yours has)
.myclass(background-color:green);
you still see red.
<link rel="stylesheet" href="TestStyleapp.css" type="text/css" media="screen" />
It should be linked as such, between the head tags. Make sure the case is correct. I like using all lowercase and _ as a word separator. Just my personal style.
First, get the .css file to show in the NET tab in Firebug and we'll take it from there.

Resources