Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to style inner elements of custom Polymer element using external styles?

Unable to style an element using Shadow DOM with Polymer 1.x or 2.x. Consider the following custom element in Polymer 2.0:

<link rel="import" href="../polymer/polymer.html">

<!--
`semantic-ui-button`


@demo demo/index.html
-->

<dom-module id="polymer-button">
  <template>
    <div class$="button {{size}}">{{label}}</div>
  </template>

  <script>
    class MyElement extends Polymer.Element {
      static get is() {
        return 'polymer-button';
      }
      static get properties() {
        return {
          label: {
            type: String,
            value: 'polymer-element'
          },
          size: { type: String }
        };
      }
    }

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

in the demo:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, minimum-scale=1, initial-scale=1, user-scalable=yes">

    <title>polymer-element demo</title>

    <script src="../../webcomponentsjs/webcomponents-lite.js"></script>

    <link rel="import" href="../../iron-demo-helpers/demo-pages-shared-styles.html">
    <link rel="import" href="../../iron-demo-helpers/demo-snippet.html">
    <link rel="import" href="../polymer-element.html">

    <style is="custom-style" include="demo-pages-shared-styles"></style>
    <style>
      body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; }
      .button {
        background: #ccc;
        border-radius: 4px;
        color: #444;
      }
      .button.big {
        font-size: 1rem;
        padding: 6px;
      }
    </style>
  </head>
  <body>
    <div class="vertical-section-container centered">
      <h3>Basic polymer-element demo</h3>
      <demo-snippet>
        <template>
          <polymer-button label="Demo"></polymer-button>
        </template>
      </demo-snippet>
    </div>
  </body>
</html>

The styles defined in the demo for .button and .button.big are not applied to the shadow element; however, in Polymer 1.x the styles are applied if we use ShadyDOM:

<link rel="import" href="../polymer/polymer.html">

<!--
`polymer-button`


@demo demo/index.html
-->

<dom-module id="polymer-button">
  <template>
    <div class$="button {{size}}">{{label}}</div>
  </template>

  <script>
    Polymer({

      is: 'polymer-button',

      properties: {
        label: { type: String }
      },

    });
  </script>
</dom-module>

is there a way to select/style these inner elements using external styles?

Below is a visual representation of what I said above in order of appearance:

  1. Polymer 1.x using Shadow DOM
  2. Polymer 1.x using ShadyDOM
  3. Polymer 2.x

differences

like image 364
djthoms Avatar asked Dec 15 '22 00:12

djthoms


2 Answers

To enable styling points, use CSS variables/mixins.

  1. Add a <style> tag to your element's template:

    <dom-module id="polymer-button">
      <template>
        <style>
          .button {
            @apply --my-button-mixin;
          }
          .button.big {
            @apply --my-button-big-mixin;
          }
        </style>
        ...
      </template>
    </dom-module>
    
  2. Specify the mixin in a container element:

    <dom-module id="x-foo">
      <template>
        <style>
          polymer-button {
            --my-button-mixin: {
              background: red;
              color: white;
            };
          }
        </style>
        <polymer-button label="Red button"></polymer-button>
      </template>
    </dom-module>
    

    ...or in index.html:

    <body>
      <custom-style>
        <style>
          polymer-button {
            --my-button-mixin: {
              background: red;
              color: white;
            };
          }
        </style>
      </custom-style>
      <polymer-button label="Red button"></polymer-button>
    </body>
    

codepen (Polymer 1)

codepen (Polymer 2)

like image 128
tony19 Avatar answered May 04 '23 11:05

tony19


Alternately, you can add a <style> element with an @import url rule inside your custom element <template> that will import an external stylesheet:

<template>
    <style>
         @import url( external.css )
    </style>
    <div class$="button {{size}}">{{label}}</div>
</template>

In your CSS stylesheet (example: external.css) you can define standard CSS:

.button {
    background: #ccc;
    border-radius: 4px;
    color: #444;
}
.button.big {
    font-size: 1rem;
    padding: 6px;
}
like image 34
Supersharp Avatar answered May 04 '23 13:05

Supersharp