Search code examples
polymerpolymer-1.0web-componentpolymer-starter-kit

Polymer Elements - Smarter responsive solution


I'm currently using following code in Polymer 1.0 to make a part of my web page responsive (it works):

<template is="dom-bind">
   <iron-media-query query="(max-width: 750px)" query-matches="{%raw%}{{isLarge}}{%endraw%}"></iron-media-query>
   <!-- set an attribute if isLarge is true -->
     <div large$="{%raw%}{{!isLarge}}{%endraw%}">
       <div class="layout vertical">
       {{ content }}
       </div>
     </div>
     <div large$="{%raw%}{{isLarge}}{%endraw%}">
       <div class="layout horizontal">
       {{ content }}
       </div>
     </div>
</template>

In my css I have

[wide] {
      display: none;
    }

To hide the <div> if false.

Now, I wonder if there's a smarter way to solve this without the double <div>.

Note I noticed that in Polymer 0.5 <div layout vertical> works but not in Polymer 1.0. Instead, only <div class="layout vertical"> seems to work for Polymer 1.0.


Solution

  • There are several ways to achieve this.

    Computing the class

    In your particular case, the content seems to remain the same, and the only difference is the horizontal/vertical class. Fortunately you can use computed values for this! Here's a sample:

    <div large$="{%raw%}{{!isLarge}}{%endraw%}">
       <div class$="_computeThisClass(isLarge)">
          {{ content }}
       </div>
    </div>
    
    ...
    
    Polymer({
       ...
       _computeThisClass: function(isLarge) {
          if(isLarge) {
             return "layout horizontal";
          } else {
             return "layout vertical";
          }
       }
    }
    

    For me, the downside of this last one is that you (AFAIK) need to include all the classes you need to apply in the js.

    Using the hidden-attribute

    If you just want to hide elements, I suggest using the hidden attribute. This can take a boolean or a computed value, as mentioned here. An example:

    <div large$="{%raw%}{{!isLarge}}{%endraw%}" hidden$="{{!isLarge}}">
       <div class="layout vertical">
          {{ content }}
       </div>
    </div>
    

    The downside is that the content does get stamped onto the page (this is essentially applying a conditional display: none;).

    Using conditional templates

    There is also the option to to this using a conditional template. An example:

    <template is="dom-if" if="{{!isLarge}}">
        <div large$="{%raw%}{{!isLarge}}{%endraw%}">
           <div class="layout vertical">
              {{ content }}
           </div>
        </div>
    <template>
    

    The downside is that content gets stamped on the page at a later stage (when the condition is met), which can cause delays. But good when the condition is unlikely to change!

    In your case simply computing the class would I believe be the best.