expand nav in mobile and tablet - javascript

Why is the menu bar not visible in tablet mode. I have to click on the colored part to see it. It works well in mobile mode but has problems in tablet mode. I checked everything but did not understand how the collapsible__content class does not work in tablet mode.
Now in tablet mode, the navigation is not visible and I have to click on the gray bar to make the menus appear, while in tablet mode, you do not need to click on the menu to be seen.
index.html
<header>
<nav class="nav collapsible">
<a class="nav__brand" href="#">Gustoso</a>
<svg class="icon icon--white nav__toggler">
<use href="images/sprite.svg#menu"></use>
</svg>
<ul class="list nav__list collapsible__content">
<li class="nav__item">
Welcome<span class="between__nav">~</span>
</li>
<li class="nav__item">
Menu<span class="between__nav">~</span>
</li>
<li class="nav__item">
reservations<span class="between__nav">~</span>
</li>
<li class="nav__item">
News<span class="between__nav">~</span>
</li>
<li class="nav__item">
Contact
</li>
</ul>
</nav>
</header>
<script src="js/main.js"></script>
style.css
.list {
list-style-type: none;
padding-left: 0;
}
/* Navigation Bar */
header {
background: rgba(86, 83, 76, 0.5294117647058824);
}
.nav {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
align-items: center;
padding: 0.6rem 1rem;
}
.nav__list {
width: 100%;
margin: 0;
}
.nav__item {
padding: 0.9rem 0.2rem;
border-bottom: 1px solid #826c6c;
}
.nav__item > a:hover {
font-weight: bolder;
}
.nav__item > a {
color: var(--color-heading);
text-transform: uppercase;
font-size: 1.7rem;
}
.nav__item > a span {
display: none;
}
.between__nav {
margin: auto 0.9rem;
font-size: 1.4rem;
font-weight: 400;
}
.nav__brand {
font-family: scriptina, Arial, Helvetica, sans-serif;
font-size: 3rem;
letter-spacing: 9px;
line-height: 24px;
color: #ffffff;
transform: translateY(-11px);
}
.nav__toggler {
opacity: 0.5;
cursor: pointer;
transition: all 0.15s;
}
.nav.collapsible--expanded .nav__toggler {
opacity: 1;
box-shadow: 0 0 0 3px #666;
border-radius: 5px;
transform: rotate(-90deg);
}
#media screen and (min-width: 768px) {
.nav__toggler {
display: none;
}
.nav__list {
max-height: 100%;
opacity: 1;
width: auto;
display: flex;
font-size: 1.6rem;
}
.nav__item {
border: 0;
}
.nav__item > a span {
display: inline-flex;
}
}
/* Collapsibles */
.collapsible__content {
max-height: 0;
opacity: 0;
overflow: hidden;
transition: all 0.3s;
}
.collapsible--expanded .collapsible__content {
max-height: 100vh;
opacity: 1;
}
main.js
const collapsibles = document.querySelectorAll(".collapsible");
collapsibles.forEach((item) =>
item.addEventListener("click", function () {
this.classList.toggle("collapsible--expanded");
})
);

Related

How to style & toggle notifications list?

