I want to add a sticky button at the bottom of screen (not page) in my angular 2 material project.
I tried some tweaks but currently when I scroll down the button doesn't stays where it was supposed to be.
before scroll it looks like below:
after scroll:
Elements's HTML inside template:
<a md-fab id="fab">
<md-icon>add</md-icon>
</a>
CSS Applied on the Element Except for any defaults:
#fab{
position: fixed;
right: 30px;
bottom: 30px;
}
*{
margin: 0;
}
How can I fix this?
Additionally is there any built in way with Angular material to do what I want?
UPDATE:
My main component's Template:
<toolbar></toolbar>
<side-nav></side-nav>
Side Nav's Template:
<md-sidenav-container id="sidenav-container">
// contents
<router-outlet></router-outlet>
</md-sidenav-container>
and its CSS:
#sidenav-container { // styling to make side nav of full height
position: fixed;
height: 90%;
min-height: 90%;
width: 100%;
min-width: 100%;
}
and then inside the component added by the router-outlet will come FAB element.
Notes-list component's template (the one shown in the images):
<a md-fab id="fab">
<md-icon>add</md-icon>
</a>
//rest of the content
LIVE DEMO
You are correct to put the router-outlet within the md-sidenav-container.
Add the follow class to your FAB element.
.md-fab-bottom-right2 {
top: auto !important;
right: 20px !important;
bottom: 10px !important;
left: auto !important;
position: fixed !important;
}
This is how I got it to work.
Add a custom class and apply your styles also look for the hierarchy in which files are referenced to DOM
<div class="example-container">
<h3>sticky icons</h3>
<a class="mine" md-fab routerLink=".">
<md-icon>check</md-icon>
</a>
<a md-mini-fab routerLink=".">
<md-icon>check</md-icon>
</a>
</div>
LIVE DEMO
Update 1 :
You are using the icon inside the md-sidenav container which is a mistake
<div class="example-container">
<md-sidenav-container>
<md-sidenav #sidenav>
<p>side nav works</p>
</md-sidenav>
</md-sidenav-container>
<p>content</p>
<a class="mine" md-fab (click)="sidenav.open()">
<md-icon>check</md-icon>
</a>
</div>
Updated Demo
Update 2 :
Look at the below code, you are wrapping everything inside sidenav which is wrong. Use as below
<md-sidenav-container id="sidenav-container"> </md-sidenav-container>
// contents
<router-outlet></router-outlet>
Related
I am looking to change the position of a div that is inside a div class. My only option is to add CSS, I cannot edit the HTML. The current code looks like this:
<div class="additional-information">
<div>
<strong> Name </strong>
<strong> Address </strong>
</div>
What I managed to do is to change the position of the entire 'additional-information' class with the following code:
.additional-information {
position: absolute;
left: 250px;
bottom: -230px;
}
Would it be possible to move individual divs inside this class that have no tag?
You could work with CSS Child Selector.
Something like this:
.additional-information > div:nth-of-type(1) {
position: absolute;
left: 250px;
bottom: -230px;
background-color: lightblue;
}
<div class="additional-information">
I am a parent
<div>
<strong>name</strong>
<strong>address</strong>
</div>
</div>
For more info look at this article.
so I am having an issue with setting up NG-ZORROs layout
I have the following layout
HERE IS A STACKBLITZ EXAMPLE OF THE SETUP
Where the HEADER should be fixed in position
The SIDE NAVIGATION (on the left) should also be fixed in position when the user is scrolling the content, but it also has an internal scroll if the menu items dont fit the screen
The CONTENT should have internal scroll so that
// WRAPPER
.wrapper {
height: 100vh;
}
// HEADER
.header {
color: white;
background-color: rgb(24, 132, 255);
height: 45px;
display: flex;
justify-content: center;
position: fixed;
z-index: 999999;
width: 100%;
}
// SIDE NAV MENU
[nz-menu] {
line-height: 64px;
height: 100vh;
overflow: auto;
}
[nz-menu]::-webkit-scrollbar {
display: none;
}
// CONTENT
.input {
border: solid 1px rgb(24, 132, 255);
}
.before {
margin-bottom: 20px;
display: flex;
justify-content: center;
background-color: rgb(184, 216, 208);
opacity: 0.3;
height: 300px;
align-items: center;
}
.after {
margin-top: 20px;
display: flex;
justify-content: center;
background-color: rgb(184, 185, 216);
opacity: 0.3;
height: 800px;
align-items: center;
}
// HERE IS WHERE THE ISSUE IS
nz-content {
padding: 0 50px;
margin-top: 64px;
// WE NEED THE OVERFLOW SO THAT ONLY THE CONTENT IS SCROLLABLE AND THE REST OF THE ELEMENTS ARE NOT
overflow: auto;
}
<nz-layout class="wrapper">
<!-- HEADER -->
<header class="header">
HEADER
</header>
<nz-layout class="content">
<!-- SIDE NAVIGATION -->
<nz-sider nzCollapsible nzWidth="200px">
<ul nz-menu nzMode="inline" nzTheme="dark" class="menu-children">
<li nz-menu-item>
<span>Menu 0</span>
</li>
<li nz-submenu *ngFor="let item of menuItems" (nzOpen)="openMap.menu+item"
(nzOpenChange)="openHandler('menu'+ item)" nzTitle="{{'Menu' + item}}">
<ul>
<li *ngFor="let submenuItem of menuItems" nz-menu-item>
Menu {{submenuItem}}
</li>
</ul>
</li>
<li nz-menu-item (click)="openHandler('menu11')">
<span>Templates</span>
</li>
</ul>
</nz-sider>
<!-- CONTENT -->
<nz-content>
<!-- ONLY CONTENT IN THE NZ-CONTENT SHOULD BE SCROLLABLE -->
<p class="before">
CONTENT BEFORE SEARCHBAR
</p>
<!-- SEARCHBAR + AUTOCOMPLETE -->
<nz-input-group class="search-wrapper" nzSize="large">
<!-- INPUT -->
<input
class="input"
type="text"
nz-input
placeholder="Click here and scroll..."
[nzAutocomplete]="auto"
/>
<!-- AUTOCOMPLETE -->
<nz-autocomplete #auto>
<nz-auto-option [nzDisabled]="true">
<span class="no-results"> No Results </span>
</nz-auto-option>
</nz-autocomplete>
</nz-input-group>
<p class="after">
CONTENT AFTER SEARCHBAR
</p>
</nz-content>
</nz-layout>
</nz-layout>
My issue is that in order to achieve that i have set up the CONTENT with overflow: auto and everything works as expected... until I added a search bar with an autocomplete box.
Now when you click the search box and scroll on the content the autocomplete box stays in position instead of sticking to the input field of the the search bar - see image
HERE IS A STACKBLITZ EXAMPLE OF THE SETUP
I was able to do some hacky workarounds, but they dont work 100%.
Does anyone know why setting up the nz-content with overflow:auto breaks the autocomplete box position ?!
Ok, after a lot more research I was able to find a working solution to the problem.
It turned out to be the following
In the usage of tooltip (including popconfirmăpopover), body element's scroll event will update the position of tooltip. It will never update the position of tooltip if the scroll event happens in a custom element.You can add cdkScrollable directive to achieve the goal. Take notice that you need to import relative package import {ScrollingModule} from '#angular/cdk/scrolling';, for more information you can visit scrolling/api.
source - ng-zorro (bottom of the page)
I also found this stackoverflow question about Material Design Autocomplete
So based on those two, what ended up doing is I imported the ScrollingModule to my module like so
import { ScrollingModule } from '#angular/cdk/scrolling';
#NgModule({
imports: [
// ...
ScrollingModule,
],
// ...
})
export class MyAppModule { }
and then just applying the cdkScrollable to NZ-CONTENT
<nz-content cdkScrollable> CONTENT GOES HERE </nz-content>
Here is a link with the working solution - line 37
I'm using Ionic 3 to make a website which will be part of another native app in a webview so I don't user cordova or any native plugins.
I have a form with an embedded Google Map View above the elements and here is my HTML :
<div style="height: 40%; width: 100%">
<div id="map_loader" *ngIf="showMapLoader">
<div class="sk-wave">
<div class="sk-rect sk-rect1"></div>
<div class="sk-rect sk-rect2"></div>
<div class="sk-rect sk-rect3"></div>
<div class="sk-rect sk-rect4"></div>
<div class="sk-rect sk-rect5"></div>
</div>
</div>
<div #mapCanvas style="width: 100%; height: 100%;"></div>
</div>
<form (ngSubmit)="submit()" padding>
<ion-list>
......
......
.....
</ion-list>
</form>
and here is my CSS :
#map_loader {
margin:auto;
background-color: rgba(0, 0, 0, 0.5);
width: 100%;
height: 100%;
z-index: 1000;
position: absolute;
}
.scroll-content {
top: 38%;
position: absolute;
margin-top: 32px;
}
Now once the user open the website on his phone and start filling the form the keyboard shifts the map out of the screen ( Up ) and it stays that way and a blank empty space shows bellow the form.
Am I doing it right? Is that happening because of my CSS? and what is the best way to make a div takes a specific percentage of the screen height? I tried ion-grid but it seems that it can't help me for this case.
it's bug in ionic, once you focus on any input the keyboard will show up and will add padding-bottom for the scroll-content class to lift the for above the keyboard and it doesn't remove the padding-bottom after you close the keyboard.
I tried to check if I have any JS event on the mobile keyboard but we don't so my work around is to set a fixed padding-bottom for the scroll-content class to prevent changing it on the runtime.
.scroll-content {
padding-bottom: 0 !important;
}
Change in the AndroidManifest.xml file did the trick for me. android:windowSoftInputMode="adjustPan"
Yes, You can avoid this issue by using Ionic grid.You need to set CSS as shown below.
your-page.scss
ion-grid {
min-height: 100%;
}
I found a good lightbox effect on a blog but I'm not sure how to tweak it the way I need. Aside from manipulating background opacity and z-index, it works by setting a divs css display property to "none" and then "block" when the effect is triggered. In that div I have the unordered lists I apply the jquery menu() and dialog() methods to. The lightbox effect and the ui methods work, but the dialog won't open inside the div designated by the class: "white content". It opens behind the white content instead. I tried to change the z-index of the dialog() in my script, but it didn't work. below I have the code from my .css, .html and .js files.
CSS
/*Lightbox effect
----------------------------------*/
.black_overlay {
display: none;
position: absolute;
top: 0%;
left: 0%;
width: 100%;
height: 2000%;
background-color: black;
z-index:1001;
-moz-opacity: 0.8;
opacity:.80;
filter: alpha(opacity=80);
}
.white_content {
display: none;
position: absolute;
top: 25%;
left: 25%;
width: 50%;
height: 100%;
background-color: white;
z-index:1002;
overflow: auto;
}
HTML
<body>
<div id="light" class="white_content">
<div id="dialog" title="Invite">
<ul class="menu">
<li>
Age Group
<ul>
<li name="ageGroup">18-21</li>
<li name="ageGroup">21-30</li>
<li name="ageGroup">30-40</li>
<li name="ageGroup">40-50</li>
<li name="ageGroup">50-60</li>
<li name="ageGroup">60-70</li>
<li name="ageGroup">70-80</li>
<li name="ageGroup">80-90</li>
<li name="ageGroup">90-100</li>
</ul>
</li>
</ul>
<button>Button label</button>
</div>
</div>
<div id="fade" class="black_overlay"></div>
</body>
JS
$(function(){
//event handler that triggers lightbox effect
$('#list').on('click', '.edit', function(event){
//this is where the lightbox effect executes.
$("#light").css("display", "block");
$("#fade").css("display", "block");
//I want the dialog and menu to open inside of the div #light
$("#dialog").dialog();
$(".menu").menu();// closes $("menu").menu()
$( "button" ).button();
}//closes function(event)
);// closes on()
}); //closes $function.
I couldn't find a way to get a UI dialog to open inside a <div>. Might be that it is made purposely to always open as a child of <body>. In jQuery UI site the dialog runs inside a <iframe> so that might trick you to believe it's inside a <div>.
My suggestion would be to put jQuery UI components inside your lightbox as it is already kind of like a dialog. Also if you want your lightbox to move you should be good with jQuery UI's draggable and resizable.
Here's a jsFiddle I made to explain what I'm after.
I have a navigation bar with images, like so:
<ul>
<li class="me">
<span class="cont"><img src="dummy.png" /></span>
</li>
<li class="me">
<span class="cont"><img src="dummy.png" /></span>
</li>
</ul>
On hovering over a list item I want to change the background color to cover the span and image like so:
.me {background-color: none;}
.me:hover {background-color: rgba(150,150,150,0.5);}
Problem is, the image does not get covered... Is this because the background is in fact... a "background" on which child elements are sitting? If so, how could I achieve this effect with plain CSS?
EDIT - solution
this worked with my original HTML structure:
<ul>
<li>
<a href="" class="ui-btn">
<span class="ui-btn-inner"> /* CONTAINS IMAGE AS BACKGROUND */
<span class="ui-btn-text">text</span> /* GETS BACKGROUND */
<span class="ui-icon"></span>
</span>
</a>
</li>
</ul>
"Negative logic": If I assign the background to list item, it sits behind all child elements, so I figured I needed to assign the background to an element that is a child of the element containing the img to have it appear above all items. span ui-btn-inner contains the image, so setting the :hover background on span ui-btn-text makes it appear above the image... weird, but works.
Yes, the background is just a background, and is placed behind any child elements.
To achieve what you're looking for, try using the css :after pseudo element to mask the image on hover:
.me {
position: relative;
}
.me:hover:after {
content: "";
position: absolute;
top: 0; left: 0;
width: 100%; height: 100%;
background: rgba(150,150,150,0.5);
}
It's shiny, you get to use the image as a semantic image, and requires no extra HTML markup.
Yes, it's because the background is in fact a background. The best method to achieve this in raw css would be to continue using the background:
.me
{
background-color: none;
background-image: url(dummy.png);
background-repeat: no-repeat;
}
.me:hover
{
background-color: rgba(150,150,150,0.5);
background-image: ;
}
You could also achieve this effect with a bit of javascript as well.
<ul>
<li class="me">
<span class="cont"><img="dummy.png" onmouseover='this.src="sometransparent.gif";' onmouseout='this.src="dummy.png";'></span>
</li>
<li class="me">
<span class="cont"><img="dummy.png"" onmouseover='this.src="sometransparent.gif";' onmouseout='this.src="dummy.png";></span>
</li>
</ul>
Code not tested. It might require tweaking to get it just right.
Edit: Layering concept
None of this pseudo-code is test, but I've done it before so it may just take a bit of tweaking. I don't have a copy of the original I did on hand so I'll have to wing it. The first step is to create a relative container and 2 sub containers.
.meContainer
{
position: relative;
width: 100px;
height: 30px; /* I usually specify height/width for these things */
}
.meContainerLink
{
position: absolute;
top: 0;
left: 0; /* You need to use position to get them to overlap */
z-index: 1; /* Provide a layer */
}
.meContainerAlpha
{
position: absolute;
top: -30px; /* Move it UP 30px */
left: 0px;
z-index: 2; /* Place it on top of the other layer */
display: none; /* Hide it */
background-color: rgba(150,150,150,0.5);
}
.meContainerAlpha:hover
{
display: inline; /* Show it */
}
Then you'd need to place these in divs inside your <li>.
<ul>
<li class="me">
<div class="meContainer">
<div class="meContainerLink">
<img="dummy.png">
</div>
<div class="meContainerAlpha">
</div>
</div>
</li>
<li class="me">
<div class="meContainer">
<div class="meContainerLink">
<img="dummy.png">
</div>
<div class="meContainerAlpha">
</div>
</div>
</li>
</ul>
I don't recall ever trying this method inside embedded <li> tags, so it may behave oddly at first. You may have to abandon <li> and switch to a different <div> structure entirely.
another potential option that should be more cross browser than :after could be:
.me:hover span { display: hidden; }