angular / material

Material design for AngularJS
https://material.angularjs.org/
MIT License
16.55k stars 3.39k forks source link

md-toolbar: allow fixed (sticky) #1053

Closed DmitryEfimenko closed 8 years ago

DmitryEfimenko commented 9 years ago

Hello,

This is more of a feature request.

I know there is a way to make toolbar appear and disappear as user scrolls via the use of md-scroll-shrink, but I'm wondering if there is a way to make toolbar fixed at the top so that it's visible at all times.

To be exact, I'm actually looking for a way to make the effect similar to the effect that can be observed on TV-Series app, where originally toolbar is large and has a background image, but as you scroll down the image disappears and the toolbar shrinks a bit.

I understand that the behavior described above is quite custom, and I'm ok writing custom code to achieve that, but for starters it'd be nice to have an easy way to make toolbar fixed at the top.

Perhaps it would make sense to create a new directive md-header (similar to how ionic is doing it) that would have fixed position by default and could potentially have an option to behave like described above.

Any help is appreciated, Thanks.

EladBezalel commented 9 years ago

Do you mean something like this?

DmitryEfimenko commented 9 years ago

Yes! Very close! The TV-Series also has image appearing/disappearing as you do that scrolling, but the idea is the same. How did you achieve this?

EladBezalel commented 9 years ago

Its from the specs of Material Design

Its a feature they didn't even talked about but i'm sure eventually they'll develop it.

opened an issue about it ##1054

DmitryEfimenko commented 9 years ago

Thanks for opening the issue!

DmitryEfimenko commented 9 years ago

By the way, it appears it's actually pretty easy to make toolbar fixed at the top. <md-toolbar> needs to be placed as the first element at the root of the <body> (I had it wrapped in a div, which is why it was not working).

Perhaps this could be placed in the documentation to avoid confusion.

demisx commented 9 years ago

@DmitryEfimenko Please post a code snippet or a working plunker. I am sure others will find it helpfull.

epelc commented 9 years ago

If anyone else needs to do this I have an example project go-material which I started working on to help people see how to structure an app. It doesn't do much right now but it does have a sticky header.

AMoQu commented 9 years ago

Any update on this missing feature?

wlingke commented 9 years ago

@AMoQu My current fix for this is just to add a class to md-toolbar that implements position: fixed;

infacq commented 9 years ago

@wlingke do you have the example?

wlingke commented 9 years ago

@infacq it's pretty easy to do it yourself... style="position: fixed;"

infacq commented 9 years ago

do you have example with the shrink one. I cannot get my head around it

wlingke commented 9 years ago

No this does not do a shrinking one. You'll have to wait until it comes out. ᐧ

Best, Lingke

Lingke Wang Stanford GSB '16

On Wed, Jun 10, 2015 at 12:08 AM, Muhaimin notifications@github.com wrote:

do you have example with the shrink one. I cannot get my head around it

— Reply to this email directly or view it on GitHub https://github.com/angular/material/issues/1053#issuecomment-110624816.

NoamaExl commented 9 years ago

Will be useful to have this this with the shrinking effect built in

guiporto commented 9 years ago

I believe this is a good reference for this issue: http://codepen.io/jbltx/pen/KwQxBX

shinrox commented 9 years ago

+1

DmitryEfimenko commented 9 years ago

I believe the use-case when you cannot put the <md-toolbar> as the first child element of the <body> is quite common and is the main source for the need for <md-toolbar> to be sticky inside other elements.

<body>
    <ui-view></ui-view>
</body>

The loaded state (thus placed inside <ui-view>) might have the toolbar.

The proposed solution to just apply style position: fixed seems to be lacking given that one has to mess with css heights/margins also.

epelc commented 9 years ago

You can already have a fixed toolbar which isn't a direct child ofbody. You just need to add layout="column" to all of the parents of your toolbar.

wlingke commented 9 years ago

I run into this problem with position fixed inside ui-view because if you ever have a backdrop (like dialog or select) the fixed position toolbar disappears. 

Ideally we would do something like ionic - where you can specify it inside ui-view but it's rendered outside of it. 

