switch from mobile menu to default menu with pure css - javascript

currently I am trying to create a navigation bar that switches itself to a hamburger menu if the screen size is too small (responsive / mobile).
https://jsfiddle.net/g7tfnry1/31/
$(document).ready(() => {
$("#btn").click(() => {
$("#items").toggle();
});
});
#navbar {
background: red;
}
#items {
display: flex;
}
#btn {
display: none;
}
#media(max-width: 300px) {
#items {
display: none;
}
#btn {
display: block;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="navbar">
<button id="btn">X</button>
<div id="items">
<div>
<a>
Link 1
</a>
</div>
<div>
<a>
Link 2
</a>
</div>
<div>
<a>
Link 3
</a>
</div>
</div>
</div>
So if you lower the screen size to mobile the css works fine. If you show the items by clicking the button the css works fine too. But after that if you want to get back to a big screen size the menu disappears completely because the items are still hidden or the items don't get aligned in a flex box next to each other.
My question is, do I have to create a resize event $(window).resize() or am I missing something in my css?

When using .toggle (show/hide) you override the CSS rules as it change the display type inline, which has a higher specificity than external rules, unless !important is used in the CSS.
Instead toggle a class .toggleClass, combined with an extra CSS rule #items.show
Updated fiddle
Stack snippet
$(document).ready(() => {
$("#btn").click(() => {
$("#items").toggleClass('show');
});
});
#navbar {
background: red;
}
#items {
display: flex;
}
#btn {
display: none;
}
/* temp. changed to 500 so it works better in the snippet/Chrome when resize */
#media(max-width: 500px) {
#items {
display: none;
}
#btn {
display: block;
}
}
#items.show {
display: flex;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="navbar">
<button id="btn">X</button>
<div id="items">
<div>
<a>
Link 1
</a>
</div>
<div>
<a>
Link 2
</a>
</div>
<div>
<a>
Link 3
</a>
</div>
</div>
</div>

Related

JQuery - Toggle class using !important property

I have a framework which renders the following mark up:
<div class="menuButton">
<button id="menuButton">Menu</button>
</div>
<ul class="menuList">
<li><a href="#" tabindex="1" id="nav_home">
Home
</a>
</li>
<li><a href="#" tabindex="1" id="nav_services">
Services
</a>
</li>
</ul>
It also has the following css which shows the menu button on small devices only:
#menuButton {
display: none;
}
#media only screen and (min-width : 769px) {
.menuList {
display: block !important;
}
}
#media only screen and (max-width : 768px) {
#menuButton {
display: block;
}
.menuList {
display: none;
}
}
An the following javascript to toggle the menu
$('#menuButton').click(function() {
$(".menuList").toggle();
return false;
});
I want to have the menu button displayed regardless of screen size and toggle the menu list i.e. have a mobile menu regardless of screensize. I can do that by overriding the css as follows but I'm unable to override the menulist because it's using the !important property and the jquery toggle function only adds 'style="display: block;" to the element.
#menuButton {
display: block;
}
#media only screen and (min-width: 769px) {
.menuList {
display: none !important;
}
}
How can you get the toggle function to add style="display: block !important;" or how else can I achieve what I'm trying to do which is to have a mobile menu regardless of screen size. Note I can only override the css and add my own javascript but cannot edit the outof the box javascript.
Using toggleClass you should be able to easily overwrite the !important declaration.
$('#click').on('click', function() {
$('#block').toggleClass('open');
});
#block{
display: none!important;
}
#block.open {
display: block!important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="click">click</div>
<div id="block">block</div>

Showing a dropdown on click instead of on hover

