How to create mega menu in Angular Material - angular-material

I am trying to build multi level mega menu with Angular Material - mat-menu. Now the problem here with me is I wanted to have mega menu like in bootstrap like this but I ended up building this in Angular material. I have changed CSS for changing the width like this:
.cdk-overlay-connected-position-bounding-box {
position: absolute;
z-index: 1000;
display: flex;
flex-direction: column;
min-width: 1px;
min-height: 1px;
}
.cdk-overlay-pane {
position: absolute;
pointer-events: auto;
box-sizing: border-box;
z-index: 1000;
display: flex;
max-width: 100%;
max-height: 100%;
}
How can I design mega menu in Angular Material like the image given below?
I am using Angular 7.3.1 (latest version).

Yes it is true that Material Design does not use this pattern. MatMenu is for Material Design menus which are overlay or 'popup' type. The mega menu is nothing more than a toolbar with a roll down panel as suggested by G.Tranter. But the mega menu can be achieved by writing custom css. I dont know is this a correct way to do or not. I have mat-menu like this is .html file
<button mat-button [matMenuTriggerFor]="menu" class="my-full-width-menu">Menu</button>
<mat-menu #menu="matMenu">
<button mat-menu-item>Item 1</button>
<button mat-menu-item>Item 2</button>
<button mat-menu-item>Item 3</button>
<button mat-menu-item>Item 4</button>
</mat-menu>
And added the following css for full-width of submenu in style.css
.mat-menu-panel {
min-width: 90vw !important;
max-width: 95vw !important;
margin-left: -8px;
margin-top: 24px;
}
Now the concern is of responsive design. For that purpose I need to write #media Query in the component css file like this
#media (min-width: 576px) {
button.mat-menu-item {
width: 100%;
float: left;
}
}
/* Medium devices (tablets, 768px and up)*/
#media (min-width: 768px) {
button.mat-menu-item {
width: 50%;
float: left;
}
}
/* Large devices (desktops, 992px and up)*/
#media (min-width: 992px) {
button.mat-menu-item {
width: 33.333%;
float: left;
}
}
/* very large devices (large desktops, 1200px and up)*/
#media (min-width: 1200px) {
button.mat-menu-item {
width: 25%;
float: left;
}
}
/* Extra large devices (large desktops, 1550px and up)*/
#media (min-width: 1550px) {
button.mat-menu-item {
width: 25%;
float: left;
}
}
Here is the StackBlitz demo of mega menu in mat-menu. This works for my requirement.

I had the same Question and finally I had to handle it by my self and I dont know its the correct way or not ; but its worked
<button mat-raised-button [matMenuTriggerFor]="profileManagementMenu" class="option-button">
{{'ProfileManagement'|translate}}
</button>
<mat-menu #profileManagementMenu="matMenu" class="mega-menu" xPosition="before">
<div fxLayout="row" fxLayoutAlign="start" class="p-1">
<div fxLayout="column" fxLayoutAlign="start" class="p-1 config">
<button mat-menu-item>
{{'Col11'|translate}}
</button>
<button mat-menu-item>
{{'Col12'|translate}}
</button>
</div>
<span class="border" style="opacity: .3"></span>
<div fxLayout="column" fxLayoutAlign="start" class="p-1 config">
<h7 fxLayoutAlign="center">header2</h7>
<button mat-menu-item>
{{'Col21'|translate}}
</button>
<button mat-menu-item>
{{'Col22'|translate}}
</button>
<button mat-menu-item>
{{'Col23'|translate}}
</button>
<button mat-menu-item>
{{'Col24'|translate}}
</button>
<button mat-menu-item>
{{'Col25'|translate}}
</button>
<button mat-menu-item>
{{'Col26'|translate}}
</button>
</div>
</div>
</mat-menu>
and its the scss:
.mega-menu .mat-menu-content {
min-width: 112px;
overflow: auto;
-webkit-overflow-scrolling: touch;
max-height: calc(100vh - 48px);
outline: 0;
background: none;
color: white !important;
:hover {
background: none;
color: white;
}
}
.mat-menu-item:hover {
background: #338ACF !important;
color: white;
}
.mat-menu-content {
min-width: 112px;
overflow: auto;
-webkit-overflow-scrolling: touch;
max-height: calc(100vh - 48px);
outline: 0;
opacity: .95;
background: #2688d6b8;
color: white !important;
}

Related

JQuery Mobile - Responsive Panel - force panel to stay open on wider screens - pure CSS solution