ghahramani commented 9 years ago

@guiporto I changed your code a little to fetch the background color of toolbar. Just replace the primary color with below code:

var reg = /\((\d+),*.(\d+),*.(\d+)/;
var bg = reg.exec($window.getComputedStyle(element[0], null).getPropertyValue('background-color'));
var primaryColor = [bg[1], bg[2], bg[3]];
xenoterracide commented 9 years ago

having it as the first isn't working for me either

<body ng-app="rpfCm" layout="column" role="application">

<md-toolbar role="application"
            layout="row" layout-align="start center"
            class="md-toolbar-tools md-whiteframe-z2">
    <md-button class="md-icon-button">
        <md-icon class="material-icons">menu</md-icon>
    </md-button>
</md-toolbar>

maybe it's because of the scripts injected at build time

<body ng-app="rpfCm" layout="column" role="application" class="layout layout-column ng-scope"><script type="text/javascript" id="__bs_script__">//<![CDATA[
    document.write("<script async src='/browser-sync/browser-sync-client.2.9.3.js'><\/script>".replace("HOST", location.hostname));
//]]></script><script async="" src="/browser-sync/browser-sync-client.2.9.3.js"></script>

<md-toolbar role="application" layout="row" layout-align="start center" class="md-toolbar-tools md-whiteframe-z2 layout layout-row layout-align-start-center md-default-theme">
    <button class="md-icon-button md-button md-default-theme" ng-transclude="">
        <md-icon class="material-icons ng-scope ng-isolate-scope md-default-theme">menu</md-icon>
    </button>

when I made the toolbar fixed, the sidebar overlayed it hiding my button.

ismarslomic commented 9 years ago

Maybe this example is of help http://codepen.io/infacq/pen/ZGabYq

EladBezalel commented 9 years ago

@ismarslomic very nice but i'd expect the md-subheader to work as well..

ismarslomic commented 8 years ago

@EladBezalel what do you mean with "work"? Please explain what is NOT working.

EladBezalel commented 8 years ago

Subheader should raise above the list

xenoterracide commented 8 years ago

Also if I do this style="position: fixed;" the contents below my toolbar get partially cut off. So contents that should remain below the toolbar (sidebar/md-content) drift to the top of the page.

adding an encapsulating unfixed div with a min height, and the same top margin seems to fix my issues if that helps anyone else, but it'd be nice if this could just work.

<body ng-app="rpfCm" layout="column" role="application" ng-controller="AppCtrl">
<div style="min-height: 64px;" role="region">
    <!-- I are hack for fixed position md-toolbar -->
    <md-toolbar
            layout="row" layout-align="start center"
            class="md-toolbar-tools md-whiteframe-z2"
            style="position: fixed;"
            >
        <md-button ng-click="toggleLeft()" class="md-icon-button">
            <md-icon class="material-icons">menu</md-icon>
        </md-button>
    </md-toolbar>
</div>

<div flex layout="column" class="md-whiteframe-z1">

    <div flex layout="row">
        <section role="region"
                 layout="column">
            <md-sidenav
                    role="navigation"
                    flex
                    layout="row"
                    md-component-id="left"
                    style="margin-top: 64px"
                    class="md-sidenav-left md-whiteframe-z2"
                    >
...
topherfangio commented 8 years ago

@EladBezalel We made some recent updates to the Subheader that fixed some issues with using a toolbar that has scroll-shrink along with a list with subheaders; so this may be possible now.

I tried to make a quick demo, but I ran into an issue of not being able to have the toolbar stop shrinking at a certain size. I'm sure it's possible, if someone wanted to spend a bit of time with it :-)

epelc commented 8 years ago

Here is a working example for everyone.

http://codepen.io/anon/pen/wKWrpy

Note if you do this in your own app you must add layout="column" to the body element for it to work. You can't add attributes to the body element in codepen so I used some js to add the classes layout="column" generates.

topherfangio commented 8 years ago

@epelc The toolbar is indeed designed to be used outside of the md-content as it must be a sibling for the scroll shrink to work. I think the request here is that the toolbar can start out big and then partially shrink to the size of a normal toolbar; which I think might now be possible, but I haven't been able to create a demo yet.

