简体   繁体   中英

Changing CSS Themes

I've made a nice little application using java and javafx and have recently started to style it with CSS. I thought of the idea to have separate themes (one yellow, one blue, etc.) but then realized I know of no good way to do this. In java if I wanted something to change I'd simply change the value of a variable but in CSS I don't think that's possible. So to my question, what is the best way to change themes by the click of a button (inside the application)? Is it as I have feared, do I have to make a separate style sheet for every theme and switch between style sheets? Thank you for any help.

The correct approach in JavaFX-CSS is to use color variables (and maybe the derive/ladder functions). So you most likely have 3 CSS-Files:

  • style.css - with the selectors for your components and references to color variables
  • theme-default.css - with the default color variables
  • theme-blue.css - with your blue color variables

Your style.css could look like this:

.button {
  -fx-background-color: my-button-background-color;
}

And your theme-default.css would be

.root {
  my-button-background-color: #f00;
}

And your theme-blue.css would be:

.root {
  my-button-background-color: #00f;
}

If you want to flip themes you'd simple remove the theme-default.css from the Scene and add the theme-blue.css (switching back you'd do the opposite) in pseudo code:

Scene s = ...
s.getStylesheet().addAll( "style.css", "theme-default.css" );

// ...
button.setOnAction( e -> {
   if( s.getStylesheet().contains( "theme-default.css" ) ) {
     s.getStylesheet().remove("theme-default.css");
     s.getStylesheet().add("theme-blue.css");
   } else {
     s.getStylesheet().remove("theme-blue.css");
     s.getStylesheet().add("theme-default.css");
   }
} );

Isn't the great power about CSS style sheets that you can just use them interchangeably? Using seperate themes just by replacing the CSS file?

Anyhow, if you'd like to change the styles of your components at runtime, as I assume from:

Is it as I have feared, do I have to make a separate style sheet for every theme and switch between style sheets?

You can re-style every component at runtime. Every object in JavaFX extends from Node . Which in turn implements Styleable . Which gives you multiple styling options.

In case you DO want to change entire stylesheets, you can add and remove style sheets on your scene as well.

I know two ways to do what you need:

1.- Change css link from a default theme default.css to a color theme blue.css . 2.- Change a class that modify the look and feel from the main container.

The 1st way: Change css link

You only have to create two css files that will change only in the color.

Live example: http://seantheme.com/color-admin-v1.9/admin/html/index_v2.html

Click the settings icon (cog) to view the Color theme controller.

The 2nd way: Add a class to the main container

Let's say that you have 3 color themes for a website, you have use one class .red or .red-theme that will be added to the main container as it changes every selector color underneath.

EX: I made a live test for a clearer answer, but I will use a contextual state for a box with information that will change depending on it's status, so we will have .warning , .info and .success state and regular theme which class is .post-wrapper .

/* General Classes
* First we will give theme bases that include padding, margin, font-size 
* or default colors, etc.
*/
.post-wrapper{ /* Regular theme */
  padding: 15px;
  margin-bottom: 30px;
  border: 1px solid #ccc;
  box-shadow: 2px 2px 2px rgba(0,0,0, 0.2);
  border-radius: 5px;
}

And our HTML will look like:

<article class="post-wrapper">
  ...
</article>

Then we set our color themes:

/* CSS THEMES 
* Here we will set every color that will change with our current state.
* It could change colors, widths, font-sizes, :hover, or anything that we need
* to be changed.
*/
.warning{
  color: #9A2C2C;
  background-color: #FFE2E2;
  border-color: #9A2C2C;
}

.info{
  color: #2D5E7D;
  background-color: #CEEAF1;
  border-color: #2D5E7D; 
}

.success{
  color: #2D7D36;
  background-color: #CEF1D2;
  border-color: #2D7D36;
}

And our HTML will change depending to the state:

<article class="post-wrapper info">
  ...
</article>

<article class="post-wrapper success">
  ...
</article>

<article class="post-wrapper warning">
  ...
</article>

Live example: https://jsfiddle.net/xwazzo/Ls9f313g/2/

I will leave here a bootstrap example that shows Contextual Colors: http://getbootstrap.com/css/#helper-classes-colors

Conclusions:

I like the 2nd option and have use it more because I haven't found a way to create multiple css files with different colors in an easy and fast way and website weight doesn't increase too much.

I suppose that the 1st way is the best because you will have fewer classes on your style sheet and will save few KB.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM