Jiew Meng
Jiew Meng

Reputation: 88367

Polymer Styling Child Components

I am trying to style my child components. Isit wrong to put the style in a parent component? It appears that does not work.

I put the style for .card-page in the top level element (containing expenses-module where I use it)

<dom-module id="expenses-app">
  <template>
    <style>
    ...
    .card-page {
      display: block;
      width: 100%;
    }
    </style>

    <app-drawer-layout>
      <app-header-layout>
        ...

        <iron-pages selected="{{routeData.view}}" attr-for-selected="name">
          <dashboard-module name="dashboard" route="{{subroute}}"></dashboard-module>
          <expenses-module name="expenses" route="{{subroute}}"></expenses-module>
          <settings-module name="settings" route="{{subroute}}"></settings-module>
        </iron-pages>
      </app-header-layout>
    </app-drawer-layout>
  </template>

In expenses module,

<paper-card heading="Expenses" class="card-page">...
</paper-card>

Seems like if I move the styles into expenses-module it works.

Upvotes: 4

Views: 3696

Answers (1)

Tomasz Pluskiewicz
Tomasz Pluskiewicz

Reputation: 3662

You cannot directly style elements inside custom element from their parents like that, because Polymer processes the style within <dom-module> and will apply styles only to direct child members. It will not descend into child custom elements.

In other words, standard CSS selectors will only work within the scope of the declaring component. Both in Shadow and Shady DOM.

For your styles to work with nested elements, you should use CSS mixins and properties. All PolymerElements and many 3rd party elements will come with such styling extension points. The naming usually follow the convention, where the main mixin is called same as the element itself. Additionally, there may be more specific mixins and properties, which style only parts of the element. <paper-card> docs for example lists --paper-card mixin, --paper-card-content mixin, --paper-card-header-color and more.

If you want to better control the styling of elements you use, you would want to create your own CSS mixins/properties and @apply() them to selected elements. See how in the example below --my-elem-card-page applies only to one of the two paper cards.

<!DOCTYPE html>
<html>
<head>
  <base href="https://polygit.org/components/">
  <script src="webcomponentsjs/webcomponents-lite.min.js"></script>
  <link href="polymer/polymer.html" rel="import"/> 
  <link href="paper-card/paper-card.html" rel="import"/>
</head>

<body>
  <my-wrapper></my-wrapper>
  
  <dom-module id="my-elem">
    <template>
      <style>
        .card-page {
          @apply(--my-elem-card-page);
        }
      </style>
      
      <paper-card heading="my-elem specific style" class="card-page">
        <div class="card-content">
          Content here
        </div>
      </paper-card>
      <paper-card heading="Default style" class="unstyled-page">
        <div class="card-content">
          Content here
        </div>
      </paper-card>
    </template>
  </dom-module>
  
  <dom-module id="my-wrapper">
    <template>
      <style>
        # will be ignored
        paper-card {
          width: 200px;
        }
        
        my-elem{
          --paper-card: {
            color: blue;
            display: block;
          }
        }
        
        my-elem {
          --my-elem-card-page: {
              color: red;
          }
        }
      </style>
      
      <my-elem></my-elem>
    </template>
  </dom-module>
  
  <script>
    Polymer({
      is: 'my-elem'
    });

    Polymer({
      is: 'my-wrapper'
    });
  </script>

</body>
</html>

Upvotes: 4

Related Questions