JavaFX’s CSS Function url() accepts an address, and converts it into a <uri>, which Java uses to load the specified resource.

The url() function accepts addresses in the following forms:

  • HTTP/WWW web-addresses
  • Local file address relative to the address of the current CSS file
  • Local file paths relative to the classpath (See behaviour note: limited functionality)
  • Fully-qualified <address> with a specified scheme

It can be used to load resources inside a CSS file, as well as using inline styles (although for inline styles, please see the syntax note below as it has more limited functionality).

The JavaFX CSS function url() is responsible for loading most resources in via CSS:

Behaviour

  • Quotes in the <address> value: The url() function accepts an <address> with unquoted text, single quotes or double quotes url(www.example.com/resources/image.png); url('www.example.com/resources/image.png'); url("www.example.com/resources/image.png")
  • Whitespace: in the <address> value will result in an error with the warning Illegal character in path.
    Whitespace should be encoded using the unicode character %20, so: url("../img/Filename With Spaces.png"); should be encoded as: url("../img/Filename%20With%20Spaces.png");

Syntax

/*  HTTP/WWW web-addresses  */
url(http://example.com/image.png)
url("http://example.com/image.png")
url('http://example.com/image.png')

/*  Local file address relative to the address of the current CSS file  */
url(/com/edencoding/EdenCodingIcon.png);

/*  Local file paths relative to the classpath (See behaviour note: limited functionality)  */
url(/EdenCodingIcon.png);

/*  Fully-qualified <address> with a specified scheme  */
url(file:/C:/project/target/classes/com/edencoding/css/EdenCodingIcon.png)

Warning on Loading Inline Styles

In theory, the url() function should enable developers to load resources using inline styles inside your Java code:

AnchorPane pane = new AnchorPane();
pane.setStyle(
    "-fx-background-image: url('/com/edencoding/img/EdenCodingIcon.png');"
);

However, I’ve never got this to work. The JavaFX CSS interpreter still struggles to resolve paths that begin with a leading slash “/” character if they attempt to resolve the path by navigating from the classpath.

For reliably loading inline styles, you’ll need to use a hybrid approach with the Java ClassLoader.

Solution

The JavaFX CSS url() function does accept fully-qualified addresses with a scheme element.

Thus, to load a resource as an inline style, the only way I’ve found to make this work is to resolve the URL using getClass().getResource(location).toExternalForm() and then to pass this fully-qualified address into the inline style.

AnchorPane pane = new AnchorPane();

//Create URL String
String address = getClass().getResource("/com/edencoding/img/EdenCodingIcon.png").toExternalForm();

pane.setStyle("-fx-background-image: url(" + address + ");");

That way you get to use the ClassLoader’s better URL-resolution, and you still get to use an inline style getClass().getResource(location).toExternalForm() to create the correct <address> for the stylesheet.

pane.getStylesheets().add(getClass().getResource("/com/edencoding/css/styles.css").toExternalForm());

Values

The JavaFX CSS interpreter isn’t a fully-compliant CSS Interpreter, nor does it support all CSS-values you might expect for the related CSS property.

url() can have the following values:

ValueDescription
<address>A hierarchical URI of the form [scheme:][//authority][path].If the address does not have a [scheme] element, it is assumed to only have a [path] component.

Example

The JavaFX CSS function url() can be used to load resources into an application.

CSS:

.content{
    -fx-background-image: url("../img/EdenCodingIcon.png");
    -fx-background-size: 50, 50;
    -fx-background-position: center, center;
    -fx-background-repeat: no-repeat;
}

.label{
    -fx-background-color: #fcc200;
    -fx-font-weight: bold;
}

FXML:

<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<VBox alignment="CENTER" prefHeight="250.0" prefWidth="300" spacing="10.0" stylesheets="@../css/styles.css" xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1">
    <Label alignment="CENTER" maxWidth="300" text="URL Example" />
    <AnchorPane fx:id="thibble" prefHeight="200.0" prefWidth="200.0" styleClass="content" />
    <padding>
        <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
    </padding>
</VBox>

See Also

Check out my guide on loading resources into JavaFX for a comprehensive walkthrough in Java, CSS and FXML