Search code examples
htmlcsspolymerpolymer-1.0css-variables

How to use CSS variable in same rule that declares it


In my custom element's definition, I have the following code:

<dom-module id="dom-element">
  <style>
    p {
      --test: brown;
      color: var(--test);
    }
  </style>
  <template>
    <p>I'm a DOM element. This is my local DOM!</p>
  </template>

  <script>
    Polymer({
      is: "dom-element"
    });
  </script>

</dom-module>

However, the CSS custom property isn't working. Polymer just turns this:

p {
  --test: brown;
  color: var(--test);
}

into this:

p {
  color: ;
}

But I want the output to be:

p {
  color: brown;
}

The demo can be found here: http://plnkr.co/edit/ogMVPKNvc7SYISomWPWm?p=preview

If I don't use Polymer, and create the custom element in pure JavaScript, the CSS custom property works as expected.

I have searched Google, but didn't find something related. What's the problem here? How can I use the CSS custom property with Polymer?


Solution

  • Polymer 1's CSS shim (enabled by default) apparently doesn't handle the CSS variable declaration in the same rule that uses it, so you'd have to move the declaration to :host in this scenario.

    <!-- inside dom-module's template -->
    <style>
      :host {
        --test: brown;
      }
      p {
        color: var(--test);
      }
    </style>
    

    HTMLImports.whenReady(() => {
      Polymer({
        is: 'x-foo'
      });
    });
    <head>
      <base href="https://polygit.org/polymer+1.7.1/components/">
      <script src="webcomponentsjs/webcomponents-lite.min.js"></script>
      <link rel="import" href="polymer/polymer.html">
    </head>
    <body>
      <x-foo></x-foo>
    
      <dom-module id="x-foo">
        <template>
          <style>
            :host {
              --test: brown;
            }
            p {
              color: var(--test);
            }
          </style>
          <p>Hello world</p>
        </template>
      </dom-module>
    </body>

    However, you can enable native CSS properties in Polymer with a global setting (useNativeCSSProperties) declared before importing polymer.html, which would allow your code to work as-is:

    <script>window.Polymer = {lazyRegister: true, useNativeCSSProperties: true};</script>
    <!-- import polymer.html here -->
    

    HTMLImports.whenReady(() => {
      Polymer({
        is: 'x-foo'
      });
    });
    <head>
      <script>window.Polymer = {dom: 'shadow', lazyRegister: 'max', useNativeCSSProperties: true};</script>
      <base href="https://polygit.org/polymer+1.7.1/components/">
      <script src="webcomponentsjs/webcomponents-lite.min.js"></script>
      <link rel="import" href="polymer/polymer.html">
    </head>
    <body>
      <x-foo></x-foo>
    
      <dom-module id="x-foo">
        <template>
          <style>
            p {
              --test: brown;
              color: var(--test);
            }
          </style>
          <p>Hello world</p>
        </template>
      </dom-module>
    </body>

    codepen