I am using Avada (fusion-theme) theme on Wordpress for my website (under construction).
They have a mega-menu option that I am using, but I would want it to appear when someone clicks on the main-menu item instead of hovering over it.
Site: www.paradigmtek.com
So right now if someone hovers over say "smart home" at the top, the sub menu appears (smart home tech support, smart hub or speaker setup, etc.). But I would like it to appear on click instead of on hover.
I don't think this will require not a simple CSS trick, but a JS one.
Anyone has experience with that theme or know how to do it?
You can simply add a class to change the opacity of the dropdown menu upon clicking one of the menus. In this example below, I'm adding show class to dropdown to change opacity from 0 to 1 upon clicking the menu. At the same time, I'm addding a class to the clicked menu (i.e. clicked) to give it an accent colour to indicate that it is the menu being clicked.
const menus = document.querySelectorAll('.menu')
const dropdown = document.querySelector('.dropdown')
let activeMenu = null
menus.forEach(menu => {
menu.addEventListener('click', e => {
// Removing previous active menu that is not itself
if (activeMenu && activeMenu !== menu) {
activeMenu.classList.remove('clicked')
activeMenu = menu
}
else if (activeMenu && activeMenu === menu) {
activeMenu = null
} else {
activeMenu = menu
}
menu.classList.toggle('clicked')
// If there is an active menu, show
if (activeMenu) dropdown.classList.add('show')
else dropdown.classList.remove('show')
})
})
* {
box-sizing: border-box;
font-family: Helvetica;
}
html,
body {
margin: 0;
width: 100%;
height: 100%;
overflow: hidden;
}
.container {
display: flex;
justify-content: center;
background: #121212;
}
.menu {
color: white;
margin: 20px;
padding: 20px;
border-radius: 5px;
cursor: pointer;
}
.menu:hover {
color: #ff8888;
}
.menu.clicked {
color: #ff8888;
}
.dropdown {
width: 100%;
height: 100px;
background: #333333;
display: flex;
flex-direction: column;
opacity: 0;
transition: opacity 0.5s ease;
}
.dropdown.show {
opacity: 1;
}
.line {
width: 100%;
height: 3px;
background: #00a5ff;
}
<div class="container">
<div class="menu">Menu 1</div>
<div class="menu">Menu 2</div>
<div class="menu">Menu 3</div>
<div class="menu">Menu 4</div>
</div>
<div class="dropdown">
<div class="line"></div>
</div>
In the options: avada options -> menu -> submenu
You just have to specify hover / click with the select button.
You can also build your own menu by creating a layout
-> avada -> layout
In your layout you can add a menu element on which you apply the wanted options.
Getting Started With Avada Layouts
Understanding Custom Headers
How To Use The Menu Element

Why does mobile nav button expand on page load?

I have a mobile nav button that upon touching/clicking, should expand and reveal page links. Problem is when you first start the page the button is already expanded:
But should actually load page with elements hidden like so:
The X icon and Line-stack Icon are also reversed. How would I switch these icons around and also make sure the page loads with them closed? I tried switching the icons classes in the jQuery function to switch the x and line-stack but that hasn't worked.
I know there is a simple concept I am missing but I am quite new to jQuery and am having trouble here.
My HTML:
<nav>
<div class="row">
<img src="img/logoblack.png" alt="logo" class="logo img-fluid">
<img src="img/logoblack.png" alt="logo" class="logo-black">
<ul class="main-nav js--main-nav">
<li>About</li>
<li>Skill</li>
<li>Résumé</li>
<li>Contact</li>
</ul>
<a class="mobile-nav-icon js--nav-icon"><i class="ion-navicon-round"></i></a>
</div>
</nav>
My CSS:
.mobile-nav-icon {
float: right;
margin-top: 30px;
cursor: pointer; /* Used since no href tag specifying link type */
display: none;
}
My jQuery:
$('.js--nav-icon').click(function() {
var nav = $('.js--main-nav');
var icon = $('.js--nav-icon i');
nav.slideToggle(200);
if (icon.hasClass('ion-navicon-round')) {
icon.addClass('ion-close-round');
icon.removeClass('ion-navicon-round');
} else {
icon.addClass('ion-navicon-round');
icon.removeClass('ion-close-round');
}
});
Figured it out, needed to create a media query that would hide the .main-nav with display-none;. This way the tags were hidden on mobile devices but still shows in a navbar on a browser:
/* Small phones to small tablets from: 481px to 767px*/
#media only screen and (max-width: 767px) {
.main-nav {
float: left;
margin-top: 25px;
margin-left: 25px;
display: none;
}
}

Make Buttons stay inline-block when toggled