alexpechkarev commented 8 years ago

Here is 'sticky' Sidenav Toolbar example, hope that helps someone.

http://codepen.io/alexpechkarev/pen/BopJwM

DmitryEfimenko commented 8 years ago

@alexpechkarev same effect can be achieved without any additional css. See forked codepen

alexpechkarev commented 8 years ago

@DmitryEfimenko brilliant, thanks!!!

MadMub commented 8 years ago

To offer some insight, I myself struggled to grasp how the angular material doc site has a sticky toolbar, while still maintaining position relative.

The key was diving further and learning how flexbox works, which is what material is implemented in (in terms of css layout). So making something scroll away or remain "sticky" should never involve changing the position attribute. But rather involve leveraging flexbox in the right way.

Technically speaking flexbox is considered "holy grail" css, because you can achieve both vertical and horizontal centering of elements, with dynamic heights and widths (as they "flex"ibly shrink and grow to fill their containers). It does have a few nasty bugs though. Which are likely best documented here, https://github.com/philipwalton/flexbugs.

Sorry if I went off topic at all.

altaurog commented 8 years ago

@MadMub Interesting. Thanks for pointing that out. This is a different approach to solving more or less the same problem, but seems easier with the current set of ng-material components. What I see is a layout including sidenav pane, toolbar, and a md-content element sized exactly to the remaining height and width of the window (using flex). So the window doesn't scroll; the md-content pane scrolls. This eliminates the need for fixed css, but it does alter the ui slightly.

dmackerman commented 8 years ago

We have several nested containers, and the issue for us is that we weren't setting a height on some of them. We used height: 100vh to get the containers to stretch properly. flex didn't seem to do it.

MadMub commented 8 years ago

@dmackerman be careful with height 100vh this will set a given container to take up the entire screen since it is sized relative to your viewport. I thought I read somewhere angular 2.0 might support multiple virtual viewports?!?!? (please someone elaborate if they know more) which might allow for some cool 100vh 100vw to fill a viewport nested within a larger one. But as it stands 100vh and 100vw fills the viewport

mackelito commented 8 years ago

+1

trainerbill commented 8 years ago

has anyone gotten a stick header inside of a ui-view?

<body ng-cloak>
  <header ui-view="header"></header>
  <section layout="row">
    <section ui-view="leftnav"></section>
    <section ui-view="main"></section>
    <section ui-view="rightnav"></section>
  </section>
ThomasBurleson commented 8 years ago

This issue is closed as part of our ‘Surge Focus on Material 2' efforts. For details, see our forum posting.

ThomasBurleson commented 8 years ago

This issue is closed as part of our ‘Surge Focus on Material 2' efforts. For details, see our forum posting @ http://bit.ly/1UhZyWs.

ThomasBurleson commented 8 years ago

This issue is closed as part of our ‘Surge Focus on Material 2' efforts. For details, see our forum posting @ http://bit.ly/1UhZyWs.

kdubau commented 8 years ago

@trainerbill any luck with sticky header in ui-view??

IsNull commented 8 years ago

I am fighting with this too. But since I always need a toolbar (just the content depends on the view state), I use this workaround:


        <md-sidenav
                class="md-sidenav-right dynamic grey"
                md-whiteframe="4"
                md-component-id="right"
                md-disable-backdrop="isLockedOpenRight()"
                md-is-locked-open="isLockedOpenRight()"
                md-is-open="isOpenRight()"
                layout="column"
                >

            <md-toolbar class="md-hue-2 md-primary" layout="row">
                <ui-view name="detail-toolbar"></ui-view>
            </md-toolbar>

            <md-content layout="column" class="detail-container" ui-view="detail"></md-content>

        </md-sidenav>

So for each detail in my right side-nav, I have two named views, @detail for a scrollable content and for the sticky toolbar @detail-toolbar. Maybe this helps.

daddydrac commented 7 years ago

@guiporto - Is there a way to make the text and tools change when you scroll down/over another index, and that text and tools/buttons are specifically bound to that index?