I made a nav bar using nav and li tags, including a notifications icon, I am trying to make notifications nested list to show notifications, and use JavaScript to toggle/hide the menu, so far no luck. I've been looking for snippets online to support my logic, but I am stuck in the styling part and the JavaScript functionality. code below:
/* When the user clicks on the button,
toggle between hiding and showing the dropdown content */
function myFunction() {
document.getElementById("myDropdown").classList.toggle("show");
}
// Close the dropdown if the user clicks outside of it
window.onclick = function(e) {
if (!e.target.matches('.dropbtn')) {
var myDropdown = document.getElementById("myDropdown");
if (myDropdown.classList.contains('show')) {
myDropdown.classList.remove('show');
}
}
}
html {
scroll-behavior: smooth;
}
* {
font-family: 'Roboto', sans-serif;
font-style: normal;
padding: 0;
margin: 0;
text-decoration: none;
}
.container {
display: flex;
flex-direction: column;
min-height: 100vh;
}
main {
flex: 1;
}
::-webkit-scrollbar {
width: 1.32vmin;
}
/*
::-webkit-scrollbar-track{
border: 0.53vmin solid rgba(7, 67, 146, 0.17);
box-shadow: inset 0 0 0.33vmin 0.26vmin rgba(7, 67, 146, 0.17);
}
*/
::-webkit-scrollbar-thumb {
background: #074392;
border-radius: 0vmin;
}
::-webkit-scrollbar-button {
height: 7.45vmin;
background: #074392;
}
body {
font-weight: 400;
font-size: 2.12vmin;
background-color: #FFFFFF;
/*overflow: hidden;*/
height: 100%;
}
h1 {
margin-left: 3vmin;
}
h5 {
margin: 2vmin 3vmin;
position: absolute;
width: 14.72vmin;
font-weight: 500;
font-size: 2.65vmin;
letter-spacing: 0.79vmin;
color: #FFFFFF;
display: inline;
}
nav {
background-color: #074392;
height: 7.42vmin;
width: 100%;
/*position: relative;*/
/*overflow: hidden;*/
position: sticky;
top: 0;
}
img.logo {
margin: 1.855vmin 3vmin;
height: 3.5vmin;
width: 7vmin;
}
nav ul {
float: right;
margin: 1.855vmin 2vmin;
}
nav ul li {
display: inline-block;
}
nav ul li::before {
content: " ";
padding: 0vmin 0.5vmin;
}
nav ul li a {
color: white;
/*margin: 0vmin 1vmin;*/
/*border-top-left-radius: 1.326vmin;
border-top-right-radius: 1.326vmin;
border-bottom-left-radius: 1.326vmin;
border-bottom-right-radius: 1.326vmin;*/
}
a.active,
a:hover {
font-variation-settings: 'FILL' 1;
}
.checkbtn {
color: #ffffff;
float: left;
cursor: pointer;
display: none;
margin: 1.855vmin 3vmin;
}
#check {
display: none;
}
#check:checked~ul {
left: 0;
}
.dropdown {}
.dropdown .dropbtn {
cursor: pointer;
border: none;
outline: none;
background-color: #074392;
color: #FFFFFF;
}
.dropdown:hover .dropbtn,
.dropbtn:focus {
color: #FFFFFF;
font-variation-settings: 'FILL' 1;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #0743922B;
width: 37.5vmin;
overflow-wrap: break-word;
transform: translateX(-56%);
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
z-index: 1;
}
.dropdown-content a {
float: none;
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
text-align: justify;
}
.dropdown-content a:hover {
background-color: #0743922B;
}
.show {
display: block;
}
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD#20..48,100..700,0..1,-50..200" />
<div class="container">
<nav>
<input type="checkbox" id="check">
<label for="check" class="checkbtn">
<i class="material-symbols-rounded" style="font-size:3.5vmin;" title="Menu">menu</i>
</label>
<h5>LOGO</h5>
<ul>
<li>
<i class="material-symbols-rounded" style="font-size:3.5vmin;" title="Home">home</i>
</li>
<!-- <li> <i class="material-symbols-rounded" style="font-size:3.5vmin;" title="Notifications">notifications</i> -->
<li class="dropdown"><button class="dropbtn" onclick="myFunction()"><i class="material-symbols-rounded" style="font-size:3.5vmin;" title="Notifications">notifications</i></button>
<div class="dropdown-content" id="myDropdown">
<div>Link 1</div>
<div>Link 2</div>
<div>Link asasdasdasdasdasdsadsadasdasdasdasd asddasdas asd asd asd dasd asd</div>
</div>
</li>
<li>
<i class="material-symbols-rounded" style="font-size:3.5vmin;" title="Tasks">task</i>
</li>
<li>
<i class="material-symbols-rounded" style="font-size:3.5vmin;" title="Profile">person</i>
</li>
</ul>
<script type="text/javascript" src="JS/ActiveTab.js"></script>
<script type="text/javascript" src="JS/ToggleNotifications.js"></script>
</nav>
<main>
<h1>Example Page</h1>
</main>
</div>
By default set a display: none on the dropdown element and set a display: block on the hover pseudo-class of the dropdown element so when a hover event is triggered the dropdown appears.
Also, you can use classList.toggle method to remove if exists or to add if not exist the class.
Remove
Just add the following to the .css:
#myDropdown {
display: none;
}
#myDropdown.show {
display: block;
}
Remove onclick="myFunction()". And replace the .js with:
const myDropdown = document.getElementById('myDropdown')
addEventListener('click', event => {
let dropbtn = event.target.closest('button.dropbtn')
if (!dropbtn) return myDropdown.classList.remove('show')
console.log('hii')
myDropdown.classList.toggle('show')
})

How to ensure only 1 nav bar is dropped when clicking on specific element?

I have this situation where I am clicking on a button in my nav bar and would like the corresponding nav bar to drop, I've drafted the HTML and attempted to create the JavaScript for this but haven't been able to successfully implement it.
const dropdownButtons = document.querySelectorAll(".dropdownButton");
const dropdownNav = document.querySelectorAll(".dropdown");
const navBar = document.querySelector("#navBar");
function toggleDropdown() {
dropdownNav.forEach((x => x.classList.toggle("show")))
}
dropdownButtons.forEach((btn) => {
btn.addEventListener("click", (e) => {
const button = e.target;
toggleDropdown(button)
})
})
#import url('https://fonts.googleapis.com/css2?family=Overpass:wght#300;600&family=Ubuntu:wght#400;500;700&display=swap');
* {
padding: 0;
margin: 0;
box-sizing: border-box;
font-family: 'Overpass', sans-serif;
font-family: 'Ubuntu', sans-serif;
}
:root {
--dark-red-cta: hsl(356, 100%, 66%);
--light-red-cta: hsl(355, 100%, 74%);
--dark-blue-heading: hsl(208, 49%, 24%);
--white: hsl(0, 0%, 100%);
--grayish-blue-footer: hsl(240, 2%, 79%);
--dark-grayish-blue: hsl(207, 13%, 34%);
--very-dark-blue: hsl(240, 10%, 16%);
}
/* NAVBAR */
nav {
padding: 2em 10em;
}
nav img {
padding-right: 2em;
}
nav,
.siteNav {
display: flex;
align-items: center;
justify-content: space-between;
}
ul {
list-style-type: none;
}
li {
display: inline;
}
button img {
margin-left: .5em;
}
button {
cursor: pointer;
background: none;
border: none;
color: white;
font-size: .9em;
}
header {
text-align: center;
background-image: url(/images/bg-pattern-intro-desktop.svg), linear-gradient(100deg, hsl(13, 100%, 72%), hsl(353, 100%, 62%));
background-size: 218%, auto;
background-position: 25% 52%;
height: 75vh;
border-radius: 0 0 0 6em;
}
header h1 {
color: white;
font-size: 3em;
font-weight: 500;
padding: 2em 0 .5em 0;
}
header p {
color: white;
padding: 0 0 2em 0;
}
.startButton,
.loginButton {
background-color: white;
color: var(--dark-red-cta);
border-radius: 30px;
width: 140px;
padding: 1.1em;
font-weight: bold;
}
.learnMoreButton {
color: white;
border-radius: 30px;
width: 140px;
padding: 1.1em;
border: 1px solid var(--white);
font-weight: bold;
}
/* For the drop down */
.dropdownItem {
position: relative;
}
.dropdown {
position: absolute;
background: var(--white);
border-radius: 8px;
padding: 1em;
text-align: left;
margin-top: 1em;
height: 14em;
width: 10em;
display: flex;
flex-direction: column;
justify-content: space-evenly;
visibility: hidden;
}
.show {
visibility: visible;
}
.rotateImg {
transform: rotate(90deg);
}
.dropdown li a {
color: black;
text-decoration: none;
}
.dropdown li a:hover {
font-weight: bold;
}
<nav>
<div class="siteNav">
<img src="/images/logo.svg" alt="Blogr logo">
<ul id="navBar">
<li class="dropdownItem">
<button class="dropdownButton">Product
<img src="/images/icon-arrow-light.svg" alt="Drop down arrow">
</button>
<ul class="dropdown dropdown-content">
<li>Overview</li>
<li>Pricing</li>
<li>Marketplace</li>
<li>Features</li>
<li>Integrations</li>
</ul>
</li>
<li class="dropdownItem">
<button class="dropdownButton">Company
<img src="/images/icon-arrow-light.svg" alt="Drop down arrow">
</button>
<ul class="dropdown dropdown-content">
<li>About</li>
<li>Team</li>
<li>Our Blog</li>
<li>Careers</li>
</ul>
</li>
<li class="dropdownItem">
<button class="dropdownButton">Connect
<img src="/images/icon-arrow-light.svg" alt="Drop down arrow">
</button>
<ul class="dropdown dropdown-content">
<li>Contact</li>
<li>Newsletter</li>
<li>LinkedIn</li>
</ul>
</li>
</ul>
</div>
<div class="login">
<button class="loginButton">Login</button>
<button class="signUpButton">Sign Up</button>
</div>
</nav>
I'm currently successfully able to correspond a click and assign the correct class using this method but the only issue is that it adds it to all 3 drop downs and I just cannot wrap my head around event bubbling so would appreciate a little bit of hand holding for this example.
I am looping through the buttons and then triggering a function which should then make the relative drop down visible by updating it's visibility. This works and it only shows the 3rd option because it updates all 3 classes instead of one.
I tried using a current target approach on this but wasn't able to get it to work since I couldn't add a classList to e.target. Could someone point out to me where I'm going wrong on this one?
EDIT:
Added CSS file as it would be relevant to see the positioning of the elements understandably.
Pass a prop index so that you would toggle the class .show only to that particular dropdown and not all
const dropdownButtons = document.querySelectorAll(".dropdownButton");
const dropdownNav = document.querySelectorAll(".dropdown");
const navBar = document.querySelector("#navBar");
function toggleDropdown(ind) {
dropdownNav[ind].classList.toggle("show")
}
dropdownButtons.forEach((btn, index) => {
btn.addEventListener("click", (e) => {
const button = e.target;
toggleDropdown(index)
})
})

How to have my css navbar be proportional to the page

My (epic) navbar gets messed up when the window is to small, how can I have it shrink proportionally to the page? I've tried a few things but it just shrinks the text size, but the text still ends up longer than the width of the window, with the title in the top left overlapping onto the text.
Here is the html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
</head>
<body>
<header id="nav-wrapper">
<nav id="nav">
<div class="nav left">
<span class="gradient skew">
<h1 class="logo un-skew">RiseUpOnario.ca</h1>
</span>
<button id="menu" class="btn-nav"><span class="fas fa-bars"></span></button>
</div>
<div class="nav right">
<span class="nav-link-span"><span class="u-nav">Home</span></span>
<span class="nav-link-span"><span class="u-nav">Blog</span></span>
<span class="nav-link-span"><span class="u-nav">Join</span></span>
<span class="nav-link-span"><span class="u-nav">Donate</span></span>
<span class="nav-link-span"><span class="u-nav">MPP Finder</span></span>
<span class="nav-link-span"><span class="u-nav">About Us</span></span>
<span class="nav-link-span"><span class="u-nav">Contact</span></span>
</div>
</nav>
</header>
<main>
<section id="home">
</section>
<section id="blog">
</section>
<section id="join">
</section>
<section id="donate">
</section>
<section id="mppfinder">
</section>
<section id="aboutus">
</section>
<section id="contact">
</section>
</main>
</body>
</html>
<style>
/*-------------Reset-------------*/
button {
background: none;
box-shadow: none;
border: none;
cursor: pointer;
}
button:focus,
input:focus {
outline: 0;
}
html {
scroll-behavior: smooth;
}
/*-------------Layout-------------*/
body {
line-height: 1.5em;
padding: 0;
margin: 0;
}
section {
height: 100vh;
}
#home {
background-color: #ddd;
}
#blog {
background-color: #aaa;
}
#join {
background-color: #888;
}
#donate {
background-color: #666;
}
#mppfinder {
background-color: #ddd;
}
#aboutus {
background-color: #aaa;
}
#contact {
background-color: #666;
}
/*-------------Helpers-------------*/
.skew {
transform: skew(-20deg);
}
.un-skew {
transform: skew(20deg);
}
/*-------------Nav-------------*/
#nav-wrapper {
overflow: hidden;
width: 100%;
margin: 0 auto;
position: fixed;
top: 0;
left: 0;
z-index: 100;
}
#nav {
background-color: #fff;
box-shadow: 0px 3px 10px rgba(0, 0, 0, 0.1);
display: flex;
flex-direction: column;
font-family: "Saira Semi Condensed", sans-serif;
height: 4em;
overflow: hidden;
}
#nav.nav-visible {
height: 100%;
overflow: auto;
}
.nav {
display: flex;
height: 4em;
line-height: 4em;
flex-grow: 1;
}
.nav-link,
.logo {
padding: 0 1em;
}
span.gradient {
background: #e9b1a7;
background: -webkit-linear-gradient(45deg, #e9b1a7, #cf0a0a);
background: linear-gradient(45deg, #e9b1a7, #cf0a0a);
padding: 0 1em;
position: relative;
right: 1em;
margin-right: auto;
}
span.gradient:hover {
animation-name: logo-hover;
animation-duration: 0.3s;
animation-fill-mode: forwards;
animation-timing-function: cubic-bezier(0.17, 0.57, 0.31, 0.85);
}
h1.logo {
font-weight: 300;
font-size: 1.75em;
line-height: 0.75em;
color: #fff;
}
h1.logo a, a:active, a:hover, a:visited {
text-decoration: none;
color: #fff;
}
.nav-link {
text-transform: uppercase;
text-align: center;
border-top: 0.5px solid #ddd;
}
a:link, a:visited, a:active {
text-decoration: none;
color: #e9b1a7;
}
a:hover {
text-decoration: underline;
}
.right {
display: flex;
flex-direction: column;
height: 100%;
}
.btn-nav {
color: #e9b1a7;
padding-left: 2em;
padding-right: 2em;
}
#media (min-width: 800px) {
#nav-wrapper {
overflow: hidden;
}
#nav {
overflow: hidden;
flex-direction: row;
}
.nav-link {
border-top: none;
}
.right {
overflow: hidden;
flex-direction: row;
justify-content: flex-end;
position: relative;
left: 1.5em;
height: auto;
}
.btn-nav {
display: none;
}
.nav a:link.active, a:visited.active, a:active.active {
background: #e9b1a7;
background: -webkit-linear-gradient(45deg, #e9b1a7, #cf0a0a);
background: linear-gradient(45deg, #e9b1a7, #cf0a0a);
color: #fff;
}
.nav-link-span {
transform: skew(20deg);
display: inline-block;
}
.nav-link {
transform: skew(-20deg);
color: #777;
text-decoration: none;
}
.nav-link:last-child {
padding-right: 3em;
}
a:hover.nav-link:not(.active) {
color: #444;
background: #ddd;
background: linear-gradient(45deg, #fff, #ddd);
}
}
#keyframes logo-hover {
20% {
padding-right: 0em;
}
100% {
padding-right: 5em;
}
}
</style>
<script>
var util = {
mobileMenu() {
$("#nav").toggleClass("nav-visible");
},
windowResize() {
if ($(window).width() > 800) {
$("#nav").removeClass("nav-visible");
}
},
scrollEvent() {
var scrollPosition = $(document).scrollTop();
$.each(util.scrollMenuIds, function (i) {
var link = util.scrollMenuIds[i],
container = $(link).attr("href"),
containerOffset = $(container).offset().top,
containerHeight = $(container).outerHeight(),
containerBottom = containerOffset + containerHeight;
if (
scrollPosition < containerBottom - 20 &&
scrollPosition >= containerOffset - 20
) {
$(link).addClass("active");
} else {
$(link).removeClass("active");
}
});
}
};
$(document).ready(function () {
util.scrollMenuIds = $("a.nav-link[href]");
$("#menu").click(util.mobileMenu);
$(window).resize(util.windowResize);
$(document).scroll(util.scrollEvent);
});
</script>
Try implementing % in your stylesheet for fonts and divs!
For example, if you want a line of text or a container within a container to adjust in size when the parent container shrinks, you can have your interior elements set to something like
elementName{ max-width: 75%}
See if that helps with some of the elements inside the navWrapper.
Set the navbar's height to 10vh or less/more. ##vh = ##% of display height. There is also 100vw. = ##% of display width.

HTML drop-down menu with icons and text

I have taken over the code from this post. As I have explained there, I have basically no HTML knowledge, yet I have this HTML part of my project that I have to finish.
So, the code creates a bar with a drop-down menu, but I want to extend it to have an icon next to the names. I have looked at these examples but I can't figure out how to combine them. Is there someone who could help?
const projectsTab = document.getElementById('projects')
const tabName = projectsTab.querySelector('.tab-name')
const projectLinks = document.querySelector('.project-links')
projectsTab.addEventListener('click', e => {
const isOpen = projectLinks.classList.contains('open')
if (isOpen) projectLinks.classList.remove('open')
else projectLinks.classList.add('open')
})
// link event listeners
const links = [...projectLinks.children] // turn this into an array
links.forEach(link => link.addEventListener('click', e => {
tabName.innerText = link.innerText
}))
* {
padding: 0;
margin: 0;
box-sizing: border-box;
font-family: 'Segoe UI', sans-serif;
}
nav {
position: fixed;
width: 100%;
height: 50px;
background: #222;
top: 0;
left: 0;
color: white;
display: flex;
}
nav>* {
flex: 1;
}
#logo {
padding-left: 20px;
font-size: 30px;
text-transform: uppercase;
letter-spacing: 2px;
display: flex;
justify-content: flex-start;
align-items: center;
}
nav ul {
display: flex;
list-style: none;
height: 100%;
}
nav ul li {
position: relative;
flex: 1;
background: #222;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
transition: 0.2s;
}
nav ul li:hover {
background: #555;
}
.project-links {
position: absolute;
display: flex;
flex-direction: column;
justify-content: center;
left: 0;
top: 100%;
width: 100%;
background-color: white;
color: black;
/* This is the height of this div + height of the nav bar */
transform: translateY(-135%);
transition: 0.2s;
z-index: -1;
}
.project-links.open {
transform: translateY(0);
}
.project-link {
height: 50px;
display: flex;
align-items: center;
padding-left: 20px;
text-decoration: none;
color: white;
cursor: pointer;
transition: 0.2s;
background: #222;
color: white;
}
.project-link:hover {
background: #555;
}
<nav>
<div id="logo">Logo</div>
<ul>
<li>About</li>
<li id="projects">
<span class="tab-name">Projects</span>
<div class="project-links">
<a class="project-link" href="#">Link 1</a>
<a class="project-link" href="#">Link 2</a>
<a class="project-link" href="#">Link 3</a>
</div>
</li>
<li>Contact</li>
</ul>
</nav>
Assuming you want to use Font Awesome icons, just add the proper i tag referencing the right icon beside the text in the corresponding a tags.
const projectsTab = document.getElementById('projects')
const tabName = projectsTab.querySelector('.tab-name')
const projectLinks = document.querySelector('.project-links')
projectsTab.addEventListener('click', e => {
const isOpen = projectLinks.classList.contains('open')
if (isOpen) projectLinks.classList.remove('open')
else projectLinks.classList.add('open')
})
// link event listeners
const links = [...projectLinks.children] // turn this into an array
links.forEach(link => link.addEventListener('click', e => {
tabName.innerText = link.innerText
}))
document.addEventListener("click", e => {
if(!projectsTab.contains(e.target)){
projectLinks.classList.remove("open");
}
})
* {
padding: 0;
margin: 0;
box-sizing: border-box;
font-family: 'Segoe UI', sans-serif;
}
nav {
position: fixed;
width: 100%;
height: 50px;
background: #222;
top: 0;
left: 0;
color: white;
display: flex;
}
nav>* {
flex: 1;
}
#logo {
padding-left: 20px;
font-size: 30px;
text-transform: uppercase;
letter-spacing: 2px;
display: flex;
justify-content: flex-start;
align-items: center;
}
nav ul {
display: flex;
list-style: none;
height: 100%;
}
nav ul li {
position: relative;
flex: 1;
background: #222;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
transition: 0.2s;
}
nav ul li:hover {
background: #555;
}
.project-links {
position: absolute;
display: flex;
flex-direction: column;
justify-content: center;
left: 0;
top: 100%;
width: 100%;
background-color: white;
color: black;
/* This is the height of this div + height of the nav bar */
transform: translateY(-135%);
transition: 0.2s;
z-index: -1;
}
.project-links.open {
transform: translateY(0);
}
.project-link {
height: 50px;
display: flex;
align-items: center;
padding-left: 20px;
text-decoration: none;
color: white;
cursor: pointer;
transition: 0.2s;
background: #222;
color: white;
}
.project-link:hover {
background: #555;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<nav>
<div id="logo">Logo</div>
<ul>
<li>About</li>
<li id="projects">
<span class="tab-name">Projects</span>
<div class="project-links">
<a class="project-link" href="#"><i class="fa fa-envelope"></i> Link 1</a>
<a class="project-link" href="#"><i class="fa fa-envelope"></i> Link 2</a>
<a class="project-link" href="#"><i class="fa fa-envelope"></i> Link 3</a>
</div>
</li>
<li>Contact</li>
</ul>
</nav>
To close the dropdown when the user clicks elsewhere, add an event listener for click and check whether the target is a subchild of projectsTab.
Since your dropdown menu elements are already flex containers, you can simply add an image at the beginning of each of them, give them a class (icon) and change a bit the padding. Here I put icon { padding: 3px; } and I removed the 20px padding at the beginning of menu elements, because it squished the images against the text.
I also added some JavaScript to close the menu when you click elsewhere.
const projectsTab = document.getElementById('projects')
const tabName = projectsTab.querySelector('.tab-name')
const projectLinks = document.querySelector('.project-links')
projectsTab.addEventListener('click', e => {
const isOpen = projectLinks.classList.contains('open')
if (isOpen) projectLinks.classList.remove('open')
else projectLinks.classList.add('open')
})
addEventListener('click', e => {
var target = e.target;
if (!(target.classList.contains('project-link') || target.classList.contains('project-link') || target.classList.contains('tab-name') || target.id == "projects")) {
projectLinks.classList.remove('open');
} else {
e.stopPropagation();
}
});
// link event listeners
const links = [...projectLinks.children] // turn this into an array
links.forEach(link => link.addEventListener('click', e => {
tabName.innerText = link.innerText
}))
* {
padding: 0;
margin: 0;
box-sizing: border-box;
font-family: 'Segoe UI', sans-serif;
}
nav {
position: fixed;
width: 100%;
height: 50px;
background: #222;
top: 0;
left: 0;
color: white;
display: flex;
}
nav>* {
flex: 1;
}
#logo {
padding-left: 20px;
font-size: 30px;
text-transform: uppercase;
letter-spacing: 2px;
display: flex;
justify-content: flex-start;
align-items: center;
}
nav ul {
display: flex;
list-style: none;
height: 100%;
}
nav ul li {
position: relative;
flex: 1;
background: #222;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
transition: 0.2s;
}
nav ul li:hover {
background: #555;
}
.project-links {
position: absolute;
display: flex;
flex-direction: column;
justify-content: center;
left: 0;
top: 100%;
width: 100%;
background-color: white;
color: black;
/* This is the height of this div + height of the nav bar */
transform: translateY(-135%);
transition: 0.2s;
z-index: -1;
}
.project-links.open {
transform: translateY(0);
}
.project-link {
height: 50px;
display: flex;
align-items: center;
padding-left: 5px;
text-decoration: none;
color: white;
cursor: pointer;
transition: 0.2s;
background: #222;
color: white;
}
.project-link:hover {
background: #555;
}
.icon {
padding-right: 3px;
}
<nav>
<div id="logo">Logo</div>
<ul>
<li>About</li>
<li id="projects">
<span class="tab-name">Projects</span>
<div class="project-links">
<a class="project-link" href="#"><img class="icon" src="http://lorempixel.com/20/20/cats/">Link 1</a>
<a class="project-link" href="#"><img class="icon" src="http://lorempixel.com/20/20/cats/">Link 2</a>
<a class="project-link" href="#"><img class="icon" src="http://lorempixel.com/20/20/cats/">Link 3</a>
</div>
</li>
<li>Contact</li>
</ul>
</nav>
This is actually pretty easy just like the example you linked to first add the link to the icon library inside the <head></head> tag of your html:
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
then add the <i/> tag inside the <a></a> tag of your drop down. Your html code should look like so
<nav>
<div id="logo">Logo</div>
<ul>
<li>About</li>
<li id="projects">
<span class="tab-name">Projects</span>
<div class="project-links">
<a class="project-link" href="#"><i class="fa fa-home"/>Link 1</a>
<a class="project-link" href="#"><i class="fa fa-search"/>Link 2</a>
<a class="project-link" href="#"><i class="fa fa-globe"/>Link 3</a>
</div>
</li>
<li>Contact</li>
</ul>
</nav>

Why is my dropdown accordion not working?

Trying to get a simple dropdown accordion to work but not sure why it's not dropping down when clicked. Would like to get the 'Collapse all' button to switch to 'Open' when toggled (but not absolutely necessary). Open to the idea of a pure css accordion as well. Pretty new to javascript and JQuery so any info is helpful on this. TIA.
<div class="accordion">
<div class="chapters___2NT4M js-chapters">
<section id="table-of-contents" class="table_of_contents___2HR-W accordion">
<header class="table_of_contents__chapter_title___2W8SV">
<h2 class="table_of_contents__chapter_heading___19HQO" tabindex="0">Navigate to..</h2>
<button class="table_of_contents__toggle_all___fVHqW accordion-header" aria-expanded="true" aria-pressed="true" aria-haspopup="true">Collapse all</button>
</header>
<div class="accordion-content">
<ul class="table_of_contents__chapter_list___2gu-a" data-gtm-element="review_toc_list">
<li class="table_of_contents__chapter_list_heading___3_laf">Zener Diodes</li>
<li class="table_of_contents__chapter_list_heading___3_laf">Bridge Rectifiers</li>
<li class="table_of_contents__chapter_list_heading___3_laf">Schottky Barrier Rectifiers</li>
<li class="table_of_contents__chapter_list_heading___3_laf">Super Fast Recovery Rectifiers</li>
<li class="table_of_contents__chapter_list_heading___3_laf">Medium Power Bipolar Transistors</li>
<li class="table_of_contents__chapter_list_heading___3_laf">Transient Protection</li>
<li class="table_of_contents__chapter_list_heading___3_laf">thyristor Modules</li>
<li class="table_of_contents__chapter_list_heading___3_laf">Obsoleted/EOL Products</li>
<li class="table_of_contents__chapter_list_heading___3_laf">Cross Reference</li>
</ul>
</div>
</section>
</div>
</div>
css
.accordion-content {
display: none;
border-bottom: 1px solid #DDE0E7;
background: #F6F7F9;
padding: 1.5rem;
color: #4a5666;
}
.accordion-header::before {
content: '';
vertical-align: middle;
display: inline-block;
width: .75rem;
height: .75rem;
border-radius: 50%;
background-color: #B1B5BE;
margin-right: .75rem;
}
.accordion-content.active {
display: block;
height: 200px;
}
#media (min-width: 80em) {
.chapters___2NT4M {
max-width: 570px;
}
}
.chapters___2NT4M {
clear: both;
margin-left: auto;
margin-right: auto
}
#media (min-width: 30em) {
.table_of_contents___2HR-W {
margin: 2em 0 0;
}
}
.table_of_contents___2HR-W {
border-top: 3px solid #000;
margin: 5em 0 0;
padding-top: 0;
}
article, aside, footer, header, nav, section {
display: block;
}
#media (min-width: 48em) {
.table_of_contents__chapter_title___2W8SV {
padding: 0;
}
}
.table_of_contents__chapter_title___2W8SV {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
margin: 0;
-webkit-box-flex: 1;
-webkit-flex: 1;
-ms-flex: 1;
flex: 1;
font-size: 1.5rem;
line-height: 1.5rem;
padding: .4em 0 1.2em;
}
#media (min-width: 80em) {
.table_of_contents__chapter_list___2gu-a {
margin-bottom: 57px;
}
}
#media (min-width: 48em) {
.table_of_contents__chapter_list___2gu-a {
display: block;
}
}
.table_of_contents__chapter_list___2gu-a {
display: ;
margin: 0 0 52px;
padding: 0;
list-style: none;
border-top: 0;
}
ol, ul {
margin: 0 0 1em 1.2em;
padding: 0;
}
#media (min-width: 48em) {
.table_of_contents__chapter_list___2gu-a .table_of_contents__chapter_list_heading___3_laf {
font-size: 1.125rem;
line-height: 1.25rem;
}
}
.table_of_contents__chapter_list___2gu-a .table_of_contents__chapter_list_heading___3_laf {
font-size: 1.1875rem;
line-height: 1.4375rem;
font-family: Arial, Helvetica, sans-serif;
font-weight: 700;
margin-bottom: .8em;
}
.table_of_contents__chapter_list___2gu-a .table_of_contents__chapter_list_heading___3_laf a, .d235 a {
color: #000;
}
.table_of_contents__chapter_list___2gu-a .table_of_contents__chapter_list_heading___3_laf a {
color: #222;
text-decoration: none;
}
.table_of_contents__chapter_list___2gu-a .table_of_contents__chapter_list_heading___3_laf a:hover {
color: #000;
border-bottom: 1px solid #000;
}
js
$(document).ready();
$(".accordion").on("click", ".accordion-header", function() {
$(this).toggleClass("active").next().slideToggle();
});
You can get something similar to an accordion without using javascript by using the html element details.
<details>
<summary>Title</summary>
Some text
</details>
Then, when you click on the title, it expands itself. No js required
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/details
There are a few issues here but I would start with the JS. Important thing here is that inside your click function this will be reference to the element that was clicked. So as I am reading it, you are toggling an active class on the button itself.
Also, I believe you intended to use document.ready() as the context of running the accordion code.
$(document).ready(function() {
$(".accordion").on("click", ".accordion-header", function() {
$(".accordion-content").toggleClass("active");
});
});
I have not got any sliding in this snippet but hopefully this gets your click connected to the CSS change that shows/hides the accordion content.

Categories