polymerpolymer-2.xcss-calciron-list

How to set the responsive width of Polymer component inside `<iron-list grid>`


Consider the following code, where <my-item> always has a fixed width of 200px inside <iron-list grid>

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Polymer Element Test Case</title>
  <!-- Load webcomponents-loader.js to check and load any polyfills your browser needs -->
  <script src="bower_components/webcomponentsjs/webcomponents-loader.js"></script>
  <link rel="import" href="bower_components/polymer/polymer-element.html">

  <link rel="import" href="bower_components/iron-list/iron-list.html">
</head>
<body>

  <h1>iron-list-grid-calc-issue</h1>
  <!-- Test case HTML goes here -->

  <test-case>
  </test-case>

  <dom-module id="test-case">
    <template>
      <iron-list items="[[items]]" grid>
        <template>
          <div>
            <!-- value: [[item.n]] -->
            <my-item data="[[item]]"></my-item>
          </div>
        </template>
      </iron-list>
    </template>
  </dom-module>

  <dom-module id="my-item">

    <template>
      <style>
        .content {
          width: calc(50% - 32px); /* Not working */
          width: 200px;
          height: 200px;
          line-height: 200px;
          text-align: center;
          border: 1px solid grey;
          box-sizing: border-box;
        }
      </style>

      <div class="container">
        <div class="content">
          data: [[data.n]]
        </div>
      </div>
    </template>
  </dom-module>

  <script>
    window.addEventListener('WebComponentsReady', function() {
      class TestCase extends Polymer.Element {
        static get is() {
          return 'test-case';
        }

        static get properties() {
          return {
            items: {
              type: Array,
              value: function() {
                let items = [];
                for (let i=0; i < 10; i++) {
                  items.push({
                    n: i,
                  });
                }

                return items;
              }
            },
          };
        }
      }

      class MyItem extends Polymer.Element {
        static get is() {
          return 'my-item';
        }

        static get properties() {
          return {
            data: Object,
          };
        }
      }

      window.customElements.define(TestCase.is, TestCase);
      window.customElements.define(MyItem.is, MyItem);
    });
  </script>
</body>
</html>

I intend to make <my-item> responsive by always showing 2 <my-item>s per row (which can be stretched) by setting the width of <my-item> with width: calc(50% - 32px). I noticed CSS calc() doesn't seem to work as expected.

How do I set the responsive width of a Polymer component inside <iron-list grid>?


Solution

  • Set the size of the item template's root container element (<div> in this case).

    <iron-list items="[[items]]" grid>
      <template>
        <div style="width: calc(50% - 32px); height: 200px"> <!-- root container element -->
          <my-item data="[[item]]"></my-item>
        </div>
      </template>
    </iron-list>
    

    <head>
      <base href="https://polygit.org/polymer+v2.3.1/components/">
      <script src="webcomponentsjs/webcomponents-loader.js"></script>
      <link rel="import" href="polymer/polymer.html">
      <link rel="import" href="iron-list/iron-list.html">
    </head>
    <body>
      <h1>iron-list-grid-calc-issue</h1>
      <test-case></test-case>
    
      <dom-module id="test-case">
        <template>
          <style>
            .item {
              width: calc(50% - 32px);
              height: 200px;
            }
          </style>
          <iron-list items="[[items]]" grid>
            <template>
              <!-- Set the size of the item template's root container,
                   which is this `div` element. -->
              <div class="item">
                <my-item data="[[item]]"></my-item>
              </div>
            </template>
          </iron-list>
        </template>
      </dom-module>
    
      <dom-module id="my-item">
    
        <template>
          <style>
            .content {
              /* NOTE: The item size is set in the item template
                 in `iron-list` */
    
              /*width: calc(50% - 32px);*/
              /*width: 200px;*/
              /*height: 200px;*/
              line-height: 200px;
              text-align: center;
              border: 1px solid grey;
              box-sizing: border-box;
            }
          </style>
    
          <div class="container">
            <div class="content">
              data: [[data.n]]
            </div>
          </div>
        </template>
      </dom-module>
    
      <script>
        window.addEventListener('WebComponentsReady', function() {
          class TestCase extends Polymer.Element {
            static get is() {
              return 'test-case';
            }
    
            static get properties() {
              return {
                items: {
                  type: Array,
                  value: function() {
                    let items = [];
                    for (let i=0; i < 10; i++) {
                      items.push({
                        n: i,
                      });
                    }
    
                    return items;
                  }
                },
              };
            }
          }
    
          class MyItem extends Polymer.Element {
            static get is() {
              return 'my-item';
            }
    
            static get properties() {
              return {
                data: Object,
              };
            }
          }
    
          window.customElements.define(TestCase.is, TestCase);
          window.customElements.define(MyItem.is, MyItem);
        });
      </script>
    </body>

    codepen