I need to make a Responsive Panel to stay open on wider screens using a pure CSS solution. I create a short jsfiddle: https://jsfiddle.net/ezbdaft4/
In this example the menu button will disappear on wider screens (if the container is expanded). I need that panel to stay open also on wider screens (without scripts, only CSS).
The trigger should be #media ( min-width: 35em ) {} but I can not figure out how.
I'm not an expert, but I think I've solved the problem. I'm writing here the solution in the hope that it will be useful to others.
Demo: https://jsfiddle.net/210woeLg/2/
HTML
<div data-role="panel" id="mypanel" data-display="push" data-theme="b" data-position-fixed="true" data-swipe-close="true" data-position="left">
<ul data-role="listview">
<li>Home</li>
<li>Links</li>
<li>Exit</li>
</ul>
</div>
<div data-role="header" data-position="fixed" data-tap-toggle="false">
menu
<h1>My App</h1>
</div>
<div role="main" class="ui-content" id="mycontent">
<p>expand this container</p>
</div>
</div>
CSS
#media ( min-width: 55em) {
.ui-responsive-panel > .ui-header,
.ui-responsive-panel > .ui-footer,
.ui-responsive-panel > .ui-panel-wrapper {
left: 17em;
right: -17em;
width: auto;
margin-right: 17em;
margin-left: 1px;
}
.ui-panel-animate.ui-panel-page-content-position-left {
-webkit-transform: none;
-moz-transform: none;
transform: none;
}
.ui-responsive-panel .ui-panel-animate {
-webkit-transition: none;
-webkit-transition-duration: 0s;
-moz-transition: none;
transition: none;
}
.ui-responsive-panel .ui-panel-closed {
width: 17em;
visibility: visible;
clip: auto;
}
.ui-responsive-panel .ui-panel {
margin-right: 0;
}
.ui-responsive-panel .ui-panel-animate.ui-panel-position-left.ui-panel-display-push {
-webkit-transform: none;
-moz-transform: none;
transform: none;
}
.hide-on-large-screen {
visibility: hidden;
}
}

Display flex and bootstrap .col-md-20 doesnt work properly in safari on Iphone 6 or plus

I am having a strange trouble with mobile displaying on mobile in Safari browser. The problem is that it doesn't respect the display flex and bootstrap .col-md-20 on Iphone 6 or plus.
I still having another problem on icon in mobile menu on the same case.
The behavior is that:
The second column is broking and font-awersome icon too
In Chrome this behavior is not happening:
Works fine on Chrome
I tried to add this but do not solve my problem:
#media screen and (-webkit-min-device-pixel-ratio:0) and (min-color-index:0) {
#search {(;
background:blue;
width: 100%
);}
.fx {(;
display: -webkit-box;
);}
nav.header-user-links.u-in-blk.mid {(;
margin: 0 auto;
text-align: center;
);}
.header-navigation-options{(;
width: 100%;
);}
.product-box-image-link img {(;
/*webkit-transform: translate(-50%,-50%);*/
-webkit-transform: translate(-50%, -50%);
);}
ul.fx-main.mc-wrap.note-wrap {(;
padding-bottom: 20px;
);}
input.form-control.cart-product-quantity {(;
padding: 0 10px;
);}
.toggle-categories {(;
text-rendering: optimizeLegibility;
);}
}
.fx.fx-rows.row {
display: flex;
display: -webkit-flex;
flex-wrap: wrap;
-webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap;
#include displayFlex;
#include flexWrap(wrap);
}
.fx.col-md-20.col-sm-4.col-xs-6 {
/**
* Height AUTO is important, because adding flex to the child makes it vertically
* stretch by default. So that means height: 100% won't work.
*/
height: auto;
//IE fallback
display: inline-block;
//Modern Browsers
display: flex;
display: -webkit-flex;
height: auto;
//IE fallback
display: inline-block;
#include flexboxDisplay;
#include flex(0 0 auto);
...
/**
* For some unknown reason, it still didn't work until I subracted 1% from
* the width of each breakpoint I was using.
*/
}
#media screen and (min-width: map_get($grid-breakpoints, 'lg')) {
width: percentage((3 / 12)) - 1%;
}
#media screen and (min-width: map_get($grid-breakpoints, 'md')) {
width: percentage((4 / 12)) - 1%;
}
#media screen and (max-width: map_get($grid-breakpoints, 'sm')) {
width: percentage((6 / 12)) - 1%;
}
}
}
Any idea how to solve that?
<div class="fx col-md-20 col-sm-4 col-xs-6">
<div class="product-box">
<a class="product-box-image-link u-blk u-center-blk" href="http://marketplace.app/teste/produto/new-hNng" role="link">
<img class="u-blk u-center-blk" src="http://marketplace.app/assets/img/product/default.jpg" alt="new" role="img">
</a>
<h2 class="product-box-title">
<a class="product-box-link text-uppercase" href="http://marketplace.app/teste/produto/new-hNng" title="new">
new
</a>
</h2>
<div class="fx fx-rows fx-space-justify">
<div class="product-box-price">
<small class="product-box-business-model">
Varejo
</small>
<h3 class="spotlight-product-price">
R$ 25,00
</h3>
</div>
</div>
<div class="product-box-footer">
<a class="spotlight-product-sku u-blk" href="http://marketplace.app/teste" title="Teste">
Teste
</a>
</div>
</div>
</div>

