I want to recreate our mobile page navigation for our AMP site. The problem is that it has multiple levels - so there are lists in the list. Like this:
<ul>
<li>section</li>
<li>
section
<span>some button that open a sub navigation via javascript</span>
<ul>
<li>subsection</li>
...
</ul>
</li>
...
</ul>
However even it's quite simple in AMP this seems to be tricky. I couldn't find any example. According to https://www.ampproject.org/docs/reference/components/amp-sidebar an amp-sidebar within an amp-sidebar is not possible since amp-sidebar has to be a child of body. Using a list in a list can't be used like on the mobile page that easily because: Javascript magic to toggle the subnav is restricted. :hover also won't work to show the subnav since it's for mobile devices.
Is there a valid solution to this problem and if yes how is it done?
Yes It is possible to create a multilevel navigation with AMP sidebar.
Here is example
Code :
<!doctype html>
<html amp>
<head>
<meta charset="utf-8">
<link rel="canonical" href="hello-world.html">
<meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
<style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}#-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}#-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}#-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}#-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}#keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style><noscript><style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style></noscript>
<style amp-custom>
amp-sidebar {background: #f0f0f0;width: 215px;}
amp-sidebar .submenu {background: #f0f0f0;bottom: 0;/*box-shadow: 0 3px 20px 0 rgba(0, 0, 0, 0.075);*/left: 0;position: fixed;right: 0;top: 0;-webkit-transform: translateX(-100%);transform: translateX(-100%);-webkit-transition: -webkit-transform 233ms cubic-bezier(0, 0, 0.21, 1);transition: -webkit-transform 233ms cubic-bezier(0, 0, 0.21, 1);
transition: transform 233ms cubic-bezier(0, 0, 0.21, 1); transition: transform 233ms cubic-bezier(0, 0, 0.21, 1), -webkit-transform 233ms cubic-bezier(0, 0, 0.21, 1)}
amp-sidebar input:checked+.submenu {-webkit-transform: translateX(0);transform: translateX(0);overflow-y:auto;}
amp-sidebar input[type="checkbox"] {position: absolute;visibility: hidden}
amp-sidebar .menu-item {color: #000;display: block;position: relative;text-transform: none}
amp-sidebar .menu-layer .items {left: 0;position: absolute;right: 0;}/*** overflow-x: hidden;overflow-y: scroll; 27 june ***/
amp-sidebar .menu-layer .submenu .items {overflow-x: hidden;overflow-y: scroll;}
amp-sidebar .menu-layer.primary {height: 100%;position: relative}
amp-sidebar .menu-layer.primary .items { bottom: 0px;top:50px;padding: 0 10px;}
amp-sidebar .menu-layer.secondary { z-index: 2}
amp-sidebar .menu-layer.tertiary { z-index: 3}
amp-sidebar .menu-layer.secondary .items, amp-sidebar .menu-layer.tertiary .items {bottom:0;top:60px;}
amp-sidebar .has-sub-level::after {width: 15px;height: 15px;content: '';position: absolute;right: 15px; top: calc(50% - 8px); background:url(https://image.flaticon.com/icons/svg/271/271228.svg) no-repeat;}
amp-sidebar .close-button { border: 0; position: absolute;left: 10px;top: 10px; width: 35px;height: 35px;background:url(https://image.flaticon.com/icons/svg/32/32178.svg) no-repeat; background-size:25px; font-size: 0px;font-family:arial, sans-serif;}
amp-sidebar .return-button {color: #b3b3b3;left: 15px;position: absolute;top: 22px;font-size: 0px;}
amp-sidebar .return-button::before {border: 0;content: '';margin-right: 5px;position: relative;top: 0px;background: url(https://image.flaticon.com/icons/svg/109/109618.svg) no-repeat; width: 30px;height: 30px;display: block;}
amp-sidebar .submenu .return-button + #menu-button {display: none;}
amp-sidebar .menu-layer.secondary .items .level1 li {border-bottom: 1px solid #e4e4e4;padding: 8px 5px;}
.hamburger{-webkit-appearance:none;background:url(https://image.flaticon.com/icons/svg/128/128453.svg) no-repeat;border:0px;font-size:0px;width:48px;height:48px;padding:0;margin:5px; outline:none;z-index:99;background-position:center center;}
.sideNavi > a, .sideNavi > label, .items > a, .items > label {font-size:14px;text-decoration:none;padding: 8px 10px;font-family:arial, sans-serif;font-weight: bold;}
span.whats-new{color:#dc4a36;}
.secondary.submenu >.items>label{font-size:12px;text-transform: uppercase}
.submenu a{font-size: 12px;font-family:arial, sans-serif;padding: 5px 10px;}
span.top-sale-style{background:#3e3e3e;margin-left: 4px;font-size:10px;padding: 0px 3px;text-transform: capitalize;color:#fff;font-weight: bold;border-radius: 2px;display:inline-block;height:15px; line-height:15px;}
.top-new-style {background:#fff;border: 1px solid #e55049;border-radius: 2px;color: #e55049;
display: inline-block;font-size: 10px;font-weight: bold;margin-left: 4px;padding: 0px 3px;text-transform: capitalize;height:15px;line-height:15px;}
.sale-style {background:#3e3e3e;border-radius: 2px; color: #fff;display: inline-block;height: 15px;line-height: 15px;font-size: 10px; margin-left: 4px;padding: 0px 3px;text-transform: capitalize; vertical-align: middle;}
</style>
<script async src="https://cdn.ampproject.org/v0.js"></script>
<script async custom-element="amp-sidebar" src="https://cdn.ampproject.org/v0/amp-sidebar-0.1.js"></script>
<script async custom-element="amp-form" src="https://cdn.ampproject.org/v0/amp-form-0.1.js"></script>
</head>
<body>
<amp-sidebar id='sidebar' side='left' layout='nodisplay'>
<form class="menu-layer primary" action="/" target="_top">
<button type="reset" class="close-button" id="menu-button" on='tap:sidebar.toggle'>X</button>
<div class="items sideNavi">
<label class="menu-item item-layer-1 has-sub-level active"><input type="checkbox">
Lavel 1 (with sub menu)
<div class="submenu menu-layer secondary">
<div class="return-button">Back</div>
<button type="reset" class="close-button" id="menu-button" on='tap:sidebar.toggle'>X</button>
<div class="items">
<a class="menu-item item-layer-2" href="#">Lavel 2</a>
<a class="menu-item item-layer-2" href="#">Lavel 2</a>
</div>
</div>
</label>
<label class="menu-item item-layer-1 has-sub-level active"><input type="checkbox">
Lavel 1
<div class="submenu menu-layer secondary">
<div class="return-button">Back</div>
<button type="reset" class="close-button" id="menu-button" on='tap:sidebar.toggle'>X</button>
<div class="items">
<label class="menu-item item-layer-1 has-sub-level"><input type="checkbox">
Lavel 2
<div class="submenu menu-layer secondary">
<div class="return-button">Back</div>
<button type="reset" class="close-button" id="menu-button" on='tap:sidebar.toggle'>X</button>
<div class="items">
<a class="menu-item item-layer-2" href="#">Lavel 3</a>
<a class="menu-item item-layer-2" href="#">Lavel 3</a>
<a class="menu-item item-layer-2" href="#">Lavel 3</a>
</div>
</div>
</label>
<label class="menu-item item-layer-1 has-sub-level"><input type="checkbox">
Lavel 2
<div class="submenu menu-layer secondary">
<div class="return-button">Back</div>
<button type="reset" class="close-button" id="menu-button" on='tap:sidebar.toggle'>X</button>
<div class="items">
<a class="menu-item item-layer-2" href="#">Lavel 3</a>
<a class="menu-item item-layer-2" href="#">Lavel 3</a>
<a class="menu-item item-layer-2" href="#">Lavel 3</a>
</div>
</div>
</label>
</div>
</div>
</label>
<a class="menu-item item-layer-3" href="#"> Lavel 1 (without sub menu) </a>
</div>
</form>
</amp-sidebar>
<button class="tab hamburger" id="menu-button" on='tap:sidebar.toggle'>=</button>
</body>
</html>
This is an alternate to the checkbox hack. Using amp-bind to switch classes and some accessibility consideration: https://codepen.io/RickRX/pen/BEzyJm (still WIP)
<!doctype html>
<html ⚡ lang="en">
<head>
<meta charset="utf-8">
<title>AMP Mobile Nav</title>
<link rel="canonical" href="index.php">
<meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
<style amp-boilerplate>
body {
-webkit-animation: -amp-start 8s steps(1, end) 0s 1 normal both;
-moz-animation: -amp-start 8s steps(1, end) 0s 1 normal both;
-ms-animation: -amp-start 8s steps(1, end) 0s 1 normal both;
animation: -amp-start 8s steps(1, end) 0s 1 normal both
}
#-webkit-keyframes -amp-start {
from {
visibility: hidden
}
to {
visibility: visible
}
}
#-moz-keyframes -amp-start {
from {
visibility: hidden
}
to {
visibility: visible
}
}
#-ms-keyframes -amp-start {
from {
visibility: hidden
}
to {
visibility: visible
}
}
#-o-keyframes -amp-start {
from {
visibility: hidden
}
to {
visibility: visible
}
}
#keyframes -amp-start {
from {
visibility: hidden
}
to {
visibility: visible
}
}
</style><noscript><style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style></noscript>
<script async src="https://cdn.ampproject.org/v0.js"></script>
<script async custom-element="amp-sidebar" src="https://cdn.ampproject.org/v0/amp-sidebar-0.1.js"></script>
<script async custom-element="amp-bind" src="https://cdn.ampproject.org/v0/amp-bind-0.1.js"></script>
<style amp-custom>
body {
width: auto;
margin: 0;
padding: 0;
background: lightgrey;
font-family: "Lato", Arial, sans-serif;
font-size: 16px;
line-height: 1.6;
}
.headerbar {
background: #ffffff;
height: 50px;
width: 100%;
display: flex;
flex-direction: row;
}
.hamburger,
.site-name {
flex: 1 1 auto;
padding: 10px;
}
amp-sidebar,
amp-sidebar .submenu {
width: 100%;
height: 100%;
}
amp-sidebar .main-menu,
amp-sidebar .submenu {
overflow: auto;
}
amp-sidebar .submenu {
top: 0;
left: 0;
position: fixed;
}
amp-sidebar .hide-submenu {
visibility: hidden;
transform: translateX(-100%);
}
amp-sidebar .show-submenu {
visibility: visible;
transform: translateX(0);
}
amp-sidebar .hide-parent {
visibility: hidden;
}
amp-sidebar .truncate {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
amp-sidebar .link-container {
display: block;
height: 44px;
line-height: 44px;
border-bottom: 1px solid #f0f0f0;
padding: 0 1rem;
}
amp-sidebar a {
min-width: 44px;
min-height: 44px;
text-decoration: none;
cursor: pointer;
}
amp-sidebar .submenu-icon {
padding-right: 44px;
}
amp-sidebar .submenu-icon::after {
position: absolute;
right: 0;
height: 44px;
width: 44px;
content: '';
background-size: 1rem;
background-image: url('data:image/svg+xml;utf8, <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M5 3l3.057-3 11.943 12-11.943 12-3.057-3 9-9z"/></svg>');
background-repeat: no-repeat;
background-position: center;
}
amp-sidebar .controls {
display: flex;
height: 50px;
background: #f0f0f0;
}
amp-sidebar .controls a {
display: flex;
justify-content: center;
align-items: center;
}
amp-sidebar .controls span {
line-height: 50px;
margin: 0 auto;
}
amp-sidebar nav>.controls>a:first-of-type {
visibility: hidden;
}
amp-sidebar .controls a svg {
height: 1rem;
width: 1rem;
}
amp-sidebar .link-icon {
float: left;
height: 44px;
margin-right: 0.75rem;
}
amp-sidebar .link-icon>svg {
height: 44px;
}
amp-sidebar {
background: #fff;
color: #232323;
fill: #232323;
text-transform: uppercase;
letter-spacing: 0.18rem;
font-size: 0.875rem;
}
amp-sidebar a {
color: #232323;
text-transform: none;
letter-spacing: normal;
}
div[class*="-sidebar-mask"] {
opacity: 0.8;
}
amp-sidebar a:hover {
text-decoration: underline;
fill: #232323;
}
amp-sidebar .view-all {
font-style: italic;
font-weight: bold;
}
</style>
</head>
<body>
<amp-sidebar id='header-sidebar' side='left' layout='nodisplay'>
<nav>
<div
class="controls"
[class]="hidePrimary ? 'controls hide-parent' : 'controls'"
aria-label="Menu controls">
<a
tabindex="0"
role="button"
aria-label="">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M16.67 0l2.83 2.829-9.339 9.175 9.339 9.167-2.83 2.829-12.17-11.996z"/></svg> </a>
<span class="truncate">Menu</span>
<a
tabindex="0"
role="button"
on='tap:header-sidebar.toggle'
aria-label="Close Menu">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M24 20.188l-8.315-8.209 8.2-8.282-3.697-3.697-8.212 8.318-8.31-8.203-3.666 3.666 8.321 8.24-8.206 8.313 3.666 3.666 8.237-8.318 8.285 8.203z"/></svg> </a>
</div>
<div class="main-menu items"
role="menu"
aria-label="Menu links"
[class]="hidePrimary ? 'main-menu items hide-parent' : 'main-menu items'">
<a
class="link-container submenu-icon truncate"
role="menuitem"
tabindex="0"
aria-label="Mens"
aria-haspopup="true"
on="tap:AMP.setState({level_1_0: !level_1_0, hidePrimary: !hidePrimary})"
title="Mens">
Mens </a>
<div class="submenu hide-submenu"
[class]="(level_1_0 ? 'submenu show-submenu' : 'submenu hide-submenu') + ' ' + (hideSecondary ? 'hide-parent' : '')"
role="menu"
aria-label="Mens">
<div
class="controls"
[class]="hideSecondary ? 'controls hide-parent' : 'controls'"
aria-label="Mens controls">
<a
tabindex="0"
role="button"
on="tap:AMP.setState({level_1_0: !level_1_0, hidePrimary: !hidePrimary})"
aria-label="Return to Menu">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M16.67 0l2.83 2.829-9.339 9.175 9.339 9.167-2.83 2.829-12.17-11.996z"/></svg> </a>
<span class="truncate">Mens</span>
<a
tabindex="0"
role="button"
on='tap:header-sidebar.toggle'
aria-label="Close Mens">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M24 20.188l-8.315-8.209 8.2-8.282-3.697-3.697-8.212 8.318-8.31-8.203-3.666 3.666 8.321 8.24-8.206 8.313 3.666 3.666 8.237-8.318 8.285 8.203z"/></svg> </a>
</div>
<a class="link-container truncate" tabindex="0" href="/link" title="Clothing" >
Clothing </a>
<a class="link-container truncate" tabindex="0" href="/link" title="Footwear" >
Footwear </a>
<a class="link-container truncate" tabindex="0" href="/link" title="Accessories" >
Accessories </a>
<a class="link-container view-all truncate" href="/link" title="Mens" >
View All Mens </a>
</div>
<a
class="link-container submenu-icon truncate"
role="menuitem"
tabindex="0"
aria-label="Womens"
aria-haspopup="true"
on="tap:AMP.setState({level_1_1: !level_1_1, hidePrimary: !hidePrimary})"
title="Womens">
Womens </a>
<div class="submenu hide-submenu"
[class]="(level_1_1 ? 'submenu show-submenu' : 'submenu hide-submenu') + ' ' + (hideSecondary ? 'hide-parent' : '')"
role="menu"
aria-label="Womens">
<div
class="controls"
[class]="hideSecondary ? 'controls hide-parent' : 'controls'"
aria-label="Womens controls">
<a
tabindex="0"
role="button"
on="tap:AMP.setState({level_1_1: !level_1_1, hidePrimary: !hidePrimary})"
aria-label="Return to Menu">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M16.67 0l2.83 2.829-9.339 9.175 9.339 9.167-2.83 2.829-12.17-11.996z"/></svg> </a>
<span class="truncate">Womens</span>
<a
tabindex="0"
role="button"
on='tap:header-sidebar.toggle'
aria-label="Close Womens">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M24 20.188l-8.315-8.209 8.2-8.282-3.697-3.697-8.212 8.318-8.31-8.203-3.666 3.666 8.321 8.24-8.206 8.313 3.666 3.666 8.237-8.318 8.285 8.203z"/></svg> </a>
</div>
<a class="link-container truncate" tabindex="0" href="/link" title="Clothing" >
Clothing </a>
<a class="link-container truncate" tabindex="0" href="/link" title="Footwear" >
Footwear </a>
<a class="link-container truncate" tabindex="0" href="/link" title="Accessories" >
Accessories </a>
<a class="link-container view-all truncate" href="/link" title="Womens" >
View All Womens </a>
</div>
<a
class="link-container submenu-icon truncate"
role="menuitem"
tabindex="0"
aria-label="Kids"
aria-haspopup="true"
on="tap:AMP.setState({level_1_2: !level_1_2, hidePrimary: !hidePrimary})"
title="Kids">
Kids </a>
<div class="submenu hide-submenu"
[class]="(level_1_2 ? 'submenu show-submenu' : 'submenu hide-submenu') + ' ' + (hideSecondary ? 'hide-parent' : '')"
role="menu"
aria-label="Kids">
<div
class="controls"
[class]="hideSecondary ? 'controls hide-parent' : 'controls'"
aria-label="Kids controls">
<a
tabindex="0"
role="button"
on="tap:AMP.setState({level_1_2: !level_1_2, hidePrimary: !hidePrimary})"
aria-label="Return to Menu">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M16.67 0l2.83 2.829-9.339 9.175 9.339 9.167-2.83 2.829-12.17-11.996z"/></svg> </a>
<span class="truncate">Kids</span>
<a
tabindex="0"
role="button"
on='tap:header-sidebar.toggle'
aria-label="Close Kids">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M24 20.188l-8.315-8.209 8.2-8.282-3.697-3.697-8.212 8.318-8.31-8.203-3.666 3.666 8.321 8.24-8.206 8.313 3.666 3.666 8.237-8.318 8.285 8.203z"/></svg> </a>
</div>
<a class="link-container truncate" tabindex="0" href="/link" title="Clothing" >
Clothing </a>
<a class="link-container truncate" tabindex="0" href="/link" title="Footwear" >
Footwear </a>
<a class="link-container truncate" tabindex="0" href="/link" title="Accessories" >
Accessories </a>
<a class="link-container view-all truncate" href="/link" title="Kids" >
View All Kids </a>
</div>
<a
class="link-container submenu-icon truncate"
role="menuitem"
tabindex="0"
aria-label="Brands"
aria-haspopup="true"
on="tap:AMP.setState({level_1_3: !level_1_3, hidePrimary: !hidePrimary})"
title="Brands">
Brands </a>
<div class="submenu hide-submenu"
[class]="(level_1_3 ? 'submenu show-submenu' : 'submenu hide-submenu') + ' ' + (hideSecondary ? 'hide-parent' : '')"
role="menu"
aria-label="Brands">
<div
class="controls"
[class]="hideSecondary ? 'controls hide-parent' : 'controls'"
aria-label="Brands controls">
<a
tabindex="0"
role="button"
on="tap:AMP.setState({level_1_3: !level_1_3, hidePrimary: !hidePrimary})"
aria-label="Return to Menu">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M16.67 0l2.83 2.829-9.339 9.175 9.339 9.167-2.83 2.829-12.17-11.996z"/></svg> </a>
<span class="truncate">Brands</span>
<a
tabindex="0"
role="button"
on='tap:header-sidebar.toggle'
aria-label="Close Brands">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M24 20.188l-8.315-8.209 8.2-8.282-3.697-3.697-8.212 8.318-8.31-8.203-3.666 3.666 8.321 8.24-8.206 8.313 3.666 3.666 8.237-8.318 8.285 8.203z"/></svg> </a>
</div>
<a
class="link-container submenu-icon truncate"
role="menuitem"
tabindex="0"
aria-label="A-B"
aria-haspopup="true"
on="tap:AMP.setState({level_2_0: !level_2_0, hideSecondary: !hideSecondary})"
title="A-B">
A-B </a>
<div class="submenu hide-submenu"
[class]="(level_2_0 ? 'submenu show-submenu' : 'submenu hide-submenu') + ' ' + (hideTertiary ? 'hide-parent' : '')"
role="menu"
aria-label="A-B">
<div
class="controls"
[class]="hideTertiary ? 'controls hide-parent' : 'controls'"
aria-label="A-B controls">
<a
tabindex="0"
role="button"
on="tap:AMP.setState({level_2_0: !level_2_0, hideSecondary: !hideSecondary})"
aria-label="Return to Brands">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M16.67 0l2.83 2.829-9.339 9.175 9.339 9.167-2.83 2.829-12.17-11.996z"/></svg> </a>
<span class="truncate">A-B</span>
<a
tabindex="0"
role="button"
on='tap:header-sidebar.toggle'
aria-label="Close A-B">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M24 20.188l-8.315-8.209 8.2-8.282-3.697-3.697-8.212 8.318-8.31-8.203-3.666 3.666 8.321 8.24-8.206 8.313 3.666 3.666 8.237-8.318 8.285 8.203z"/></svg> </a>
</div>
<a class="link-container truncate" tabindex="0" href="/link" title="Armani" >
Armani </a>
<a class="link-container truncate" tabindex="0" href="/link" title="BOSS" >
BOSS </a>
</div>
<a
class="link-container submenu-icon truncate"
role="menuitem"
tabindex="0"
aria-label="C-F"
aria-haspopup="true"
on="tap:AMP.setState({level_2_1: !level_2_1, hideSecondary: !hideSecondary})"
title="C-F">
C-F </a>
<div class="submenu hide-submenu"
[class]="(level_2_1 ? 'submenu show-submenu' : 'submenu hide-submenu') + ' ' + (hideTertiary ? 'hide-parent' : '')"
role="menu"
aria-label="C-F">
<div
class="controls"
[class]="hideTertiary ? 'controls hide-parent' : 'controls'"
aria-label="C-F controls">
<a
tabindex="0"
role="button"
on="tap:AMP.setState({level_2_1: !level_2_1, hideSecondary: !hideSecondary})"
aria-label="Return to Brands">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M16.67 0l2.83 2.829-9.339 9.175 9.339 9.167-2.83 2.829-12.17-11.996z"/></svg> </a>
<span class="truncate">C-F</span>
<a
tabindex="0"
role="button"
on='tap:header-sidebar.toggle'
aria-label="Close C-F">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M24 20.188l-8.315-8.209 8.2-8.282-3.697-3.697-8.212 8.318-8.31-8.203-3.666 3.666 8.321 8.24-8.206 8.313 3.666 3.666 8.237-8.318 8.285 8.203z"/></svg> </a>
</div>
<a class="link-container truncate" tabindex="0" href="/link" title="Channel" >
Channel </a>
<a class="link-container truncate" tabindex="0" href="/link" title="CK Jeans" >
CK Jeans </a>
</div>
</div>
</div>
</nav>
</amp-sidebar>
<header class="headerbar">
<div class="hamburger" role="button" aria-label="mobile menu" on="tap:header-sidebar.toggle" tabindex="0">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M24 6h-24v-4h24v4zm0 4h-24v4h24v-4zm0 8h-24v4h24v-4z"/></svg>
</div>
<div class="site-name">AMP Mobile Nav</div>
</header>
<div class="info">
<p>some content...</p>
</div>
</body>
</html>
You can try using the amp-nested-menu component. You just have to expand the amp-sidebar if you are using it. Here an example:
<amp-sidebar id="sidebar" layout="nodisplay" side="left">
<amp-nested-menu layout="fill">
<ul>
<li>
<div amp-nested-submenu-open class="nested-arrow">Test</div>
<div amp-nested-submenu>
<ul>
<li><div amp-nested-submenu-close>go back</div></li>
<li>First link</li>
....
</ul>
</div>
</li>
</ul>
</amp-nested-menu></amp-sidebar>
Related
I am facing a weird problem, till yesterday the page was loading properly but after 2 days. the page is loading with images being zoomed.. (i.e. actual image size ) unable to figure out.
main.html
<!DOCTYPE html>
{% load static %}
<html>
<head>
<title>Ecom</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1" />
<link rel="stylesheet" type="text/css" href="{% static 'css/main.css' %}">
<script type="text/javascript">
var user = '{{request.user}}'
function getToken(name) {
let cookieValue = null;
if (document.cookie && document.cookie !== '') {
const cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
const cookie = cookies[i].trim();
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
const csrftoken = getToken('csrftoken');
function getCookie(name) {
var cookieArr = document.cookie.split(";");
for (var i = 0; i < cookieArr.length; i++) {
var cookiePair = cookieArr[i].split("=");
console.log('cookiePair:',cookiePair);
if(name==cookiePair[0].trim()) {
return decodeURIComponent(cookiePair[1]);
}
}
return null;
}
var cart = JSON.parse(getCookie('cart'))
if(cart == undefined) {
cart = {}
console.log('Cart was created');
document.cookie = 'cart=' + JSON.stringify(cart) +";domain=;path=/"
}
console.log('Cart:',cart);
</script>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<a class="navbar-brand" href="{% url 'store' %}">Ecom</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="{% url 'store' %}">Store <span class="sr-only">(current)</span></a>
</li>
</ul>
<div class="form-inline my-2 my-lg-0">
Login
<a href="{% url 'cart' %}">
<img id="cart-icon" src="{% static 'images/cart.png' %}">
</a>
<p id="cart-total">{{cartItems}}</p>
</div>
</div>
</nav>
<div class="container">
{% block content %}
{% endblock content %}
<br>
<nav aria-label="...">
{%if page.paginator %}
<ul class="pagination">
{%if NoOfProducts > 6 %}
<li class="page-item {% if not prev_page_url %} disabled {% endif %} ">
<a class="page-link" href="{{ prev_page_url }}" tabindex="-1" aria-disabled="true">Previous</a>
</li>
{% for n in page.paginator.page_range %}
{% if page.number == n %}
<li class="page-item active" aria-current="page">
<a class="page-link" href=="?page={{n}}">{{n}}<span class="sr-only">(current)</span></a>
</li>
{% elif n > page.number|add:-3 and n < page.number|add:3 %}
<li class="page_item">
<a class="page-link" href ="?page={{n}}">{{n}}</a>
</li>
{% endif %}
{% endfor %}
<li class="page-item {% if not next_page_url %} disabled {% endif %} ">
<a class="page-link" href="{{next_page_url}}">Next</a>
</li>
{% endif %}
</ul>
{% endif %}
</nav>
</div>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
<script type="text/javascript" src="{% static 'js/cart.js' %}"></script>
</body>
</html>
main.css
body{
background-color: hsl(0, 0%, 98%);
}
h1,h2,h3,h4,h5,h6{
color:hsl(0, 0%, 30%);
}
.box-element{
box-shadow:hsl(0, 0%, 80%) 0 0 16px;
background-color: #fff;
border-radius: 4px;
padding: 10px;
}
.thumbnail{
width: 100%;
height: 200px;
-webkit-box-shadow: -1px -3px 5px -2px rgba(214,214,214,1);
-moz-box-shadow: -1px -3px 5px -2px rgba(214,214,214,1);
box-shadow: -1px -3px 5px -2px rgba(214,214,214,1);
}
.product{
border-radius: 0 0 4px 4px;
}
.bg-dark{
background-color: #4f868c!important;
}
#cart-icon{
width:25px;
display: inline-block;
margin-left: 15px;
}
#cart-total{
display: block;
text-align: center;
color:#fff;
background-color: red;
width: 20px;
height: 25px;
border-radius: 50%;
font-size: 14px;
}
.col-lg-4, .col-lg-6, .col-lg-8, .col-lg-12{
margin-top: 10px;
}
.btn{
border-radius: 0;
}
.row-image{
width: 100px;
}
.form-field{
width:250px;
display: inline-block;
padding: 5px;
}
.cart-row{
display: flex;
align-items: flex-stretch;
padding-bottom: 10px;
margin-bottom: 10px;
border-bottom: 1px solid #ececec;
}
.quantity{
display: inline-block;
font-weight: 700;
padding-right:10px;
}
.chg-quantity{
width: 12px;
cursor: pointer;
display: block;
margin-top: 5px;
transition:.1s;
}
.chg-quantity:hover{
opacity: .6;
}
.hidden{
display: none!important;
}
Output:
Can someone help me how to resolve the issue? what setting needs to change thus enable to load correct image sizes .. ( only the problem facing the size of the images... )
Thank you very much
caching issue, try press F5 while holding shift button and it solved the problem
This is the array
[
{
"TO":"test#gmail.com",
"FROM":"nathanoluwaseyi#gmail.com",
"SUBJECT":"subject 1",
"NAME":"Oluwaseyi Oluwapelumi",
"MESSAGE-DATE":[
[
"Hey eniayomi heeyyy",
"2019-12-03 20:49:07"
]
]
},
{
"TO":"test#gmail.com",
"FROM":"pelz#gmail.com",
"SUBJECT":"Thanks for contacting R",
"NAME":"",
"MESSAGE-DATE":[
[
"Thanks for contacting me! Once i check my email, i shall definitely get back.",
"2019-08-18 19:48:10"
],
[
"will check it.",
"2019-08-18 19:48:10"
]
]
}
]
i need it to display on the angular frontend.
this is the mail.component.html file
<div class="card-body p-0">
<div class="float-left" style="width: 330px; height: 430px; border-right: 1px solid #dad9d9; overflow-x: hidden; overflow-y: auto;">
<div class="p-2 profile-card" style="width: 315px; height: 100px; border-bottom: 1px solid #dad9d9;" *ngFor="let mail of dataservice.data; let i = index;" (click)="viewMail(mail.MESSAGE_DATE,mail.FROM,mail.NAME,mail.DATE,i)" [ngClass]="{'highlight': selectedIndex === i}">
<div class="row">
<div class="col-md-3 pt-2">
<div class="rounded-circle shadow" style="background-image: url('images/avt.jpg'); background-repeat: round; height: 70px; width: 70px;">
<div style="height: 20px; width: 20px; border: 3px solid white;" class="rounded-circle bg-success"></div>
</div>
</div>
<div class="col-md-7 p-0 pl-3 pt-4" style="line-height: 12px;">
<p style="font-size:18px;"><b>{{mail.FROM}}</b></p>
<p style="font-size:13px;">{{mail.NAME }}.</p>
</div>
<div class="col-md-2 p-0 pt-3" style="line-height:11px;">
<p class="text-secondary" style="font-size:12px;">20m <i class="fa fa-star fa-md" aria-hidden="true"></i></p>
</div>
</div>
</div>
this is the data.service.ts file
mail_det() {
this.message = 'Welcome!';
console.log(this.message);
this.staff_email=sessionStorage.getItem('email');
console.log(this.staff_email)
this.http.get(this.domain_protocol + this.f_domain_name+'/api/v1.0/get_user_detail/?id='+this.staff_email)
.subscribe((res) => {
this.data = res
console.log(this.data)
})
}
this is the mail.component.ts file
viewMail(mail, mailer, mailee, user_date, _index: number) {
this.router.navigate(['mail/'+ mailer])
console.log(mail)
console.log(mailer)
console.log(user_date)
this.message = ''
sessionStorage.setItem('mailer', mailer)
sessionStorage.setItem('mailee', mailee);
sessionStorage.setItem('user_date', user_date)
console.log(sessionStorage.getItem('mailer'))
this.user_message = mail;
this.mailee = mailee;
this.user_date = user_date;
this.selectedIndex = _index;
}
i am doing something wrong. The only thing i get to show is the mail.FROM and mail.SUBJECT. I know this is because of the array in the mesage part. I dont know how to go about that.
In Data.service.ts
mail_det() {
this.message = 'Welcome!';
console.log(this.message);
this.staff_email=sessionStorage.getItem('email');
console.log(this.staff_email)
this.http.get(this.domain_protocol + this.f_domain_name+'/api/v1.0/get_user_detail/?id='+this.staff_email);
}
in mail.component.ts
public data: Array<any> = [];
constructor(public dataSrv: DataService <-- this is the class name of the data service you created; import it)
ngOnInit(){
this.dataSrv.mail_det().subscribe(result =>{
console.log(result); <-- your api response;
this.data = result;
}, error => {console.log(error);
});
}
in mail.component.html
<div class="card-body p-0">
<div class="float-left" style="width: 330px; height: 430px; border-right: 1px solid #dad9d9; overflow-x: hidden; overflow-y: auto;">
<div class="p-2 profile-card" style="width: 315px; height: 100px; border-bottom: 1px solid #dad9d9;" *ngFor="let mail of data; let i = index;" (click)="viewMail(mail.MESSAGE_DATE,mail.FROM,mail.NAME,mail.DATE,i)" [ngClass]="{'highlight': selectedIndex === i}">
<div class="row">
<div class="col-md-3 pt-2">
<div class="rounded-circle shadow" style="background-image: url('images/avt.jpg'); background-repeat: round; height: 70px; width: 70px;">
<div style="height: 20px; width: 20px; border: 3px solid white;" class="rounded-circle bg-success"></div>
</div>
</div>
<div class="col-md-7 p-0 pl-3 pt-4" style="line-height: 12px;">
<p style="font-size:18px;"><b>{{mail.FROM}}</b></p>
<p style="font-size:13px;">{{mail.NAME }}.</p>
</div>
<div class="col-md-2 p-0 pt-3" style="line-height:11px;">
<p class="text-secondary" style="font-size:12px;">20m <i class="fa fa-star fa-md" aria-hidden="true"></i></p>
</div>
</div>
</div>
How to make a dropdown .top-bar? Foundation hides it by display: none; and i can't use transition height.
Below header structure
<div class="title-bar" data-responsive-toggle="example-animated-menu" data-hide-for="large">
<div class="toggle-button"><button class="menu-icon" type="button" data-toggle></button></div>
<div class="title-bar-title show-for-sr" >Menu</div>
</div>
<nav class="top-bar navigation" id="example-animated-menu">
<div class="dropdown menu navigation-list" data-dropdown-menu >
<ul id="menu-menu " class="menu algin-right vertical medium-horizontal" data-responsive-menu="drilldown medium-dropdown" data-auto-height="true" data-animate-height="true">
<li>X</li>
<li>X</li>
<li>X</li>
<li>X</li>
<li>X</li>
<li>X</li>
</ul>
</div>
<form class="search">
<div class="grid-x grid-padding-x">
<div class="small-9 cell">
<input type="text" id="middle-label" placeholder="Search">
</div>
<div class="small-3 cell">
<label for="middle-label" class="text-left middle"><img src="img/ico-search.png" alt="#" /></label>
</div>
</div>
</form>
</nav>
You can display the .top-bar as a child of .dropdown-pane and then override the display: none; with display: block.
Then simply add a max-height transition to the .top-bar going from 0 to the height of your choice.
HTML:
<div class="dropdown-pane"
id="example-animated-menu"
data-dropdown
data-position="bottom"
data-alignment="bottom"
data-v-offset="40px">
<nav class="top-bar navigation" ></nav>
</div>
CSS:
.dropdown-pane {
width: 100%;
padding: 0;
display: block;
max-height: 0;
-webkit-transition: all 0.11s ease;
transition: all 0.11s ease;
}
.top-bar {
max-height: 0;
overflow: hidden;
}
.is-open .top-bar {
max-height: 76px;
-webkit-transition: max-height 0.5s ease;
transition: max-height 0.5s ease;
overflow: hidden;
}
See a JSFiddle demo
I have a list of items. Each item has an icon (fontawesome) on the left and text on the right. Unfortunately I'm not able to align the items.
My CSS and HTML code is:
.colle ul {
margin-left: -20px;
}
.colle ul li {
list-style-type: none;
margin-bottom: 35px;
display: flex;
}
.colle ul li i {
margin-right: 25px;
}
.colle ul li p {
margin: 0;
}
<div class="colle">
<ul>
<li>
<i class="fa fa-black-tie" style="color:#0e3c68;font-size:230%;"></i>
<div style="color: #0e3c68;">
<strong>DIRECTOR: </strong><br> <strong>Francisco </strong><br><div style="color: #0e3c68;font-size:80%;line-height: 12px;">Universidad Francisco de Vitoria</div>
</div></li> </ul>
<li> <i class="fa fa-suitcase" style="color:#0e3c68;font-size:230%;"></i> <div style="color: #0e3c68;">
<strong>COMITÉ CIENTÍFICO ASESOR: </strong><br> <strong>Francisco </strong><br><div style="color: #0e3c68;font-size:80%;line-height: 12px;">Universidad Francisco de Vitoria</div>
</li>
<li> <i class="fa fa-mobile" style="color:#0e3c68;font-size:230%;"></i> <div style="color: #0e3c68;"><strong>CONTACTO: </strong><br> <strong>Francisco</strong><br><div style="color: #0e3c68;line-height: 12px;">9135567 ext. 2115</div> </li>
</div>
(Unfortunately the code snippet can't run the icons) What I'm trying to do is having all perfectly aligned. You can find an image of what I have done up to now. Anyone can help me?
Since you are trying to have two columns, your flex container (the "li") should have two child elements. One should be the (i.fa) icon, and the other should be a container (e.g "div") with all of the info that you want next to the icon.
Then, you need to give at least the icon a fixed width. This is what will align things.
I modified your code to do that, and also replaced your inline styles with classes. That just makes it more maintainable and readable.
See my version here: https://codepen.io/anon/pen/aEzQgM
Here is the code:
.colle ul {
margin-left: -20px;
}
.colle ul li {
list-style-type: none;
margin-bottom: 35px;
display:flex;
}
.colle ul li i.fa {
color:#0e3c68;
font-size:230%;
width:1em;
height:1em;
}
.data1{
color: #0e3c68;
font-weight:bold;
}
.data2{
color: #0e3c68;
font-size:80%;
line-height: 12px;
}
.data3{
color: #0e3c68;
font-size:80%;
line-height: 12px;
}
.colle ul li p {
margin: 0;
}
<div class="colle">
<ul>
<li>
<i class="fa fa-black-tie">x</i>
<div class="data">
<div class="data1">DIRECTOR:</div>
<div class="data2">Francisco</div>
<div class="data3">Universidad Francisco de Vitoria</div>
</div>
</li>
<li>
<i class="fa fa-suitcase">x</i>
<div class="data">
<div class="data1">COMITÉ CIENTÍFICO ASESOR:</div>
<div class="data2">Francisco</div>
<div class="data3">Universidad Francisco de Vitoria</div>
</div>
</li>
<li>
<i class="fa fa-mobile">x</i>
<div class="data">
<div class="data1">CONTACTO:</div>
<div class="data2">Francisco</div>
<div class="data3">9135567 ext. 2115</div>
</div>
</li>
</ul>
</div>
.colle ul li {
list-style-type: none;
margin-bottom: 35px;
display: flex;
align-items: center;
}
align-items: center will align both your flex items vertically center.
this is my question:
is it possible to set equal heights to last items in row?
My masonry layout is on two columns and I would like to set the last two items with the same height...
UPDATE
This is a simple starting code that I think to use because I haven't yet begun to work on it:
/* ---- js ---- */
jQuery(document).ready(function($) {
var $container = $('#container');
$container.imagesLoaded(function () {
$container.masonry({
isInitLayout: false,
isFitWidth: true
});
$container.masonry('layout');
});
});
/* ---- css ---- */
.wrapper{
margin: 0 auto;
}
#container {
width: 100%;
height: 1200px;
background: #DDD;
margin: 0 auto;
}
#container:after {
content: '';
display: block;
clear: both;
}
.item {
float: left;
width: 500px;
background: #0D8;
border-color: hsla(0, 0%, 0%, 0.7);
}
.item img{
max-width: 100%;
}
<!-- ---- html ---- -->
<div class="wrapper">
<div id="container">
<div class="item"><img src="img/image1.jpg" width="500" height="200" alt="" /></div>
<div class="item"><img src="img/image2.jpg" width="500" height="450" alt="" /></div>
<div class="item"><img src="img/image3.jpg" width="500" height="300" alt="" /></div>
<div class="item"><img src="img/image4.jpg" width="500" height="260" alt="" /></div>
<div class="item"><img src="img/image5.jpg" width="500" height="500" alt="" /></div>
<div class="item"><img src="img/image6.jpg" width="500" height="420" alt="" /></div>
<div class="item"><img src="img/image7.jpg" width="500" height="260" alt="" /></div>
<div class="item"><img src="img/image8.jpg" width="500" height="430" alt="" /></div>
</div>
</div>
Thank you.
Fabio