1

My idea is to have different files (either .css or .html) containing all the rules for a specific theme and load theme dynamically changing the look&feel of the Polymer application at runtime.


I have found pretty useful this method described here by Polymer itself with using custom style at document level (using .html files)

Frequently you want to define custom property values at the document level, to set a theme for an entire application, for example. Because custom properties aren't built into most browsers yet, you need to use a special custom-style tag to define custom properties outside of a Polymer element. Try adding the following code inside the tag of your index.html file

Basically we define an my-theme.html, that defines variables used in the application style, that looks like this:

<style is="custom-style">
      /* Define a document-wide default—will not override a :host rule in icon-toggle-demo */
      :root {
        --icon-toggle-outline-color: red;
      }
      /* Override the value specified in icon-toggle-demo */
      icon-toggle-demo {
        --icon-toggle-pressed-color: blue;
      }
      /* This rule does not work! */
      body {
        --icon-toggle-color: purple;
      }
 </style>

And I import it in my index.html file.


And then I found on stackoverflow this method to change the style dynamically.

HTML

 <link type="text/css" rel="stylesheet" media="all" href="../green.css" id="theme_css" />

JS

document.getElementById('buttonID').onclick = function () { 
    document.getElementById('theme_css').href = '../red.css';
};

The problem here is that the file is a rel: stylesheet and changing its href causes the browser to reload the file and apply the changes, wherease in my case changin the href of the html import doesn't leed to the same effect.

Is there a way to get this to work as I want? Is there a better solution to achieve my goal?

Community
  • 1
  • 1
Incio
  • 355
  • 1
  • 13

2 Answers2

1

Definitely, you have to use custom CSS properties and mixins. If you style your website correctly it will be very easy to swap to different theme.

You can change Custom CSS property value by doing:

this.customStyle['--my-toolbar-color'] = 'blue';

Every css rule that is using var(--my-toolbal-color) will change to color blue, once you call one ore function:

this.updateStyles();

which tells Polymer, hey i just updated styles can you re-render css rules..

Hope this helps and it's the thing you were looking for. Because what you described was too much complicated i think.

Kuba Šimonovský
  • 2,013
  • 2
  • 17
  • 35
  • Hi, thanks for the answer. I had read something about this approach of changing the CSS properties by code and calling updateStyles. But in this way if I had a button "change to red theme" I will have to hard code the changes (example: `this.customStyle['--my-toolbar-color'] = 'red';`) which is what I wanted to avoid creating a my-theme.html containing all my properties. I would like to have a red-theme.html from which I load my new properties. Impossible to do? – Incio Apr 07 '17 at 09:45
  • @Incio well i am not sure if it is possible. I have no idea how to solve it like you want.. :/ i tried now few test cases but none of them were successfull. Propably someone who know much more about Polymer could help – Kuba Šimonovský Apr 07 '17 at 09:59
  • Thanks Kuba. I am probably trying to do something impossible. Changing approach and using yours, I am thinking of creating mixins in my-theme.html and applying them programmatically. In this way they will be still defined in my file and not hardcoded in the code. Could that be a solution? – Incio Apr 07 '17 at 10:07
  • i think that it could be. you have to try it. I wanted to make my application using more themes too so i am interested if you are able to implement it – Kuba Šimonovský Apr 07 '17 at 10:12
0

Not really happy with it but that work :

<link rel="import" href="my-css.html">

<dom-module id="my-app">
  <template>
    <style include="my-css"></style>
    <button class="btn-primary-dark">Dark button</button>
    <button class="btn-primary-light">Light button</button>
    <button class="btn-primary-default">Default button</button>
    <br><br>
    <button on-click="setTheme1">Set theme 1</button>
    <button on-click="setTheme2">Set theme 2</button>
  </template>
  <script>
    class MyApp extends Polymer.Element {
      static get is() { return 'my-app'; }

      // Dynamicaly change vars
      setTheme1() {
        Polymer.updateStyles({
          '--dark-primary-color' : '#689F38',
          '--default-primary-color' : '#8BC34A',
          '--light-primary-color' : '#DCEDC8',
          '--text-primary-color' : '#212121'
        });
      }
      setTheme2() {
        Polymer.updateStyles({
          '--dark-primary-color' : '#1f8f37',
          '--default-primary-color' : '#818bbf',
          '--light-primary-color' : '#f0e82f',
          '--text-primary-color' : '#333333'
        });
      }

    }
    window.customElements.define(MyApp.is, MyApp);
  </script>
</dom-module>

my-css.html

<dom-module id="my-css">
  <template>
    <style>
      .btn-primary-dark {
          background-color: var(--dark-primary-color);
          color: var(--secondary-text-color);
      }
      .btn-primary-light {
          background-color: var(--light-primary-color);
          color: var(--secondary-text-color);
      }
      .btn-primary-default {
          background-color: var(--default-primary-color);
          color: var(--secondary-text-color);
      }
    </style>
  </template>
</dom-module>
Camille
  • 2,439
  • 1
  • 14
  • 32