I have made a toggle button to show some navlinks on mobile screens.
However on the first page load it takes two clicks.
After that point it toggle perfectly fine.
How can I make it so it functions correctly first time?
Heres the script that contains the function.
script.js
function ToggleNavLinks() { /
var navLink = document.getElementsByClassName("nav-links")[0];
if (navLink.style.display === "none") {
navLink.style.display = "flex";
}
else {
navLink.style.display = "none";
}
}
Heres the layout file that contains the front-end element.
I have tested if it was the external script reference and it definitely works.
layout.hbs
<!DOCTYPE html>
<html lang="en">
<head>
<title>{{title}}</title>
<meta charset="utf-8"/> <!-- Charset -->
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<link rel='stylesheet' href='/stylesheets/style.css'/>
<script type="text/javascript" src="/javascripts/script.js"></script>
</head>
<body>
<header>
<nav class="navbar">
<img class="logo" alt="logo" src="images/logo-stock.png">
<a class="nav-toggle" onclick="ToggleNavLinks()" >
<span class="bar"></span>
<span class="bar"></span>
<span class="bar"></span>
</a>
<!-- Links used in the navbar -->
<div class="nav-links">
<ul>
<li>
Home
</li>
<li>
Projects
</li>
<li>
Contact
</li>
</ul>
</div>
</nav>
</header>
<div>
{{{body}}}
</div>
</body>
</html>
Ill also include the stylesheet in case that has anything to do with it.
#import url('https://fonts.googleapis.com/css2?family=Roboto:wght#300&display=swap');
:root {
font-size: 16px;
font-family: 'Roboto', sans-serif;
--text-primary: white;
--text-secondary: #4c6bc1;
--bg-primary: #101316;
--bg-secondary: #181a1d;
}
* {
box-sizing: border-box;
}
body {
background-color: var(--bg-primary);
margin: 0;
padding: 0;
}
body::-webkit-scrollbar {
width: 0.25rem;
}
body::-webkit-scrollbar-track {
background: #181a1d;
}
body::-webkit-scrollbar-thumb {
background: #4c6bc1;
}
.navbar {
justify-content: space-between;
position: relative;
background-color: var(--bg-secondary);
display: flex;
justify-content: space-between;
align-items: center;
}
.navbar img {
width: 250px;
height: 100px;
}
.logo{
max-width: 100%;
height: auto;
}
.navbar-links {
height: 100%;
}
.nav-links ul {
margin: 0;
padding: 0;
display: flex;
}
.nav-links li {
list-style: none;
}
.nav-links li a {
font-size: 1.5rem;
text-decoration: none;
color: white;
padding: 1rem;
display: block;
}
.nav-links li a:hover {
color: #4c6bc1;
}
.nav-toggle {
position: absolute;
top: 1.5rem;
right: 1rem;
display: none;
flex-direction: column;
justify-content: space-between;
height: 21px;
width: 30px;
}
.nav-toggle:hover {
cursor: pointer;
}
.nav-toggle .bar {
height: 3px;
width: 100%;
background-color: white;
border-radius: 10px;
}
#media (max-width: 800px) {
.nav-toggle {
display: flex;
}
.nav-links {
display: none;
width: 100%;
}
.navbar {
flex-direction: column;
align-items: flex-start;
}
.nav-links ul {
width: 100%;
flex-direction: column;
}
.nav-links li {
text-align: center;
}
.nav-links.active {
display: flex;
}
element.style.display === 'none'
is true when the element has an inline style attribute, which includes display: none. Note that this is true regardless of the actual computed style property of the element. You can check it in this example:
console.log(document.querySelector('.test').style.display);
.test {
display: block !important;
}
code {
background-color: #eee;
}
<div style="display: none;" class="test">I haz <code>style.display === 'none'</code>. You are looking at me. Stop staring, it's not nice.</div>
To check the computed property of the display, use
window.getComputedStyle(element).display === 'none'
In conclusion, replace
if (navLink.style.display === "none") {
with
if (window.getComputedStyle(navLink).display === "none") {
It maybe not the problem of Your Javascript. First check your CSS file. Check if the order of your code i.e display tag is already none or flex. Then only it was not working at 1st instance.
It may be like that:
.navlink{
display: none;
}
Change it to :
.navlink{
display: flex;
}
Related
This question already has answers here:
How do I detect a click outside an element?
(91 answers)
Closed 9 months ago.
I am having trouble as to how to make the contents of the dropdown menu hide when clicking off of the dropdown menu on the page. I have provided the code below and need some assistance. Please help in explaining the correct javascript code.
<!-- html code -->
<!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">
<title>HTML 5 Boilerplate</title>
<link rel="stylesheet" href="styles.css">
<script src="https://kit.fontawesome.com/36947df53d.js" crossorigin="anonymous"></script>
<script src="script.js"></script>
<script src="jquery-3.6.0.min.js"></script>
</head>
<body>
<div class = "header">
<div class = "logo">Logo</div>
<div class = "dropdown">
<div class ="button">
<i class="fa-solid fa-bars" id ="button"></i>
</div>
<div class = "dropdown-content" id = "myDropdown">
<nav>
<ul class ="dropdownMenu">
<li>Home</li>
<li>About</li>
<li>Store</li>
<li>Contact</li>
</ul>
</nav>
</div>
</div>
</div>
</body>
</html>
This is the CSS Code for the webpage.
/* css code */
#import url('https://fonts.googleapis.com/css2?family=Montserrat:wght#100&family=Open+Sans:wght#300;400&display=swap');
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.header {
height: 80px;
background-color: lightblue;
box-shadow: 0px 3px #888888;
display: flex;
justify-content: space-between;
line-height: 55px;
z-index: 99;
}
ul {
list-style-type: none;
}
ul li {
display: inline-block;
padding: 10px 10px;
}
ul li a {
text-decoration: none;
color: black;
font-family: 'Montserrat', sans-serif;
}
.logo {
padding: 10px 10px;
font-family: 'Montserrat', sans-serif;
font-size: 3em;
}
#button {
display: none;
}
#media only screen and (max-width: 550px) {
body {
padding: 0;
margin: 0;
background-color: lightblue;
}
.header {
display: flex;
flex-direction: column;
/*z-index: 99;*/
}
ul li {
display: flex;
flex-direction: column;
width: 100%;
padding: 0;
}
ul li a {
display: flex;
justify-content: center;
align-items: center;
padding: 0;
margin: 0;
height: 5em;
width: 100%;
text-align: center;
border-bottom: 1px solid black;
color: black;
font-size: 20px;
font-weight: 800;
justify-content: center;
}
a:hover {
background-color: lightblue;
}
#button {
display: inline;
top: 0;
right: 0;
padding: 30px;
/*z-index: 98;*/
position: absolute;
color: black;
}
.dropdown-content {
display: none;
background-color: white;
/*z-index: 97;*/
}
.show {display:block;}
}
This is the javascript code for the webpage.
// JS Code
// Not sure how to close dropdown menu when page is clicked off of dropdown menu on page
function myFunction() {
document.getElementById("myDropdown").classList.toggle("show");
}
You can add a click handler on the whole page and toggle the dropdown with it. Though would need some checks and bubbling prevention on the dropdown itself, but this way it should work:
document.documentElement.addEventListener(
'click',
() => document.getElementById("myDropdown").classList.toggle("hide"),
false
);
I am creating a navbar using flex CSS. My problem is that I wanted the links to be on the right side of the screen, but they are on the left side and next to the title which is what I do not want. I have tried margin-left: auto, but it does not work. Is there a different solution to this problem? The image down below:
Image of Navbar
Here's my codes:
#import url("https://fonts.googleapis.com/css2?family=Montserrat+Alternates&display=swap");
#import url("https://fonts.googleapis.com/css2?family=Poppins&display=swap");
/*
font-family: 'Poppins', sans-serif;
font-family: 'Montserrat Alternates', sans-serif;
*/
* {
margin: 0;
padding: 0;
}
body {
width: 100%;
height: 100vh;
box-sizing: border-box;
background-color: #fff;
}
nav {
padding: 20px;
display: flex;
justify-content: space-between;
position: fixed;
align-content: center;
background-color: transparent;
}
.name-title {
font-family: "Montserrat Alternates", sans-serif;
font-size: xx-large;
color: #000;
}
nav ul {
display: flex;
justify-content: space-between;
align-content: center;
margin-top: 10px;
}
nav li {
list-style: none;
}
nav a {
font-family: "Poppins", sans-serif;
font-size: medium;
padding-right: 2em;
text-decoration: none;
color: #000;
}
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!--Font Awesome CDN-->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css" integrity="sha512-iBBXm8fW90+nuLcSKlbmrPcLa0OT92xO1BIsZ+ywDWZCvqsWgccV3gFoRBv0z+8dLJgyAHIhR35VZc2oM/gI1w==" crossorigin="anonymous" referrerpolicy="no-referrer"
/>
<nav>
<div class="name-title">Ayush Kumar</div>
<ul>
<li>Link</li>
<li>Link</li>
<li>Link</li>
</ul>
</nav>
Just add width: 100%; to Nav
nav {
padding: 20px;
display: flex;
justify-content: space-between;
position: fixed;
align-content: center;
background-color: transparent;
width: 100%;
}
or remove position fixed
position: fixed; is causing the issue. If you really want to use it, add some more details describing the position.
nav {
position: fixed;
left: 0;
right: 0;
}
The above will give it a width of 100% since the position is 0 distance from both left and right end of the viewport. Codepen
Otherwise you can remove position:fixed too.
My Solution to your Question, I hope I can help.
<style>
.main-nav {
width: 100%;
display: flex;
flex-direction: row;
justify-content: space-between;
}
.navbar {
display: flex;
flex-direction: row;
list-style: none;
}
.navbar li {
padding-right: 5px;
}
</style>
<body>
<nav class="main-nav">
<h1>Name</h1>
<ul class="navbar">
<li>
link A
</li>
<li>
link B
</li>
<li>
link C
</li>
</ul>
</nav>
</body>
Try Wrapping your nav tag in a body tag in your html. You set the body width to 100% but theres no body tag in your HTML.
The overflow x in my react Navbar not working as expected. The navbar is meant to slide in only when the Hamburger is clicked and not to show when not clicked. Everything works well except the fact that the overflow X that was supposed to hide keeps scrolling. Have tried a few things but yet not working.
Here is the link to the CodeSandbox
My Navbar and my CSS code are here below. Kindly help me look into this.
import React, { useState } from "react";
import { IconContext } from "react-icons";
import { MdMenu } from "react-icons/md";
// import { MdClose } from "react-icons/md";
export default function Navbar() {
const[navLinkOpen, navLinkToggle] = useState(false)
const handleNavLinksToggle = () =>{
navLinkToggle(!navLinkOpen)
}
const renderClasses = () =>{
let classes = "navlinks";
if(navLinkOpen){
classes += " active"
}
return classes;
}
return (
<div>
<div className="container">
<nav>
<div className="logo">
Edie
</div>
<ul className={renderClasses()}>
<li className="link"> Home </li>
<li className="link"> Services </li>
<li className="link"> Our Works </li>
<li className="link"> Clients </li>
<li className="link"> Contacts </li>
</ul>
<IconContext.Provider value={{ color: "#000000", size: "30px", className: "icon" }}>
<div onClick={handleNavLinksToggle} className="hamburger-toggle">
<MdMenu/>
</div>
</IconContext.Provider>
</nav>
</div>
</div>
)
}
CSS
#import url('https://fonts.googleapis.com/css2?family=Heebo&family=Poppins&display=swap');
nav{
display: flex;
justify-content: space-between;
align-items: center;
}
.navlinks{
display: flex;
justify-content: space-evenly;
width: 50%;
align-items: center;
}
.logo{
width: 70px;
height: 53px;
}
.logo > a{
font-family: 'Heebo', sans-serif;
text-decoration: none;
font-style: normal;
font-weight: 800;
font-size: 36px;
line-height: 53px;
color: #333333;
}
.navlinks > li > a{
text-decoration: none;
font-family: 'Poppins', sans-serif;
font-style: normal;
font-weight: 500;
font-size: 24px;
line-height: 36px;
color: #333333;
}
.hamburger-toggle{
cursor: pointer;
display: none;
}
#media screen and (max-width: 1024px){
body{
overflow-x: hidden;
}
.hamburger-toggle{
display: block;
}
.navlinks{
display: none;
position: absolute;
right: 0;
display: flex;
flex-direction: column;
height: 92vh;
align-items: center;
width: 100%;
top: 10vh;
background-color: red;
transform: translateX(100%);
transition: transform 0.5s ease-in;
}
.active{
transform: translateX(0%);
}
}
For that you can use the position relative and additional width for html and body in global css.
It appears that browsers that parse the tag simply ignore overflow attributes on the html and body tags.
on Global CSS
html, body{
width: 100%;
position: relative;
}
Whenever I click on the hamburger icon the menu opens but when I click on it again it is supposed to get closed... But it's not. I am trying to debug but I have no idea what is going wrong. If anyone knows, please help
// Hamberger menu
const navSearch = document.querySelector('.nav-search');
const navLeft = document.querySelector('.nav-left');
document.querySelector('.toggle').addEventListener('click', () => {
console.log(navSearch.style.display);
console.log('1');
if(navSearch.style.display = "none") {
console.log('2');
navSearch.style.display = "inline-block";
navLeft.style.display = "inline-block";
console.log(navSearch.style.display);
} else if(navSearch.style.display = "inline-block") {
console.log('3');
navSearch.style.display = "none";
navLeft.style.display = "none";
}
console.log('......');
});
// Variables
$website-width: 1280px;
$color-main: #4bbf73;
$color-dark: #343a40;
$color-light: #fff;
$color-lightx2: #f7f7f9;
//General Styles
* {
margin: 0;
padding: 0;
}
body {
background-color: $color-light;
font-family: "Nunito", Arial, Helvetica, sans-serif;
line-height: 1.6;
}
a {
text-decoration: none;
color: $color-light;
}
ul {
list-style: none;
}
h2,
h3,
h4 {
text-transform: uppercase;
}
img {
width: 100%;
}
input {
border: none;
padding: 0.7rem 1rem;
background: $color-lightx2;
&:focus {
outline: none;
}
}
// Utilities
.container {
max-width: $website-width;
padding: 0 1.5rem;
margin: auto;
overflow: hidden;
}
// navbar
header {
background: $color-dark;
height: 100px;
#navbar {
padding-top: 1.3rem;
color: $color-light;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
.nav-logo {
font-size: 1.5rem;
font-weight: 900;
letter-spacing: 2px;
padding: 0.5rem 1rem;
}
ul {
display: flex;
justify-content: center;
li {
padding-left: 1.5rem;
}
}
input[type="submit"] {
margin-left: 0.4rem;
background-color: inherit;
border: $color-main 2px solid;
color: $color-main;
&:hover {
background-color: $color-main;
color: $color-light;
transition: all 0.2s ease-in-out;
}
}
input[type="text"] {
padding: 0.7rem 1rem;
}
}
.toggle {
position: absolute;
top: 2.2rem;
right: 6rem;
transform: scale(2);
display: none;
}
}
#import 'media';
#media (max-width: 850px) {
header {
height: auto;
#navbar {
flex-direction: column;
align-items: start;
input[type="text"] {
margin: 1rem 0 1.4rem 3rem;
}
ul {
padding-bottom: 1rem;
}
}
.toggle {
display: inline-block;
}
.nav-search,
.nav-left {
display: none;
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.0/css/all.css"
integrity="sha384-OLYO0LymqQ+uHXELyx93kblK5YIS3B2ZfLGBmsJaUyor7CpMTBsahDHByqSuWW+q" crossorigin="anonymous">
<link href="https://fonts.googleapis.com/css2?family=Nunito:wght#300&display=swap" rel="stylesheet">
<link rel="stylesheet" href="scss/style.css">
<title>AllMart</title>
</head>
<body>
<header>
<div class="container">
<nav id="navbar">
<div class="nav-logo">
AllMart
</div>
<div class="nav-search">
<form>
<input type="text" placeholder="Search Product...">
<input type="submit" value="SEARCH">
</form>
</div>
<div class="nav-left">
<ul>
<li id="cart"><i class="fas fa-shopping-cart"></i> CART</li>
<li id="profile"><i class="fas fa-user"></i> SIGN IN</li>
</ul>
</div>
</nav>
<span class="toggle"><i class="fas fa-bars"></i></span>
</div>
</header>
<script src="js/index.js"></script>
</body>
</html>
and this is the output I get whenever I click on the icon
I have no idea what is going wrong if anyone knows, please help
You need to use === or == in if statements, not =, which is the assignment operator. === is preferred because it tests for strict equality (no type conversion).
if(navSearch.style.display === "none")
else if(navSearch.style.display === "inline-block") {
I'm currently trying to create a website from scratch, seen as I have the time to practice.
So far, I have got a working navigation bar (one which does not actually take you to other pages yet but does actually work ).
I decided to make this navigation bar responsive, as it is quite a big bar.
I have given the option of a vertical bar at a click of a button.
To note, the button is only available to the user when the browser is less than 900px width.
My current issue is that when the button is pressed, nothing is being displayed. I have ensured the javascript for the button is working, via trial and error but still have no luck.
I am new to this, so forgive me if my error is silly but any help would be greatly appreciated.
To help give an idea of what I am trying to achieve, here is the link I have been using as guidance: https://www.w3schools.com/howto/howto_js_topnav_responsive.asp
If the issue lays within the fact that I am using an 'unordered list' tag to align my navigation bar to the right and my logo to the left, then any alternative way is welcome too!
Thank you.
P.s. ignore the names of each section in the navigation, I was just filling in the spaces for now ^^
body{
background-color: grey;
margin:0;
}
/*----------------------NAVIGATION BAR----------------------*/
.nav-container{
background-color: white;
float: right;
height: 80px;
position: absolute;
width: 100%;
margin-top: 0;
}
#nav-menu{
float:right;
padding: 13px 13px;
}
#nav-menu li{
display:inline-block;
font-size: 20px;
padding: 10px 12px;
text-align: center;
}
#nav-menu li a:not(.nav-active){
color: black;
text-decoration: none;
}
#nav-menu li a:hover:not(#logo){
color: #0aaaa0;
}
.nav-active {
color: #0aaaa0;
text-decoration: none;
}
/* LOGO */
#logo{
padding: 0px 13px;
float: left;
font-size: 27px;
}
/* Hide the link that should open and close the topnav on small screens */
#nav-menu .icon {
display: none;
}
/* When the screen is less than 600 pixels wide, hide all links, except for the first one ("Home"). Show the link that contains should open and close the topnav (.icon) */
#media screen and (max-width: 900px) {
#nav-menu li a:not(.icon) {display: none;}
#nav-menu li a.icon {
float: right;
display: block;
}
}
/* The "responsive" class is added to the topnav with JavaScript when the user clicks on the icon. This class makes the topnav look good on small screens (display the links vertically instead of horizontally) */
#media screen and (max-width: 900px) {
.nav-bar.responsive {position: relative;}
.nav-bar.responsive li a.icon{
position: relative;
right: 0;
top: 0;
}
.nav-bar.responsive li a{
float: none;
display: block;
text-align: left;
position: relative;
}
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="UTF-8">
<link rel="stylesheet" href="practice.css">
<!-- Load an icon library to show a hamburger menu (bars) on small screens -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
</head>
<body>
<!-- NAVIGATION BAR -->
<div class="nav-container">
<ul id="logo">Dellion</ul>
<ul class="nav-bar" id="nav-menu">
<li><a class="nav-active" href="index.html">Home</a></li>
<li>Cars</li>
<li>Charities</li>
<li>Pros</li>
<li>Games</li>
<li>Auctions</li>
<li>Support</li>
<li><a href="javascript:void(0);" class="icon" onclick="myFunction()">
<i class="fa fa-bars"></i></a></li>
</ul>
</div>
<script>
function myFunction() {
var x = document.getElementById("nav-menu");
if (x.className === "nav-bar") {
x.className += " responsive";
} else {
x.className = "nav-bar";
}
}
</script>
</body>
</html>
Simplify your layout by using flexbox
function myFunction() {
var x = document.getElementById("nav-menu");
if (x.className === "nav-bar") {
x.className += " responsive";
} else {
x.className = "nav-bar";
}
}
body {
background-color: grey;
margin: 0;
}
.nav-container {
display: flex;
background-color: white;
min-height: 80px;
width: 100%;
align-items: center;
flex-wrap: wrap;
}
#logo {
font-size: 27px;
padding: 0 13px;
height: 80px;
line-height: 80px;
}
.nav-bar {
flex-direction: row;
}
.nav-bar li {
list-style: none;
}
.nav-bar a {
color: #000;
font-size: 20px;
padding: 10px 12px;
text-decoration: none;
}
.nav-links {
margin-left: auto;
padding-right: 20px;
display: flex;
flex: 1;
justify-content: flex-end;
}
.hamburger .icon {
/* remove the styling, this code is for illustration purpose only*/
height: 40px;
width: 40px;
background: grey;
border: 1px solid #000;
}
.nav-bar,
.hamburger .icon {
display: none;
}
.hamburger {
position: absolute;
right: 20px;
top: 20px;
}
#media screen and (min-width: 901px) {
.nav-bar,
.nav-bar.responsive {
display: flex;
align-items: center;
}
}
#media screen and (max-width: 900px) {
.hamburger .icon {
display: block
}
.nav-bar.responsive {
display: flex;
flex-direction: column;
width: 100%;
margin: 0;
padding: 0;
}
.nav-links {
flex-basis: 100%;
margin: 0;
padding: 0;
}
.nav-bar li {
padding: 10px 0;
}
}
<div class="nav-container">
<div id="logo">Dellion</div>
<div class="nav-links">
<ul class="nav-bar" id="nav-menu">
<li><a class="nav-active" href="index.html">Home</a></li>
<li>Cars</li>
<li>Charities</li>
<li>Pros</li>
<li>Games</li>
<li>Auctions</li>
<li>Support</li>
</ul>
<div class="hamburger">
<a href="javascript:void(0);" class="icon" onclick="myFunction()">
<i class="fa fa-bars"></i></a>
</div>
</div>
</div>
There is a very simple way:
.nav-container{
background-color: white;
/* float: right; */
height: 80px;
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
margin-top: 0;
}
#nav-menu{
/* float:right; */
/* padding: 13px 13px; */
}
#nav-menu li{
display:inline-block;
font-size: 20px;
padding: 10px 12px;
text-align: center;
}
#nav-menu li a:not(.nav-active){
color: black;
text-decoration: none;
}
#nav-menu li a:hover:not(#logo){
color: #0aaaa0;
}
.nav-active {
color: #0aaaa0;
text-decoration: none;
}
/* LOGO */
#logo{
padding: 0px 13px;
/* float: left; */
font-size: 27px;
}
/* Hide the link that should open and close the topnav on small screens */
#nav-menu .icon {
display: none;
}
And I recommended you to read this useful article about css Flexbox.
I think part of your problem is, :
Javascript:
if (x.className === "nav-bar") {
x.className += " responsive"; //add space after quotation mark, otherwise class is added adjacent
} else {
x.className = "nav-bar";
}
Css:
.nav-bar.responsive li a{
float: none;
display: block !important; /* I think this needs to be crushed with important */
text-align: left;
/* position: relative; you don't need it */
}
you can simply do it with css
flex-direction: column;