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
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:
Toolbar: app-layout and app-header-layout should give you a fixed toolbar on the top. Use the fullbleed attribute to make it fullsize (`')
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.
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.
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.
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?)
Related
I am building a small blog based on metalsmith and the PureCSS framework, which has a simple three-row-layout like so:
<div class="pure-g">
<div class="pure-u-1"> Navbar </div>
<div class="pure-u-1"> Content </div>
<div class="pure-u-1"> Footer </div>
</div>
As I am still learning a lot new stuff about CSS and responsive design I am wondering if a navbar should be put into a grids row as well or if it should reside outside of it. The PureCSS documentation states the following:
All content which is visible to people needs to be contained inside a
grid unit. This ensures that the content will be rendered properly.
This would make it a yes, as a navigation menu is of course visible to the user. However doesn't that make handling of media queries more complicated for the navbar? So where should I put my navbar to, when using responsive grids?
No. Navbar should not necessarily be within the grid. The main purpose of using grids is to make the content look better and proper. It also aids the programmer in deciding how many blocks of the grid to allot to a certain element.
However, since a Navbar goes all the way across the page, there is no reason to assign it a grid size. It should always be 100%.
If you are building a blog app, then only your content should be within your grid system so as to properly render the elements. From what I've seen, a footer also generally stretches all the way across the window.
You can use grid. Managing and handling contents and components would be easier and rendering in different browsers would be more stable.
Goal
I am trying to implement a layout that works as follows:
Page content is responsive and adjusts to window width
If the page contains a large data table, the table will overflow to the right
In this case, a scroll bar on the window (not on the table) will be shown
If the user now scrolls to the right, only the table scrolls, not the rest of the page
Sidebar, header, footer (all with fixed height/width) should be present
Example
Here is a jsbin with a very hacky implementation, that should illustrate what I mean: http://jsbin.com/gonezaqala/1/edit?html,css,js,output
Issues
Frequent problems that I ran into:
I figured that I need to use position: sticky to make this layout work but since elements are only ever sticky relative to their parent, I need to try to keep the sticky elements at a top level
Alternatively, I can create a separate container that does the horizontal scrolling (like in the jsbin example), but then trying to make this fit with the other parts of the layout (sidebar, footer) because really painful
I also want to implement this in a way that all the elements in the main content area (so everything but header, footer, sidebar) are together in one single container, since I am using AngularJS and this is where my router would inject the view
Question
I am sure, I have seen this kind of behaviour before, but I can't remember where it was. So my questions are as follows:
Is this a somewhat common UI pattern? Does it have a name?
Is it possible to implement a layout like this with only CSS?
Would it anyway be desirable to create such a layout or are there any concerns from a UX perspective?
I am trying to use Angular UI-Grid . It works well, but it always small with a scroll bar on the y-axis (You can just visit there home page to view the two examples there, the height of the grids there are the basic grid).
In the docs I have seen that "height" can be given, but I do not want the scroll bar at all.
I want the grid to fit the entire container (page) and to scroll the grid using the browsers scroll-bars.
I have looked everywhere (and in the css) and could not find a solution,
can anyone help me with this?
The ui-grid will just take all the space in the div element it is added in.
http://plnkr.co/edit/hcG0ucnCCbIFbVDqewkr?p=preview take a look at the example and try playing with the .grid in the css.
<div id="grid1" ui-grid="gridOptions" ui-grid-exporter ui-grid-selection class="grid"></div>
Is it possible to design page like on this picture:
I need reach only three goals:
First content can be scrolled only vertically.
Second content can be scrolled only horizontally.
Must be used only browsers scrollbars.
p.s. Better if we will not use javascript code.
Yes, this is possible.
The real difficulty is to add scrollbars outside de views.
But when done, you can easily scroll to a position your scrollviews.
I don't think this is really a good feature to make this but why not.
Be strong!
My company doc pages need to be laid out as specified in this image:
The iframes are handled by the doc team software, MadCap Flare. The problem we're having is that we'd like the breadcrumbs and topic heading/logo to be fixed elements at the top of the page and have the topic content be scrollable, without disappearing under the fixed elements at the top.
We'd also like for the topic content scrollbar to be the web browser scrollbar, and not an overflow scroller. Additionally, because we have fixed elements at the top, we need to avoid content disappearing under the fixed element such as when the page loads or a link is clicked to an anchor somewhere on the page (anchors load at the top of the page and not the top of the content table cell).
The built content looks like this:
<body>
<table class="superheader">
<tr class="topRow">
<td class="headingBreadcrumbs">
<div class="breadcrumbs">breadcrumb trail</div>
<h1>topic heading</h1>
</td>
<td class="headingLogo">
<img src="logo.png">
</td>
</tr>
<tr class="contentRow">
<td class="content" colspan="2">topic content - full of tables, divs,
paragraphs, lists, etc...</td>
</tr>
</table>
</body>
I'm not married to the inner table. I'll welcome a different solution so long as:
the breadcrumbs/heading/logo are fixed at the top so they're always visible.
topic content does not get hidden under the fixed top element, such as when the page loads or when clicking a link to an anchor.
the user can scroll the content using the browser scrollbar.
Doing it exactly as you mention with the scrollbars being native says Frames to me, though now I have to beat myself silly for suggesting it. Frames were annoying back in the early 90's when I got my start....
Something like JQuery layout would probably end up doing a lot more for you and could add the ability for the user to customize (to an extent) their workspace.
Since iFrames are also not exactly in vogue any more, you could draw that information directly in to the dom via jQuery Ajax or the like. At least that's how I think I would approach it.
Maybe something like this. It lacks equal height columns, but that can be acheived though.
Fiddle
Just a try! - Does not solve the scroolbar problem though. Downvotes desereved.
Try this out:
http://jsfiddle.net/k2R3G/
I have created this jquery plugin to solve a similar issue I was having where I had a centered container (tabular data) and I wanted the header to fix to the top of the page when the list was scrolled. One of the issues was, when the header became fixed, the content below it would jump up the page (not good). This plugin compensates for the "fixed" element and allows the content below it to position and scroll as it should, without having to set margin-top on my content, so the header can vary in height.
In the jsfiddle, I modified your layout a bit to use list items instead of tables.
Here is the link to this jquery plugin that may solve this problem:
https://github.com/bigspotteddog/ScrollToFixed
The description of this plugin is as follows:
This plugin is used to fix elements to the top of the page, if the element would have scrolled out of view, vertically; however, it does allow the element to continue to move left or right with the horizontal scroll.
Given an option marginTop, the element will stop moving vertically upward once the vertical scroll has reached the target position; but, the element will still move horizontally as the page is scrolled left or right. Once the page has been scrolled back down passed the target position, the element will be restored to its original position on the page.
This plugin has been tested in Firefox 3/4, Google Chrome 10/11, Safari 5, and Internet Explorer 8/9.
Usage for your particular case:
<script src="scripts/jquery-1.4.2.min.js" type="text/javascript"></script>
<script src="scripts/jquery-scrolltofixed-min.js" type="text/javascript"></script>
$(document).ready(function() {
$('.topRow').scrollToFixed();
});