I've got 3 categories acting as buttons for a toggle function. The categories are
displayed inline-block and have a width of 30% each.
When you click on one of them a paragraph appears underneath, however that causes the other two categories to be displayed underneath that paragraph. I need them to stay in one line though.
Here's the fiddle so you can see what I mean. When you click on 'Test1' the 'Test2' is moved underneath the paragraph but I need it to stay where it is.
Any suggestions how to achieve this?
Edit
I've got the html structure like this as it makes the layout work for mobile devices where the categories are stacked.
I've changed your HTML structure, see this fiddle
HTML:
<div class="Categories">
<p id="Category1">Test1</p>
<p id="Category2">Test2</p>
</div>
CSS:
.Categories p {
width:33%;
display:inline-block;
}
JS :
$('#Category1').click(function(){
$('.moreCategory1').toggle();
});
$('#Category2').click(function(){
$('.moreCategory2').toggle();
});
This problem is easily solved by using a flex container. Not only it solves your problem, it is also easy to change for mobile in responsive web design and it is semantically correct.
HTML:
<div class="categories">
<p id="Category1">Test1</p>
<p id="Category2">Test2</p>
<p id="Category3">Test3</p>
</div>
<div id="more1" class="moreCategory">
<p>Content 1</p>
</div>
<div id="more2" class="moreCategory">
<p>Content 2</p>
</div>
<div id="more3" class="moreCategory">
<p>Content 3</p>
</div>
CSS:
.categories {
display: flex;
width: 100%; /*Not necessary. Make sure its large enough to be clear*/
flex-direction: row;
}
.categories p {
width: 30%;
margin: 2px;
padding: 3px;
text-align: center;
background-color: #000;
color: #fff;
}
.moreCategory {
display: none;
}
For Mobile:
#media (min-width: 600px) {
.categories {
flex-direction: column;
}
.categories p {
width: 100%;
}
}
JQuery:
$('#Category1').click(function() {
if ($('#more1').is(":hidden")) $('#more1').toggle();
if (!$('#more2').is(":hidden")) $('#more2').toggle();
if (!$('#more3').is(":hidden")) $('#more3').toggle();
});
$('#Category2').click(function() {
if (!$('#more1').is(":hidden")) $('#more1').toggle();
if ($('#more2').is(":hidden")) $('#more2').toggle();
if (!$('#more3').is(":hidden")) $('#more3').toggle();
});
$('#Category3').click(function() {
if ($('#more1').is(":hidden")) $('#more1').toggle();
if (!$('#more2').is(":hidden")) $('#more2').toggle();
if (!$('#more3').is(":hidden")) $('#more3').toggle();
});
This should solve your problem. JS Fiddle.
EDIT :
If you really want the heading tabs together, but also applicable for mobile you can hide the selecting controller from my for, i.e., the topmost main div.
Hide the header tags for large screens and the same css applies. For mobiles, hide the control div and show the headers and moreContent divs without any JQuery controls. A simple if statement should do the trick(check for screen size or user agent).

jQuery Toggle does not show on window resize

I'm using jQuery slideToggle function and the media queries.
The problem is that when I resize the window to small size, the toggle links appear. Now if I click on toggle, it works fine, but when I resize the window back to large size, the hidden element still do not appear.
If I do not click on the toggle link, and resize the window back to large size, it works fine.
Demo to see the problem:
Please check the demo here, where you can see the problem:
http://jsfiddle.net/3Jj7J/
Resize the window to small size that you see "Main Menu" link. When you click on it, you will see the toggle. Now if you resize it back to large size, the normal links will still not appear.
Here's my code:
HTML:
<div class="bar">
<a class="toggle" href="#">MAIN MENU</a>
</div>
<div class="nav">
<div class="wrap">
<ul>
<li>Link 1</li>
<li>Link 2</li>
</ul>
</div>
</div>
CSS:
.bar{
display: none;
border: 1px solid red;
}
#media screen and (max-width: 500px) {
.nav ul {
display: none;
}
.bar{
display: block;
}
}
jQuery:
var menu = jQuery('.nav .wrap > ul');
jQuery(".toggle").click(function() {
menu.slideToggle(500);
});
add on window resize event handler :
var menu = jQuery('.nav .wrap > ul');
jQuery(".toggle").click(function() {
menu.slideToggle(500);
});
jQuery(window).on('resize', function(){
if(!jQuery(".toggle").is(":visible") && !menu.is(':visible'))
{
menu.show();
}
});
jsFiddle : http://jsfiddle.net/3Jj7J/1/
update: this is alternative solution (just remove inline display property, so it will use css rule).
jQuery(window).on('resize', function(){
if(!jQuery(".toggle").is(":visible") && !menu.is(':visible'))
{
menu.css({'display':''});
}
});
DEMO
I've read your problem and tested it myself. Now, I've made the Link appear by doing the following:
CSS:
#bar {
display: none;
color: #000000;
border: 1px solid red;
}
#media screen and (max-width: 500px) {
#nav ul {
display: none;
}
.bar{
display: block;
}
}
To see for yourself (http://jsfiddle.net/hSZ7t/) What I've done is changed your CSS. Instead of you using:
.bar {
It's now:
#bar {

Categories

Resources