Button with display: flex does not work in Safari. Causing size and alignment issues

I'm having some problem with display: flex in both Safari and iOS Safari.
Safari has alignment issues and iOS Safari has both alignment and size issues. Is this expected or a valid bug in Safari?
Edit: Also, height in percentage on the child SVG inside the Button does not work either. This works in all other browsers.
I mane another more advanced example with SVG elements, and I added an anchor to compare to the button. More advanced example here
My simple example
HTML:
<div class="flex">
<div class="col col-1">
<button class="sub-col">
<span class="span"></span>
</button>
<div class="sub-col">2</div>
<div class="sub-col">3</div>
</div>
<div class="col col-2"></div>
<div class="col col-3"></div>
</div>
CSS:
.flex {
display: flex;
flex-direction: column;
height: 80vh;
background: #666666;
position: fixed;
width: 100%;
}
.col {
display: inherit;
flex: 1 1 auto;
background: #ccffcc;
}
.col-1 {
flex: 0 0 10vh;
background: #ffcccc;
}
.col-3 {
flex: 0 0 10vh;
background: #ccccff;
}
.sub-col {
display: inherit;
flex: 0 0 25%;
justify-content: center;
align-items: center;
}
.span {
width: 10px;
height: 10px;
background: #ffaaaa;
}
Screenshots:
This is what it should look like, and does in Chrome, FF and Edge (Haven't tested IE)
This is what it looks like in Safari
And this is iOS Safari
You can't set display flex to button and fieldset elements. chk below link. Wrap your element with div or span tags
https://github.com/philipwalton/flexbugs#9-some-html-elements-cant-be-flex-containers
The button element, and a couple other elements for that matter, cannot be flex containers in some browsers. Safari is one of them.
You can try a simple solution though, if you like. The idea is, you wrap your .span inside .span-wrapper. Then you let .span-wrapper be your flex container.
Like that:
HTML:
<div class="flex">
<div class="col col-1">
<button class="sub-col">
<span class="span-wrapper">
<span class="span"></span>
</span>
</button>
<div class="sub-col">2</div>
<div class="sub-col">3</div>
</div>
<div class="col col-2"></div>
<div class="col col-3"></div>
</div>
CSS:
.flex {
display: flex;
flex-direction: column;
height: 80vh;
background: #666666;
position: fixed;
width: 100%;
}
.col {
display: inherit;
flex: 1 1 auto;
background: #ccffcc;
}
.col-1 {
flex: 0 0 10vh;
background: #ffcccc;
}
.col-3 {
flex: 0 0 10vh;
background: #ccccff;
}
.sub-col {
display: inherit;
flex: 0 0 25%;
justify-content: center;
align-items: center;
}
.span {
width: 10px;
height: 10px;
background: #ffaaaa;
}
.span-wrapper {
display: flex;
flex-basis: 100%;
justify-content: center;
align-items: center;
}

Ionic CSS Styling Off when Deployed to iOS but fine everywhere else

So when I am looking at my app on android phones and in the browser, the header (and sub header) looks like the following
When I am running on iOS emulator, or deploying to iOS phone, it looks like the following:
The markup looks like the following
<ion-header-bar class="bar item-input-inset search">
<div class="buttons buttons-left header-item">
<span class="left-buttons">
<button class="button button-icon button-clear ion-navicon" ng-click="showMenu()">
</button>
</span>
</div>
<label class="item-input-wrapper search">
<input placeholder="Search..." ng-model="model.searchTerm" ng-change="updateSearchTerm(model.searchTerm,model.quickSearchType)" type="text">
</label>
<button class="button button-clear" ng-click="clearSearch()">
<i class="icon" ng-class="{'ion-close':model.searchTerm.length > 0}"></i>
</button>
</ion-header-bar>
<ion-header-bar class="bar bar-sub-header item-input-inset action-sub-header">
<button ng-style="model.quickSearchType == 'featured' && {'font-weight': 'bold'}"
style="color:#fff;"
class="button button-clear col col-33"
ng-click="quickSearch('featured',model.searchTerm)">
FEATURED
</button>
<button class="button button-clear col col-33"
ng-style="model.quickSearchType == 'nearby' && {'font-weight': 'bold'}"
style="color:#fff;"
ng-click="quickSearch('nearby',model.searchTerm)">
NEARBY
</button>
<button class="button button-clear col col-33"
style="color:#fff;"
ng-style="model.quickSearchType == 'recent' && {'font-weight': 'bold'}"
ng-click="quickSearch('recent',model.searchTerm)">
RECENT
</button>
</ion-header-bar>
The CSS I have is the following:
.action-sub-header {
background-color: #007fff;
}
.item-input-inset {
display: -webkit-box;
display: -webkit-flex;
display: -moz-box;
display: -moz-flex;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
-webkit-align-items: center;
-moz-align-items: center;
align-items: center;
position: relative;
overflow: hidden;
padding: 10.66667px;
}
.bar-header {
top: 0;
border-top-width: 0;
border-bottom-width: 1px;
}
.bar {
display: -webkit-box;
display: -webkit-flex;
display: -moz-box;
display: -moz-flex;
display: -ms-flexbox;
display: flex;
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
position: absolute;
right: 0;
left: 0;
z-index: 9;
box-sizing: border-box;
padding: 5px;
width: 100%;
height: 44px;
border-width: 0;
border-style: solid;
border-top: 1px solid transparent;
border-bottom: 1px solid #ddd;
background-color: white;
/* border-width: 1px will actually create 2 device pixels on retina; */
background-size: 0;
}
The ion-header-bar has a specific css on ios to add space on top of it for the iOS statusbar. You have to override it in your case.
To test the ios specific css in your browser, edit the classes on the body tag. Replace platform-browser by platform-ios and platform-macintel or platform-windows by paltform-cordova.
When you have do that, you'll be able to see the specific style applied by the ionic css:
.platform-ios.platform-cordova:not(.fullscreen) .bar-header:not(.bar-subheader) > * {
margin-top: 20px;
}
You just need to override it.
You need to add ionic.Platform.fullScreen(); to your $ionicPlatform.ready function.

Mobile Safari shows hidden back face when in tab view

I made a simple flippable element using common techniques and found some strange behavior in Mobile Safari on iOS 7 (older version also may be affected, unfortunately I can't test them at the moment older versions also seem to be affected), please see the images below or visit a demo directly on your iOS device.
Editable markup and stylesheet
Full screen view to visit on your iOS device
<div class="flippable">
<input id="flippable-trigger" type="checkbox">
<label for="flippable-trigger" class="flippable-faces">
<div class="flippable-face-front">
Front
</div>
<div class="flippable-face-back">
Back
</div>
</label>
</div>
body {
font: 1em/0 Arial;
background-color: silver;
}
.flippable {
position: relative;
float: left;
width: 10rem;
height: 10rem;
-webkit-perspective: 800;
}
.flippable input[type="checkbox"] {
display: none;
}
.flippable-faces,
.flippable-face-front,
.flippable-face-back {
position: absolute;
width: 100%;
height: 100%;
}
.flippable-faces {
-webkit-transform-style: preserve-3d;
-webkit-transition: 600ms;
}
.flippable-face-front,
.flippable-face-back {
position: absolute;
width: 100%;
height: 100%;
line-height: 10rem;
text-align: center;
-webkit-box-shadow: 0 0 1rem gray;
-webkit-backface-visibility: hidden;
}
.flippable-face-front {
color: black;
background-color: white;
}
.flippable-face-back {
color: white;
background-color: black;
-webkit-transform: rotateY(180deg);
}
.flippable input[type="checkbox"]:checked ~ .flippable-faces {
-webkit-transform: rotateY(180deg);
}
It appears that repositioning your divs fixes the issue. I don't have an answer as to why that was happening though. Sorry. Working Example | Example for iPhone
<div class="flippable">
<input id="flippable-trigger" type="checkbox" >
<label for="flippable-trigger" class="flippable-faces">
<div class="flippable-face-back">
Back
</div>
<div class="flippable-face-front">
Front
</div>
</label>
</input>
</div>

Resources