angular / components

Component infrastructure and Material Design components for Angular
https://material.angular.io
MIT License
24.32k stars 6.72k forks source link

(sidenav) elements with `position: fixed` inside `md-sidenav-layout` #998

Closed fxck closed 6 years ago

fxck commented 8 years ago

Because of transform: translate3d(0, 0, 0) on md-sidenav-layout any element with position: fixed inside it will act as if it had position: absolute or static instead. It's an expected behaviour, but it's annoying nevertheless.

Could we either remove that transform from md-sidenav-layout(it's only there because of performance I suppose), or add more examples to Portal and mention it as a workaround in docs, since portal could probably solve this by basically putting the element that needs to be fixed next to the md-sidenav-layout in the dom tree.

cc @hansl @jelbourn

fxck commented 8 years ago

https://gist.github.com/fxck/b668f7fec77d7b28d8c7ce6b706601f7

here's a component that takes whatever is inside it and puts it to the body using material2 overlay

fxck commented 7 years ago

@jelbourn this is still a thing, can you label it please?

jelbourn commented 7 years ago

We need to discuss whether we consider this a bug or not.

cortopy commented 7 years ago

In my opinion this is a bug insofar as it is the equivalent of putting a ban on fixed elements. I am now trying to create a fab button on the bottom right corner of the screen. Because of this issue I'm unable to do so unless I use solution provided by @fxck

bergben commented 7 years ago

Is the workaround from @fxck still working? I am getting EXCEPTION: Must provide a portal to attach...

mmalerba commented 7 years ago

I recommend just absolutely positioning the fab outside the scrollable region: http://plnkr.co/edit/VItn3Y2AaTzpzIykTTyH?p=preview

cortopy commented 7 years ago

that's clever @mmalerba but it wouldn't work in my case. My button is inside a router outlet as the fab is not always needed. Your solution would work great for cases where fixed elements should be visible in every view though.

Also, it would mean a lot of boilerplate to pass events to other components within the scrollable area

cortopy commented 7 years ago

@bergben it is. I'm using material alpha 10 and it still works. It took me a bit to get it working though. Could you post what you have?

bergben commented 7 years ago

@cortopy It was kinda late yesterday, the problem was that I simply forgot to import the Directive as well πŸ˜„ Got some other problem now though that the sidebar is not opening / visible / whatever... What I got now is this:

<md-sidenav-layout [ngClass]="{'administration' : isLoggedIn}">
    <md-sidenav #sideNav mode="push" [hidden]="!isLoggedIn" opened="true">
        <noe-admin-sidenav>
        </noe-admin-sidenav>
    </md-sidenav>
    <fnls-displacer [sideNav]="sideNav">
            <noe-admin-topnav [sideNav]="sideNav" *ngIf="isLoggedIn">
            </noe-admin-topnav>
            <div class="content-wrapper">
                <router-outlet></router-outlet>
                <noe-footer></noe-footer>
            </div
    </fnls-displacer>
</md-sidenav-layout>

How exactly do I have to wrap the content with the displacer to get it to work? I also had to add this css to make the fixed content work:

.md-overlay-pane{
    width:100%;
}
.md-overlay-container{
    position:absolute !important;
}
bergben commented 7 years ago

Still couldn't resolve this. Seems like this wasn't a problem with the angular 1 version of the sidenav... Problem is, I don't only have one button that is fixed but the whole content is fixed for a certain time as I am using https://github.com/bergben/ng2-scrollimate to apply animations on the fly during scroll. So if I displace that all then there is nothing left anymore in md-sidenav-content and the sidenav itself doesn't work anymore...

mmalerba commented 7 years ago

1966 adds a sidenav with fab example

fxck commented 7 years ago

@mmalerba Having a scroll inside content rather than on body brings a lot problems with UX and with fixed elements(various cases when fixed element is actually overlaying the scrollbar, or regions that appear part of scrollable areas but are not, so you are scrolling on them and the page doesn't scroll), also there are potential problems / extra set up on phones for smooth scrolling required, potential double scrollbars... meh. All this because of an unnecessary transform: translate3d(0, 0, 0). πŸ‘

Take my directive, name it something better, make it a structural directive for easier use and add it to the core. It just puts everything inside it in a Overlay, nothing more, doesn't break binding in any way. Problem solved. Usable on many other places.

mmalerba commented 7 years ago

I do think separate scrolling areas should be the recommended solution for this. If I have a lot of content in my sidenav I probably want it to scroll independently from my content area. However I do think it currently requires a bit too much work to set up, I would like to make it easier if possible. I'm also not opposed to removing the translate3d if it really is superfluous (I need to investigate) so that people can use the fixed positioning solution if they prefer.

@jelbourn Do you have any opinions on this?

bergben commented 7 years ago

@mmalerba This solution only works if you have relatively simple fixed content, if you have it spanning over the whole page or stuff like that it just gets too complicated. What I find interesting though is that this problem didn't seem to come up in the Angular 1 version of the sidenav - as I was searching through the issues there. The translate3d could be replaced with a simple animation and basic distance property to fix this problem for good... I don't know though why the translate3d breaks a css position in the first place, this is surely a misbehavior of CSS in the first place IMO, but that's another topic.

johnl242 commented 7 years ago

I am using angular 2 material design, pls give a solution base on angular 2 material design and not material 1

cortopy commented 7 years ago

@bergben I'm not sure I understand your template.

Simplifying a lot this is what I have in app.component.html:

<md-sidenav-layout>
    <md-sidenav #start mode="side">
      <my-sidenav></my-sidenav>
    </md-sidenav>

    <router-outlet></router-outlet>
 </md-sidenav-layout>

And then in a template for a component that gets loaded by the router I have:

<fnls-displacer>
      <button></button>
</fnls-displacer>
johnl242 commented 7 years ago

fab button not being fixed on button right position while scrolling

On Nov 29, 2016 3:38 PM, "Juan J. Jimenez-Anca" notifications@github.com wrote:

@bergben https://github.com/bergben I'm not sure I understand your template.

Simplifying a lot this is what I have in app.component.html:

And then in a template for a component that gets loaded by the router I have:

β€” You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/angular/material2/issues/998#issuecomment-263529150, or mute the thread https://github.com/notifications/unsubscribe-auth/AKF9fMNi-a5ccvI1k6Ot40RvfZHCmcX8ks5rC_mzgaJpZM4JiD6w .

fxck commented 7 years ago

Yeah you got that right @cortopy there are no inputs on displacer itself, it's literally just "take whatever is inside me and append it to body". It doesn't break bindings or anything, so it's as if you were wrapping it in a div. What I think he's doing is wrapping the whole router-outlet inside it, which I'm not surprised at all that doesn't work. It's really intended for buttons/modals/whatever you need appended to body from inside the router outlet.

cc @bergben

johnl242 commented 7 years ago

I have the fab button inside a component and this component is being called from router-outlet and the router-outlet is inside the side-nav-layout as u have described. After doing every thing the fab scrolls while scrolling data in the component which is not what I need.

On Nov 29, 2016 10:01 PM, "AleΕ‘" notifications@github.com wrote:

Yeah you got that right @cortopy https://github.com/cortopy there are no inputs on displacer itself, it's literally just "take whatever is inside me and append it to body". It doesn't break bindings or anything, so it's as if you were wrapping it in a div. What I think he's doing is wrapping the whole router-outlet inside it, which I'm not surprised at all that doesn't work. It's really intended for buttons/modals/whatever you need appended to body from inside the router outlet.

cc @bergben https://github.com/bergben

β€” You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/angular/material2/issues/998#issuecomment-263621269, or mute the thread https://github.com/notifications/unsubscribe-auth/AKF9fBpBHTG8b78hNquET1i-TVcNbcKhks5rDFNMgaJpZM4JiD6w .

cortopy commented 7 years ago

@johnl242 don't forget to style your button!! The displacer doesn't do anything in terms of styling or positioning. This is what I have

  bottom: 1rem
  position: fixed
  right: 1rem
  transform: translateZ(0)
johnl242 commented 7 years ago

It's positing at fixed bottom right but scrolling while data being scrolled

On Nov 30, 2016 3:31 PM, "Juan J. Jimenez-Anca" notifications@github.com wrote:

@johnl242 https://github.com/johnl242 don't forget to style your button!! The displacer doesn't do anything in terms of styling or positioning. This is what I have

bottom: 1rem position: fixed right: 1rem transform: translateZ(0)

β€” You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/angular/material2/issues/998#issuecomment-263832373, or mute the thread https://github.com/notifications/unsubscribe-auth/AKF9fBjIoSS_TyW2G_WsQSWVKOi80VI8ks5rDUmOgaJpZM4JiD6w .

bergben commented 7 years ago

@johnl242 I think it would be better if you post some code to see what you have so that people can actually help you.

@cortopy @fxck Thanks but I realized the displacer is no solution for me as the content is only fixed during a certain period of time and the rest of the time it is normally positioned inside some other content. As said I am using ng2-scrollimate to create some scrolling effects which also include having an element fixed for a certain period of scroll only. Porting that element to the body does not offer a solution as it breaks the whole layout. So I guess I'll have to wait for a solution that does not use transform: translate3d

sterlingfs commented 7 years ago

pretty please remove transform: translate3d from the .md-sidenav-content class?

Carlos-Montiel commented 7 years ago

So, what's the solution?

Splaktar commented 7 years ago

.mat-tab-body-content of md-tab-body has transform: translate3d(0px, 0px, 0px); as well. Thus trying to add a FAB inside of tab container is also a problem.

joonaspi commented 7 years ago

Any update on this? I would need to have a FAB button floating while user scrolls down the page.

alexichepura commented 7 years ago

CSS transform on .mat-sidenav-content creates a new local coordinate system. For now I use this workaround.

.mat-sidenav-content {
    transform: none !important;
}
Defmetalhead commented 7 years ago

Currently having to override globally

.mat-sidenav-container, .mat-sidenav-content {
    transform: none !important;
    transition: none !important;
}
radoslavpetranov commented 7 years ago

@Defmetalhead removing the transition screws up the sidebar content animation when you toggle the menu. In my case using just

.mat-sidenav-container, .mat-sidenav-content {
    transform: none !important;
}

was all I needed to get the position: fixed to work. Just a heads up to anyone who just copy/pastes this without noticing the side effect.

Defmetalhead commented 7 years ago

@radoslavpetranov I do not experience the issue with the sidebar animation, but you are correct in the fact that only "transform" needs to be overwritten.

mina-skunk commented 7 years ago

Just a note this is also causing change in behavior in other libraries as well. http://wijmo.com/topic/how-to-prevent-window-scroll-to-top-on-wijmo-flexgrid-click-event/

ArthurianX commented 7 years ago

It is actually breaking bindings, a form submit type=submit button.

If I manually submit through a (click) it works, but the submit itself, it gets it out of context.

ncrawlins commented 7 years ago

I use a third party charting library in the content and the transform breaks all their mouseover tooltips in certain container structures.. It also causes full page flickers in IE 11 when their tooltips are active. Turning off the 3d transform fixes all these things. What does it do? Is it necessary?

mackelito commented 7 years ago

using transform will (on some devices) trigger to use hardware acceleration.. feels like a good incentive to keep it.. ?

jvanhall commented 7 years ago

With the latest release the component @fxck built no longer works due to the TemplatePortal changes. Can we get an updated version as a patch until this is resolved. Also, just removing transforms via CSS no longer seems to be a valid work around.

ncrawlins commented 7 years ago

the transform fix still works for me but they changed the class names from .mat-sidenav- to .mat-drawer- so you probably have to update your css

jvanhall commented 7 years ago

Yeah looks like I missed one of the .mat-drawer classes. Working now. Thanks!

WaterBleu commented 7 years ago

Im surprised we still have to do workaround at this point. this is like a year old bug

CDDelta commented 7 years ago

@WaterBleu see #6712

WaterBleu commented 7 years ago

@CDDelta nice! now just have to wait for the approval

MatthewS2077 commented 7 years ago

@CDDelta Excellent!

mackelito commented 7 years ago

aaaah maaaaan.. just I did this like 3 weeks ago! πŸ˜† But still.. Great work πŸ‘Š πŸ˜„

karser commented 6 years ago

Great that it'll be fixed soon. Meanwhile after updating to 2.0.0-beta.10:

.mat-sidenav-content,
.mat-sidenav-container,
.mat-drawer-content {
    transform: none !important;
}
sijithc40 commented 6 years ago

I given this .mat-sidenav-content, .mat-sidenav-container, .mat-drawer-content { transform: none !important; }

But side-nav "push" is not working now

mina-skunk commented 6 years ago

@sijithc40 It won't because "push" mode uses transform.

Sangeethaself commented 6 years ago

Material design light with version v1.0.1

After long searching and trying , problem solved by following code

.mat-sidenav-container, md-sidenav-container div[style], .mat-sidenav-content{ transform: none !important; -webkit-transform: none !important; }

rahulasharm commented 6 years ago

I am using angular 2, so what should I do for this issue.....

gaalha commented 6 years ago

Simply define width margin at mat-sidenav-content in styles.css file:

mat-sidenav-content {
    width: 100vw;
}
angular-automatic-lock-bot[bot] commented 5 years ago

This issue has been automatically locked due to inactivity. Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.