The -fx-background-image CSS property allows developers to specify one or more images as the background of a any Region. As all controls and layout panes extend the Region class, the -fx-background-image is a powerful property for styling your scene. The -fx-background-image accepts one or more <uri-string> objects separated by commas.

#my-class{
  -fx-background-image: url(www.example.com/image-to-use.png);
}

The default behaviour of the -fx-background-image is to:

  • Position the image in the top left of the Region
  • Tile the image, repeating in both the X- and Y-axes, if the image is too small to occupy the entire area

This may not be the desired behaviour. To change this default behaviour, developers can additionally set -fx-background-position and -fx-background-repeat properties. To change the size of images, this can be set using -fx-background-size.

Usually, using -fx-background-image, -fx-background-position, -fx-background-size, and -fx-background-repeat together will yield the most visually appealing results.

Behaviour

Render order: The -fx-background-image can be used to define one or more background images. These are always rendered above background fills (colors and gradients).

Multiple Images: Where more than one images is used, these are rendered in order from first to last, with the last therefore on top.

Defining images: Images can be defined as both web-resources and file-locations, and where multiple images are used, a mixture of web-based resources and file-based resources.

-fx-background-image: url("../img/Image1.png"), url(https://edencoding.com/EdenCodingIcon.png);

Errors: Images that cannot be loaded will throw an error, but will not block execution of the program, nor will they stop the rendering of other images.

com.sun.javafx.css.StyleManager$ImageCache getCachedImage
WARNING: Error loading image: https://edencoding.com/EdenCodingIcon.png

Syntax

/* URL web address - with or without quotes*/
-fx-background-image: url(https://edencoding.com/EdenCodingIcon.png);
-fx-background-image: url('https://edencoding.com/EdenCodingIcon.png');
-fx-background-image: url("https://edencoding.com/EdenCodingIcon.png");

/* Relative file addresses (same folder) */
-fx-background-image: url("EdenCodingIcon.png");

/* Relative file addresses (manually navigating to folder) */
-fx-background-image: url("../img/EdenCodingIcon.png");

/* Multiple images */
-fx-background-image: url("../img/Image1.png"), url(https://edencoding.com/EdenCodingIcon.png);

Animating Background Images

CSS animation in current JavaFX CSS versions is not supported. It can be achieved, however, using a combination of Java code and JavaFX animation in the setting of in-line styles. This can create very visually appealing backgrounds from a very simple scene graph.

In this example, six images of a cityscape are layered (from bottom to top) in CSS, and then animated in the JavaFX controller code to simulate movement. A single region is used as the root node with no need for layered image views or canvases.

FXML:

<VBox fx:id="content" styleClass="content" alignment="TOP_CENTER" stylesheets="@../css/styles.css"
      xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1"
      fx:controller="controllers.ExampleController">
</VBox>

CSS:

.content{
    -fx-background-size: contain, contain, contain, contain, contain, contain;
    -fx-background-position: bottom, bottom, bottom, bottom, bottom, bottom;
    -fx-background-repeat: repeat-x, repeat-x, repeat-x, repeat-x, repeat-x, repeat-x;

    -fx-background-image:
        url("../img/cityscape/layer_06_1920x1080.png"),
        url("../img/cityscape/layer_05_1920x1080.png"),
        url("../img/cityscape/layer_04_1920x1080.png"),
        url("../img/cityscape/layer_03_1920x1080.png"),
        url("../img/cityscape/layer_02_1920x1080.png"),
        url("../img/cityscape/layer_01_1920x1080.png");
}

Java Controller code:

public class ExampleController {

    public Region content;

    public void initialize() {
        DoubleProperty xPosition = new SimpleDoubleProperty(0);
        xPosition.addListener((observable, oldValue, newValue) -> setBackgroundPositions(content, xPosition.get()));

        Timeline timeline = new Timeline(
                new KeyFrame(Duration.ZERO, new KeyValue(xPosition, 0)),
                new KeyFrame(Duration.seconds(200), new KeyValue(xPosition, -15000))
        );
        timeline.play();

    }

    void setBackgroundPositions(Region region, double xPosition) {
        String style = "-fx-background-position: " +
                "left " + xPosition/6 + "px bottom," +
                "left " + xPosition/5 + "px bottom," +
                "left " + xPosition/4 + "px bottom," +
                "left " + xPosition/3 + "px bottom," +
                "left " + xPosition/2 + "px bottom," +
                "left " + xPosition + "px bottom;";

        region.setStyle(style);
    }
}

Result:

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.

-fx-background-image can have the following values:

ValueDescription
<uri-string>A valid URI string pointing to an online, or local file.
<uri-string> [, <uri-string>]+]Multiple images specified in a comma-separated list

Example

-fx-background-image can be used to set the background image on a Region node

CSS:

.content{
    -fx-background-image: url('../img/EdenCodingIcon.png');
}

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

FXML:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.layout.AnchorPane?>

<AnchorPane prefHeight="250.0" prefWidth="300.0" xmlns="http://javafx.com/javafx/10.0.2-internal"
stylesheets="@../css/styles.css">
    <Label alignment="CENTER"
           text="Title Text"
           AnchorPane.leftAnchor="10"
           AnchorPane.rightAnchor="10"
           AnchorPane.topAnchor="10.0">
      <font>
         <Font name="System Bold" size="12.0" />
      </font>
    </Label>
   <AnchorPane styleClass="content"
               style="-fx-background-color: springgreen;"
               AnchorPane.bottomAnchor="10.0"
               AnchorPane.leftAnchor="10.0"
               AnchorPane.rightAnchor="10.0"
               AnchorPane.topAnchor="36.0" />
</AnchorPane>

See also: