The effect that I wanted is an active underline and change color. When I click on a button, the button will change color and have a underline.
.menu_item {
display: inline-block;
position: relative;
}
.menu_link {
font-family: "Montserrat";
font-size: 20px;
font-weight: 600;
color: grey;
letter-spacing: 0.6px;
}
.menu_link:hover,
.menu_link.active {
color: black;
}
.menu_link:after {
content: '';
position: absolute;
width: 125%;
transform: scaleX(0);
height: 3px;
bottom: -30px;
left: -.8rem;
background-color: black;
transform-origin: bottom right;
transition: transform 0.25s ease-out;
}
.menu_link:hover:after,
.menu_link.active:after {
transform: scaleX(1);
transform-origin: bottom left;
}
<ul class="menu p-0">
<li class="menu_item me-5">
<a class="text-decoration-none menu_link" type="button" id="btnContact">Contact Us</a>
</li>
<li class="menu_item">
<a class="text-decoration-none menu_link" type="button" id="btnLocation">Location</a>
</li>
</ul>
The Buttons
And I have tried with JS but I don't know how to add :after(underline effect) in onclick JS.
var btnMenu1 = document.getElementById("btnContact");
var btnMenu2 = document.getElementById("btnLocation");
btnMenu1.onclick = function() {
btnMenu1.style.color = "black";
btnMenu2.style.color = "grey";
}
btnMenu2.onclick = function() {
btnMenu1.style.color = "grey";
btnMenu2.style.color = "black";
}
//Any help or tutorials are appreciated, thank you!//
================================================================
closed, the solution:
var menuActive = '.menu_link';
$(menuActive).on('click', function(){
$(menuActive).removeClass('active');
$(this).addClass('active');
});
Related
With the help of Michael M. I edited my WordPress menu code in the previous question nicely.
Now I want to open the submenu slowly whenever every li is clicked if there is a ul under it, which I wrote this code but in addition to opening the sub menu, I want the right direction sign (→) to the down direction sign (↓ ) to change.
I have put all the code of this professional menu below, but my problem is only related to the last script code.
let icon = document.querySelector(".icon_menu");
let nav = document.querySelector(".main_menu");
$('.back').hide();
$('.back').click(function() {
if ($(this).is(':hidden')) return;
$(this).toggle();
icon.classList = "bi bi-grid-fill icon_menu";
icon.style.left = "2%";
icon.style.color = "#a66fff";
icon.style.fontSize = "40px";
nav.style.left = '-300px';
});
icon.addEventListener("click", function() {
if (this.classList.contains("bi-grid-fill")) {
this.classList = "bi bi-x-circle-fill icon_menu";
icon.style.left = "21%";
icon.style.color = "#ff6f6f";
icon.style.fontSize = "30px";
nav.style.left = 0;
} else {
this.classList = "bi bi-grid-fill icon_menu";
icon.style.left = "2%";
icon.style.color = "#a66fff";
icon.style.fontSize = "40px";
nav.style.left = "-300px";
}
$('.back').toggle();
});
//********************** **A script that needs editing** *********************
$('.main_menu').find('li').click(function(sub_menu) {
sub_menu.stopPropagation();
sub_menu.preventDefault();
$(this).children('ul').slideToggle();
if ($(this).is(style.content = ' → ')) {
this.style.content = " ↓ ";
};
});
.main_menu {
position: absolute;
top: 0;
left: -300px;
bottom: 0;
z-index: 999;
background: #eee;
padding-right: 2rem;
transition: all 1s ease;
}
.icon_menu {
position: fixed;
top: 10%;
left: 2%;
font-size: 40px;
color: #a66fff;
cursor: pointer;
z-index: 99999;
transition: all 1.1s ease;
}
.main_menu ul {
list-style: none;
line-height: 60px;
font-size: 35px;
}
.main_menu ul li a {
color: #000000;
text-decoration: none;
padding-right: 15px;
padding-left: 40px;
margin-left: -60px;
margin-bottom: 10px;
}
.back {
width: 100%;
height: 100%;
position: fixed;
z-index: 9 !important;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: #00000056;
}
.main_menu ul li ul {
display: none;
}
.main_menu ul li>a::after {
content: ' → ';
}
.main_menu ul li:first-child>a::after {
content: ' → ';
}
.main_menu ul li>a:only-child::after {
content: ' ';
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons#1.10.3/font/bootstrap-icons.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section>
<nav id="nav">
<span class="bi bi-grid-fill icon_menu"></span>
<aside class="main_menu">
<ul>
<li>
home
</li>
<li>
our articles
<ul>
<li>
social
</li>
<li>
Academic
</li>
<li>
historical
</li>
</ul>
</li>
<li>about us</li>
</ul>
</aside>
</nav>
</section>
<div class="back"></div>
It's probably best to do this with CSS instead of JavaScript. Just add the submenu class to any <li> elements that hold sub-menus. Then, create an open class that will be toggled from the JavaScript. From your click handler, all you need to do is toggle the open class.
Because you're using WordPress and can't give elements classes directly, you can use some JavaScript trickery to assign the submenu class to each li in the main_menu that has a ul child.
Like this:
let icon = document.querySelector(".icon_menu");
let nav = document.querySelector(".main_menu");
$('.back').hide();
$('.back').click(function() {
if ($(this).is(':hidden')) return;
$(this).toggle();
icon.classList = "bi bi-grid-fill icon_menu";
icon.style.left = "2%";
icon.style.color = "#a66fff";
icon.style.fontSize = "40px";
nav.style.left = '-300px';
});
icon.addEventListener("click", function() {
if (this.classList.contains("bi-grid-fill")) {
this.classList = "bi bi-x-circle-fill icon_menu";
icon.style.left = "21%";
icon.style.color = "#ff6f6f";
icon.style.fontSize = "30px";
nav.style.left = 0;
} else {
this.classList = "bi bi-grid-fill icon_menu";
icon.style.left = "2%";
icon.style.color = "#a66fff";
icon.style.fontSize = "40px";
nav.style.left = "-300px";
}
$('.back').toggle();
});
//********************** **A script that needs editing** *********************
// hack to give the 'submenu' class
$('.main_menu li ul').each(function() {
$(this).parent().addClass('submenu')
})
$('.submenu').click(function(sub_menu) {
sub_menu.stopPropagation();
sub_menu.preventDefault();
$(this).children('ul').slideToggle();
$(this).toggleClass('open');
});
.main_menu {
position: absolute;
top: 0;
left: -300px;
bottom: 0;
z-index: 999;
background: #eee;
padding-right: 2rem;
transition: all 1s ease;
}
.icon_menu {
position: fixed;
top: 10%;
left: 2%;
font-size: 40px;
color: #a66fff;
cursor: pointer;
z-index: 99999;
transition: all 1.1s ease;
}
.main_menu ul {
list-style: none;
line-height: 60px;
font-size: 35px;
}
.main_menu ul li a {
color: #000000;
text-decoration: none;
padding-right: 15px;
padding-left: 40px;
margin-left: -60px;
margin-bottom: 10px;
}
.back {
width: 100%;
height: 100%;
position: fixed;
z-index: 9 !important;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: #00000056;
}
.main_menu ul li ul {
display: none;
}
.main_menu .submenu > a::after {
content: ' → ';
}
.main_menu .open > a::after {
content: ' ↓ ' !important;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons#1.10.3/font/bootstrap-icons.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section>
<nav id="nav">
<span class="bi bi-grid-fill icon_menu"></span>
<aside class="main_menu">
<ul>
<li>
home
</li>
<li>
our articles
<ul>
<li>
social
</li>
<li>
Academic
</li>
<li>
historical
</li>
</ul>
</li>
<li>about us</li>
</ul>
</aside>
</nav>
</section>
<div class="back"></div>
Working on a side nav that appears when I click on the burger menu. I am relatively new to this. I'm using event listeners to add and remove a class. But what's happening is the click is registered, the transition starts and then is cut off and doesn't continue, it goes back to original state.
const menuBtn = document.querySelector(".burgerMenu");
const sMenu = document.querySelector("#sideMenu");
const bI1 = document.querySelector(".burgerIcon1");
const bI2 = document.querySelector(".burgerIcon2");
const bI3 = document.querySelector(".burgerIcon3");
menuBtn.addEventListener('click', () => {
if (!sMenu.classList.contains('menuAway')) {
sMenu.classList.add('menuAway');
} else {
sMenu.classList.remove('menuAway');
}
if (!bI1.classList.contains('oneOnClick')) {
bI1.classList.add('oneOnClick');
} else {
bI1.classList.remove('oneOnClick');
}
if (!bI2.classList.contains('twoOnClick')) {
bI2.classList.add('twoOnClick');
} else {
bI2.classList.remove('twoOnClick');
}
if (!bI3.classList.contains('threeOnClick')) {
bI3.classList.add('threeOnClick');
} else {
bI3.classList.remove('threeOnClick');
}
})
.menu {
background: var(--gradient);
height: 100vh;
width: 38%;
position: fixed;
right: 0;
top: 0;
z-index: 3;
display: flex;
align-items: center;
padding-left: 5%;
opacity: 0.92;
transition: 0.3s;
}
.menuAway {
right: -75vw;
}
.menu li {
font-size: 1.8rem;
text-transform: uppercase;
font-weight: 500;
line-height: 4rem;
}
.menu li:hover {
text-decoration: underline;
}
.burgerMenu {
z-index: 4;
}
.burgerIcon {
width: 35px;
height: 3px;
margin: 5px auto;
background-color: #282828;
border-radius: 10px;
transition: 0.3s;
}
.oneOnClick {
transform: translate(0px, 8px) rotate(45deg);
}
.twoOnClick {
width: 0px;
}
.threeOnClick {
transform: translate(0px, -8px) rotate(-45deg);
}
<div class="navParent">
<div class="navBar">
<a href="index.html">
<img src="Assets/logo.svg" alt="Inform Logo" class="smallLogo">
</a>
<a href="" class="burgerMenu">
<div class="burgerIcon burgerIcon1"></div>
<div class="burgerIcon burgerIcon2"></div>
<div class="burgerIcon burgerIcon3"></div>
</a>
</div>
<section class="menu menuAway" id="sideMenu">
<ul>
<a href="about.html">
<li>About Us</li>
</a>
<a href="projects.html">
<li>Projects</li>
</a>
<a href="articles.html">
<li>Articles</li>
</a>
<a href="contact.html">
<li>Contact Us</li>
</a>
</ul>
</section>
</div>
This happens because of the <a href=""> so when you click the link you actually navigate, causing the page to reload. I suggest replacing the link with a button, or for a quick fix, do <a href="javascript:void(0)">
Also, you can make your code a lot easier to read by using classList.toggle instead of the if/else blocks
https://developer.mozilla.org/en-US/docs/Web/API/DOMTokenList/toggle
E.g. replace
if (!sMenu.classList.contains('menuAway')) {
sMenu.classList.add('menuAway');
} else {
sMenu.classList.remove('menuAway');
}
With
sMenu.classList.toggle('menuAway')
The sidebar menu below works as expected but there are some elements that I would like to fix and improve.
#1 If you expand the 'System Admin' section the line that is displayed on the left side a in the correct place. However, if you
click on the 'Access Control' the line eon the left side is going
below the horizontal line that's pointing to that section. I tried
fixing that with css 'last-child' method but still is not working
correct. If I change percentage from 50% to 85% then the other
section will have an issue.
#2 I'm looking for a better way to expand/collapse the sections. The function show mimic the existing one, but instead of using the object
with key items I would like to use classes instead if possible.
$( document ).ready(function() {
SIDEBAR_OLD.BASE.ExpandCollapse('Auto');
});
const SIDEBAR_OLD = {};
SIDEBAR_OLD.BASE ={};
SIDEBAR_OLD.BASE.ToggleContent = function(section_id) {
let $sContents = $("#section_" + section_id);
if ( $sContents.css("display") != "none" ) {
$sContents.css("display","none");
} else { // Default to seeing the folder's contents:
$sContents.css("display","");
}
};
$("#main-page-wrapper").on("click", ".toggle-menu", function(e){
e.preventDefault();
let section_id = $(this).attr("data-id");
SIDEBAR_OLD.BASE.ToggleContent(section_id);
});
SIDEBAR_OLD.BASE.ExpandCollapse = function(action) {
let $sContents = null,
sExpand = null,
sRoot = false,
items = {1:"m",2:"sysadmin",5:"access"};
for (key in items) {
$sContents = $("#section_" + items[key]);
switch (action) {
case "Expand":
sExpand = "Yes";
break;
case "Collapse":
sExpand = "No";
break;
default:
if ( !(sExpand = $sContents.attr("data-expand")) ) sExpand = "Yes";
}
// Never close root elements automatically. Only ToggleContent(pNumber), below, can do that.
if ( sRoot = $sContents.attr("data-root") ) { // Note! Assignment! "=", not "=="!
if (sRoot == "Yes") sExpand = "Yes";
}
if ( sExpand == "No" ) {
$sContents.css("display","none");
} else { // Default to seeing the folder's contents:
$sContents.css("display","");
}
}
return true;
};
$("#main-page-wrapper").on("click", ".collapse-menu", function(e){
e.preventDefault();
let action = $(this).attr("data-action");
SIDEBAR_OLD.BASE.ExpandCollapse(action);
});
.sidebar {
position: absolute;
top: 56px;
right: 0px;
bottom: 0px;
left: 0px;
width: 180px;
background-color: #0071bc;
color: #fff;
height: calc(100vh - 98px);
overflow: auto;
font-size: 9pt !important;
white-space: nowrap;
}
.sidebar a {
color: #fff;
}
.menuitem {
color: #fff;
font-weight: bold;
text-decoration: none;
}
.menuitem:hover, .menuitem:focus {
color: #ff0;
}
#tree {
font-weight: bold;
padding: 1px;
}
#expandcollapse {
border: 1px solid white;
text-align: center;
}
.sb-row {
border: 0px;
height: 22px;
margin: 0px;
overflow: hidden;
padding: 0px 0px 0px 3px;
position: relative;
white-space: nowrap;
}
.fa-folder-open:before {
color: #DBDB2A !important;
}
.nav>li {
position: relative;
display: block;
}
.nav>li>a {
position: relative;
display: block;
padding: 7px 22px 6px;
}
.nav>li>a:focus {
text-decoration: none;
background: transparent;
background-color: transparent;
}
.nav > li > a:hover {
color: red;
background-color: transparent;
text-decoration: none;
}
.nav.side-menu>li {
position: relative;
display: block;
cursor: pointer;
}
.nav.child_menu li {
padding-left: 20px;
}
.nav.child_menu>li>a {
font-weight: 500;
font-size: 12px;
font-weight: bold;
}
li.first-level::before {
background: #fff;
bottom: auto;
content: "";
height: 1px;
left: 10px;
margin-top: 14px;
position: absolute;
right: auto;
width: 8px;
}
li.first-level::after {
border-left: 1px solid #fff;
bottom: 0;
content: "";
left: 10px;
position: absolute;
top: 0;
}
ul.nav.side-menu li.first-level:last-child::after {
bottom: 50%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
<body>
<div class="container body" id="main-page-wrapper">
<div class="sidebar">
<div id="tree" role="navigation" data-expandall="Auto">
<div id="expandcollapse">
<a class="menuitem collapse-menu pr-2" href="#" data-action="Expand">Expand</a> | <a class="menuitem collapse-menu pl-2" href="#" data-action="Collapse">Collapse</a>
</div>
<div class="sb-row">
<a class="toggle-menu" title="Open/Close Folder - System Management" data-id="m">
<i class="fa fa-folder-open fa-lg"></i> System Management
</a>
</div>
<div id="section_m" class="menu-section" data-root="Yes" data-expand="Yes">
<ul class="nav side-menu">
<li class="first-level">
<a class="toggle-menu" href="#" title="System Admin" data-id="sysadmin"><i class="fa fa-folder-open"></i> System Admin</a>
<ul class="nav child_menu first" id="section_sysadmin" data-expand="No">
<li><a class="link-item" data-action="param" title="System Parameters">System Parameters</a></li>
<li><a class="link-item" data-action="schema" title="Select Schema">Select Schema</a></li>
<li><a class="link-item" data-action="item" title="Menu Item">Menu Items</a></li>
</ul>
</li>
<li class="first-level">
<a class="toggle-menu" href="#" title="Access Control" data-id="access"><i class="fa fa-folder-open"></i> Access Control</a>
<ul class="nav child_menu first" id="section_access" data-expand="No">
<li><a class="link-item" data-action="user" title="Manage User">Manage User</a></li>
<li><a class="link-item" data-action="role" title="Manage Role">Manage Role</a></li>
</ul>
</li>
</ul>
</div>
</div>
</div>
</div>
</body>
I am trying to get a transition to activate when the burger menu is clicked. My javascript, and css work for everything but creating a slow nav drop down transition from top to bottom.
Trying to find an answer online has led me to many different ways of creating a transition. So I am lost on that, if there is a standard way to do this please assist me. Not trying to be lazy but I have seen 5 different ways. Not sure what i need to target in my css. Thank you
<header>
<button class="hamburger hamburger--squeeze" type="button">
<span class="hamburger-box">
<span class="hamburger-inner"></span>
</span>
</button>
<img class="header-logo" src="/logo/piancavallo-logo.svg" alt="">
<nav>
<ul class="nav-links">
<li>home</li>
<li>shop</li>
<li>sport</li>
<li>read</li>
<li>about</li>
</ul>
</nav>
<img class="search-icon" src="/logo/search-icon.svg" alt="">
<img class="shopping-cart" src="/logo/shopping-cart.svg" alt="">
</header>
nav {
position: absolute;
text-align: left;
top: 100%;
left: 0;
}
nav .nav-links {
display: none;
background-color: orange;
font-size: 1.4rem;
position: absolute;
width: 100vw;
}
nav .nav-active {
display: block;
}
nav ul {
margin: 0;
padding: 0;
list-style: none;
}
nav li {
margin: 5px;
padding: 5px;
}
nav a {
text-decoration: none;
color: green;
font-weight: 700;
}
nav ul {
-webkit-transition: height 1s ease-in;
transition: height 1s ease-in;
}
const revealNav = () => {
const hamburger = document.querySelector('.hamburger');
const nav = document.querySelector('.nav-links');
hamburger.addEventListener('click', () => {
hamburger.classList.toggle('is-active');
}, false);
hamburger.addEventListener('click', () => {
nav.classList.toggle('nav-active');
});
}
revealNav();
As far as I know there isn't a standard or better way to do this, it very much depends on the visual effect you are trying to achieve.
I have a solution here and I have stripped out most of the CSS that is not needed for the top/bottom transition.
I also have a jump in opacity that may be helpful while developing as it shows you exactly when the class is added or removed.
const revealNav = () => {
const hamburger = document.querySelector('.hamburger');
const nav = document.querySelector('.nav-links');
hamburger.addEventListener('click', () => {
nav.classList.toggle('is-active');
});
}
revealNav();
nav {
overflow: hidden;
}
.nav-links {
opacity: 1; /* only to show when class is added */
background-color: orange;
margin: 0;
padding: 0;
list-style: none;
transition: transform 1s;
transform: translateY(-100%);
}
.nav-links.is-active {
opacity: 1; /* only to show when class is added */
transform: translateY(0);
}
<header>
<button class="hamburger hamburger--squeeze" type="button">
<span class="hamburger-box">
<span class="hamburger-inner">hamburger</span>
</span>
</button>
<nav>
<ul class="nav-links">
<li>home</li>
<li>shop</li>
<li>sport</li>
<li>read</li>
<li>about</li>
</ul>
</nav>
</header>
I'm looking to have the background color of my content attribute fade to another color upon the user clicking a color which is an image.
I assume I am going about this all the wrong way and would be grateful for any help.
I hope I post this correctly. Apologies if not. I've been a browser for a long time and have only now decided to register.
http://jsfiddle.net/WhiteSlevin7/LAcFa/9/
<body>
<div id ="wrapper">
<section id ="logo">
</section>
<section id ="header">
</section>
<div id="accessibility">
<ul>
<li><a data-color-id="1" href="#"><img src="images/red-color.jpg"></a></li>
<li><a data-color-id="2" href="#"><img src="images/blue-color.jpg"></a></li>
<li><a data-color-id="3" href="#"><img src="images/grey-color.jpg"></a></li>
<li><a data-color-id="4" href="#"><img src="images/purple-color.jpg"></a></li>
</ul>
</div>
<section id="content">
<article>
</article>
</section>
</div>
a{
color: #ffffff;
text-decoration: none;
font-size: 85%;
border: 0;
}
a:hover{
color: #000000;
font-size: 85%;
}
#header{
height: 170px;
background: url(images/banner.jpg) no-repeat center ;
padding: 0px;
}
#logo{
height: 109px;
background: #9bbdc7 url(images/logo.jpg) no-repeat center;
border-style: none;
padding: 0px;
}
#accessibility li {
float: left;
padding: 0 20px 0 0;
list-style: none;
}
#accessibility li a {
color: #CFCFCF;
font-size: 16px;
font-weight: bold;
text-decoration: none;
transition: all 0.2s linear;
-webkit-transition: all 0.2s linear;
-moz-transition: all 0.2s linear;
}
#wrapper {
width: 960px;
margin: 10px auto;
text-align:left;
min-width: auto;
}
#content {
width: 100%;
background: #eff6f4;
float: left;
transition: background 4s linear;
-webkit-transition: background 4s linear;
-moz-transition: background 4s linear;
}
article{
background: #f9f6f6;
border: 1px solid black;
padding: 20px;
margin-bottom:10px;
margin-top:10px;
}
function changeBg(currentItem) {
var bg = 'null';
currentItem = Number(currentItem)
switch (+currentItem) {
case 1 :
bg = '#9CC8BC';
break;
case 2 :
bg = '#9CA7C8';
break;
case 3 :
bg = '#C8BC9C';
break;
case 4 :
bg = '#C89CBD';
break;
default :
bg = '#eff6f4';
}
$('#content').css('background', bg);
}
jQuery('#accessibility li a').bind('click', function() {
changeBg(this.id);
return false;
});
Issues:
(1) Wrap the event handler inside ready(). (2) Set the style to valid element, #content.
Working code: Live Demo
HTML
<div id ="wrapper">
<section id ="logo"></section>
<section id ="header"></section>
<div id="accessibility">
<ul>
<li><a id="1" href="#"><img src="images/red-color.jpg"></a></li>
<li><a id="2" href="#"><img src="images/blue-color.jpg"></a></li>
<li><a id="3" href="#"><img src="images/grey-color.jpg"></a></li>
<li><a id="4" href="#"><img src="images/purple-color.jpg"></a></li>
</ul>
</div>
<section id="content">
<article>
</article>
</section>
</div>
Script
function changeBg(currentItem) {
var bg = 'null';
switch (+currentItem) {
case 1 :
bg = '#9CC8BC';
break;
case 2 :
bg = '#9CA7C8';
break;
case 3 :
bg = '#C8BC9C';
break;
case 4 :
bg = '#C89CBD';
break;
default :
bg = '#eff6f4';
}
$('#content').css('background', bg);
}
jQuery(document).ready(function() {
jQuery('#accessibility li a').on('click', function() {
changeBg(this.id);
return false;
});
});
I think you meant to use $('#content') instead of $('layout').
$('#content').css('background', bg);
You may want to use a data-* attribute such as data-color-id for the id of your colors instead.
<a data-color-id="1" href="#"><img src="images/red-color.jpg"></a>
Also, your fiddle is missing jQuery and the HTML contents should contain only the content of the <body> preferably.
See it here.