0

I am building a Polymer application based around the concepts of the prpl pattern espoused at Google IO this year. Specifically related to this question this means that there is an index.html file which loads the web-components polyfil and has a single element in its body <my-app>

<my-app> in turn uses the polymer elements <app-header-layout> set to provide a waterfall effect on a top toolbar, does some session management (to ensure the user logs in) and then delegates everything else to a <my-pages> element. In simplistic terms <my-app> looks like this:-

  <app-header-layout>
    <app-header fixed effects="waterfall">
      <app-toolbar>
        <h4 >Part of my toolbar</h4>
      </app-toolbar>
    </app-header>
    <my-pages></my-pages>
  </app-header-layout>

<my-pages> uses the <iron-pages> element to allow the user to select among different pages, each page of which is its own element. In simplistic form like this:-

  <iron-pages role="main" selected="[[page]]" attr-for-selected="name" >
    <my-menu name="home" menu-page="{{page}}"></my-menu>
    <my-list name="list" list-page="{{page}}"></my-list>
    <my-long-page name="long" long-page="{{page}}"></my-long-page>
  </iron-pages>

The reason my example has three pages is because there are three cases I want to cover. <my-menu> is a flexible layout consisting of lots of buttons and a number of separate <paper-card> elements used to group the menu into sections. In the normal desktop scenario this comfortably sits within the screen size, but when displayed on a smart phone will require scrolling to reach all the buttons. <my-long-page> is an example of a page with lots of content. It WILL require scrolling to reach the content at the bottom of the page.

<my-list> is the difficult one - It will consists of a header and then an <iron-list> element. An example layout looks like this:-

  <div class="title">
    <span>List Page</span>
    <paper-button id="return" raised>Return To Menu</paper-button>
  </div>
  <div class="header">This is the heading for my List</div>
  <iron-list items="[[data]]" as="row">
    <template>
      <div class="row" tabindex$="[[tabIndex]]" index="[[index]]">
        <div class="field">[[row.id]]</div>
        <div class="field">[[row.name]]</div>
        <div class="field">[[row.outcome]]</div>
      </div>
    </template>
  </iron-list>

Mostly, my list pages have a controlled set of columns, but there is one class of page where the server sends the columns to be displayed back in the ajax request to get the data. In that instance I have to use a <template is="dom-repeat"> element to list the fields (in both the above list header and in the lists row contents).

This app has grown organically over the last few months, and my styling is a mess. Despite my best efforts the majority of pages have a scrollbar on the right even when the content doesn't justify it and the <my-list> page is difficult to get completely right. So I am taking a step back, breaking the styling down and trying to approach it from scratch. I want to use Polymers flex-box mixins (eg @apply(--layout-vertical); etc ) in each of the custom elements styles to achieve the following:-

  • A toolbar that remains at the top of the page always, with a waterfall effect if content has to scroll underneath it.
  • A flexible layout that will work on desktop, tablets and phones
  • No horizontal scroll bar the majority of the time - when the pages collapse to their minimum width after flexing and they are still outside the bounds of the device they are being displayed on then a horizontal scroll bar should appear
  • When page content is less than the vertical space on the screen, to have no vertical scroll bar, when more than the vertical space to then have a scroll bar.
  • The <my-list> page should precisely fit the screen in most cases (so no scroll bar for the page in normal circumstances) with the <iron-list> element height set to fully fill the remaining vertical space on the screen below the header items. It will of course throw up its own scroll bar if the number of items in its list exceed the available space. This space for the <iron list> should have a minimum height such that when the screen height is too small, then and only then, can a second, page oriented vertical scroll bar appear.

I am struggling to achieve this - particularly the element with the <iron-list> I can easily set its height to a fixed size and it will work, but whenever I try and apply flex to it seems grow to the full size of its content and then the overall page ends up by being scrollable and I loose the list heading. The closest I've got so far is to use calc(100vh -200px) to set the height, but this requires me to guess (or know) the height of the heading above the list.

What I am looking for is guidance as to what to put inside a <style> inside the <template> each of the custom elements to achieve the aims listed above in the most elegant manner

akc42
  • 4,893
  • 5
  • 41
  • 60

1 Answers1

0

This question is quite broad an actually more a question about CSS layout and flexbox than about Polymer itself, but I will try to answer some of the points:

  1. Toolbar: app-layout and app-header-layout should give you a fixed toolbar on the top. Use the fullbleed attribute to make it fullsize (`')
  2. Regarding responsive layout: The easiest in my mind is to start to design for mobile first (define your styles so that it works good for mobile view). Use ChromeDevTools to switch to a mobile view. One the mobile view works, use media queries and change some of the CSS classes. Most of the time you might for example switch from --layout-horizontal to --layout-vertical. You can also look into app-grid for content heavy or card layouts.
  3. Horizontal scrollbar: I would try to avoid it as much as possible to have a horizontal scrollbar. Rather re-arrange the content or use different visualization paradigms. In general you should work with min-width and min-height and combine it with flex:1 settings to flexible adapt content to available space.
  4. Vertical scrollbars are more common. Using flexbox you can make the content stretch to the entire avaialble space and combining it with min-height you can make sure that the vertical scrollbar is displayed.
  5. The iron-list requires an explicit size for itself or the container. One way is to size it ahead of time. Alternatively you can use --layout-fit or --layout-vertical on the container and --layout-flex on the iron-list to make it take the available space.

I would recommend to read some material on flexbox. It sometimes can be tricky (see this question for example: How to make flexbox children 100% height of their parent?)

Community
  • 1
  • 1
Ümit
  • 17,379
  • 7
  • 55
  • 74
  • Thanks for all this input. I need to spend some time considering before accepting as the answer. I solved one problem and that was I had copied my app style from somewhere (I think an example using the taller background image version of app-header) and it had a big margin at the bottom of the page area. It was this causing the spurious extra vertical scrollbar. – akc42 Sep 12 '16 at 17:45