From the JavaFX CSS Reference Guide I know enough about the -fx-text-fill
property to use it.
Working on a larger JavaFX project that has recently been updated to JavaFX 16, I came across some CSS code that uses -fx-text-inner-color
to apparently achieve the exact same thing, that is changing the text color of (in my case) a TextField control.
Since I could not find any documentation on the second property, I decided to ask here.
Can someone explain the difference between those two properties, why might we need both of them, and when to prefer one over the other?
-fx-text-fill
is a CSS property that is defined for controls with text
properties (such as Labeled
and its subclasses, and TextInputControl
and its subclasses).
The property, as noted in the question, is listed in the JavaFX CSS Reference Guide.
-fx-text-inner-color
is not a property, but a looked-up color (essentially a CSS color variable) that is defined in the default stylesheet modena.css. It is used as the value of the -fx-text-fill
property for controls which have a background color set to -fx-control-inner-background
, namely "text boxes, password boxes, lists, trees, and tables".
Changing -fx-text-inner-color
at the root level will have the effect of changing the text color on all text boxes, password boxes, lists, trees, and tables.
Note that the default value of -fx-text-inner-color
is set to a color ladder, which depends on the value of -fx-control-inner-background
. Namely, when -fx-control-inner-background
is dark (less than 45% intensity), it is set to -fx-light-text-color
, when it is light (greater than 60% intensity, which it is by default), it is set to -fx-mid-text-color
, and otherwise it is set to -fx-dark-text-color
. The default values of these are white
, #333
, and black
, respectively.
The effect of these default settings is to get a text fill which always contrasts with the background; so if you change the value of -fx-control-inner-background
the text color will adjust automatically.
There are really two distinct approaches to defining a production-level style for an application:
Define the styles for all the controls you use in the application. In this approach, you'll set the properties on each control (or at least, the properties which are different to the default). This is more work, but creates a "stand-alone" style which is more likely to be robust in the future if the user has a JavaFX implementation with a new default stylesheet.
Tap into the default stylesheet modena.css
and change the values of the looked-up colors on which everything is based. This is much easier. You can go a long way just by changing the value of -fx-base
, from which most other looked-up colors are defined. Other key looked-up colors are
-fx-background
, used for the background color of windows and panes-fx-control-inner-background
, used for the background color of text boxes, lists, tables, and trees-fx-dark-text-color
, -fx-mid-text-color
, and -fx-light-text-color
, used to define the color ladders for text drawn over -fx-background
and -fx-control-inner-background
-fx-accent
(selection), -fx-default-button
, -fx-focus-color
, and -fx-faint-focus-color
Try creating an application and using
.root { -fx-base: black; }
as the stylesheet, with no other styles set anywhere. You should see a pretty effective "dark theme". You'd probably want to change a few other colors, particularly for selection and focus, but it will work well enough with just that change.
Note that if you use the approach of changing looked-up colors, instead of setting properties for all the controls individually, you are not robust to new default stylesheets. You can make this robust by explicitly setting your user agent stylesheet to MODENA
:
Application.setUserAgentStylesheet(Application.STYLESHEET_MODENA);