dropdown cannot show over a div with hidden overflow - javascript

In my case, dropdown cannot show over the card cause the overflow is hidden, any solution ? Pls find bellow the css and html and js for the hover effect of a section. the idea of this card is a card with some text details and a dropdown list and in the right a banner with hover effect to have some options, as on the phone when we swipe to the left to get delete or ...
$(window).resize(function() {
var $window = $(window);
var windowsize = $window.width();
if (windowsize > 767) {
$('.section2').hover(
function() {
$(this).addClass('hover');
},
function() {
$(this).removeClass('hover');
}
);
}
});
$(window).trigger('resize');
$('.section2').bind('swiperight', function() {
$('.section2').removeClass('hover');
});
$('.section2').bind('swipeleft', function() {
$('.section2').removeClass('hover');
$(this).addClass('hover');
});
.card {
display: flex;
width: 100%;
background-color: white;
border: 1px solid lightgray;
border-radius: 8px;
justify-content: space-between;
align-items: center;
padding: 20px;
overflow: hidden;
position: relative;
transition: all ease .4s;
height: 90px;
margin-bottom: 100px;
}
.section1 {
width: 95%;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.dropdown {
position: relative;
display: inline-block;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f9f9f9;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
padding: 12px 16px;
z-index: 1;
}
.dropdown:hover .dropdown-content {
display: block;
}
.section2 {
position: absolute;
top: 0;
right: 0;
height: 100%;
z-index: 1;
display: flex;
transition: all ease .4s;
transform: translateX(90%);
background-color: purple;
color: whitesmoke;
}
.section2.hover {
transform: translateX(0%);
}
.section2 a {
color: var(--white);
text-decoration: none;
display: inline-flex;
width: 60px;
height: 100%;
margin-right: 0%;
align-items: center;
justify-content: center;
transition: all ease .4s;
}
.section2 a:hover {
color: var(--gray2);
background-color: var(--gray1);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="card">
<div class="section1">
<div>Ipsus lupem ipsus lupem</div>
<div class="dropdown">
<span>Mouse over me</span>
<div class="dropdown-content">
<p>Hello World!</p>
<p>Hello World!</p>
<p>Hello World!</p>
</div>
</div>
</div>
<div class="section2">
option1
option2
option3
option4
</div>
</div>

You need to remove position: relative from the ancestors. The combination of that and overflow: hidden is the cause of your problem.
$(window).resize(function() {
var $window = $(window);
var windowsize = $window.width();
if (windowsize > 767) {
$('.section2').hover(
function() {
$(this).addClass('hover');
},
function() {
$(this).removeClass('hover');
}
);
}
});
$(window).trigger('resize');
$('.section2').bind('swiperight', function() {
$('.section2').removeClass('hover');
});
$('.section2').bind('swipeleft', function() {
$('.section2').removeClass('hover');
$(this).addClass('hover');
});
.card {
box-sizing: border-box;
display: flex;
width: 100%;
background-color: white;
border: 1px solid lightgray;
border-radius: 8px;
justify-content: space-between;
align-items: center;
padding: 20px;
overflow: hidden;
transition: all ease .4s;
height: 90px;
margin-bottom: 100px;
}
.section1 {
width: 95%;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.dropdown {
display: inline-block;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f9f9f9;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
padding: 12px 16px;
z-index: 1;
}
.dropdown:hover .dropdown-content {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="card">
<div class="section1">
<div class="dropdown">
<span>Mouse over me</span>
<div class="dropdown-content">
<p>Hello World!</p>
<p>Hello World!</p>
<p>Hello World!</p>
</div>
</div>
</div>
</div>

Related

Unable to properly show content in all devices

I'm making a car research/ranking website using React. Coming to the issue, I have 3 cards, with content on it once you hover over it.
It works perfectly well in desktops, but it doesn't properly show content in smaller devices: it overflows to the other section.
To fix this, I have added a media query to it, but it doesn't work either.
Please check my code:
.sec2 {
height: 100vh;
width: 100%;
color: white;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
background: linear-gradient(to left, rgba(0, 0, 0, 0.7), rgba(0, 0, 0, 0.7)),
url(https://static.feber.se/article_images/48/81/62/488162_1920.jpg)
no-repeat top center;
}
.wrapper {
display: flex;
width: 90%;
justify-content: space-around;
}
.card {
width: 350px;
height: 370px;
border-radius: 15px;
padding: 1.5rem;
position: relative;
object-fit: fill;
display: flex;
align-items: flex-end;
transition: 0.4s ease-out;
box-shadow: 0px 7px 10px rgba(0, 0, 0, 0.5);
}
.card:hover {
transform: translateY(20px);
}
.card:hover:before {
opacity: 1;
}
.card:hover .info {
opacity: 1;
transform: translateY(0px);
}
.card:before {
content: "";
position: absolute;
top: 0;
left: 0;
display: block;
width: 100%;
height: 100%;
border-radius: 15px;
background: rgba(0, 0, 0, 0.6);
z-index: 2;
transition: 0.5s;
opacity: 0;
}
.card img {
width: 100%;
height: 100%;
object-fit: cover;
position: absolute;
top: 0;
left: 0;
border-radius: 15px;
}
.card .info {
position: relative;
z-index: 3;
color: white;
opacity: 0;
transform: translateY(30px);
transition: 0.5s;
}
.card .info h1 {
margin: 0px;
font-size: 2rem;
}
.card .info p {
letter-spacing: 1px;
font-size: 15px;
margin-top: 8px;
}
.card .info button {
padding: 0.6rem;
outline: none;
border: none;
border-radius: 3px;
background: white;
color: black;
font-weight: bold;
cursor: pointer;
transition: 0.4s ease;
}
.card .info button:hover {
background: dodgerblue;
color: white;
}
#media only screen and (min-width: 600px) and (max-width: 768px) {
.wrapper {
flex-direction: column;
justify-content: center;
align-items: center;
}
.card {
height: 270px;
padding: 1rem;
width: 250px;
margin-bottom: 10px;
}
.card .info h1 {
font-size: 1rem;
}
.card .info p {
font-size: 15px;
}
.card .info button {
padding: 0.4rem;
font-weight: normal;
font-size: 12px;
}
}
#media (max-width: 600px) {
.wrapper {
flex-direction: column;
justify-content: center;
align-items: center;
}
.card {
height: 15%;
padding: 0.3rem;
width: 180px;
margin-bottom: 5px;
}
.card .info h1 {
font-size: 1rem;
}
.card .info p {
font-size: 10px;
}
.card .info button {
padding: 0.3rem;
font-weight: normal;
font-size: 10px;
}
}
And
<div>
<header className="sec2" id="section2">
<h1>
What is in this website?
</h1>
<div class="wrapper">
<div class="card">
<img src="https://cdn.jdpower.com/JDPA_2022%20Genesis%20G70%20Red%20Front%20Quarter%20View.jpg" />
<div class="info">
<h1>Car Rankings</h1>
<p>
It contains cars ranked based on body type, done after
comprehensive research.
</p>
<button>Go</button>
</div>
</div>
<div class="card">
<img src="https://i0.wp.com/autonxt.net/wp-content/uploads/2018/01/autocontentexp.com2018-Lincoln-Navigator5-5b1aebecc618f268352b037fb2253a291d670994-1.jpg?resize=2500%2C1500&ssl=1" />
<div class="info">
<h1>Car Reviews</h1>
<p>Contains reviews of selective cars written by us.</p>
<button>Read More</button>
</div>
</div>
<div class="card">
<img src="https://static0.hotcarsimages.com/wordpress/wp-content/uploads/2020/09/AWD-e1600115646672.jpg" />
<div class="info">
<h1>Used Cars/h1>
<p> We rank used cars so that you will only get the best out of it.
</p>
<button>Read More</button>
</div>
</div>
</div>
</header>
</div>
Image in computer: click, and
Image in smaller devices: click
first add the margin: auto in .wrapper class and some margin: 5px; to .card class because this make content in the center and looks good.
.wrapper {
display: flex;
width: 90%;
margin: auto;
justify-content: space-around;
}
.card {
/* your code */
margin: 5px;
}
Now, add just update margin: 15px; of all .card instead of margin-bottom
Here is the full code, https://codesandbox.io/s/laughing-gwen-4i47v5?file=/src/Home.jsx

Responsive Navigation Hamburger Menu not working

I'm trying to make my navigation responsive but when i tried to resize my window, my hamburger doesn't allow the dropdown function to work. I took both the navigation and responsive hamburger online so is there somewhere that might be overwriting the hamburger ?
This is my HTML
<header>
<div class="logo">
<p>LEGEND</p>
<div class= "hamburger">
<div class="line"></div>
<div class="line"></div>
<div class="line"></div>
</div>
</div>
<nav class="nav-bar">
<ul>
<li>HOME</li>
<li>STORE</li>
<li>MY ACCOUNT</li>
<li>SEARCH</li>
</ul>
</nav>
<button>
<a href="#">
<h4 style="color: #f5f5f5">PLAY DIVINE</h4>
</a>
</button>
</header>
This is my css
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background-color: #12171c;
}
header {
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 10%;
background: rgba(0, 0, 0, 0.2);
position: fixed;
height: 10%;
}
.logo {
font-size: 30px;
font-weight: bold;
color: white;
letter-spacing: 1.5px;
cursor: pointer;
}
.nav-bar li {
display: inline-block;
list-style: none;
padding: 0px 15px;
}
a, button {
font-size: 16px;
font-weight: 500;
color: #b7b9bb;
text-decoration: none;
cursor: pointer;
}
button {
background: #967526;
border: 2px solid #ffce1f;
padding: 9px 25px;
}
.header-pic {
width: 100%;
height: 100%;
background-size: cover;
}
.hamburger {
display: none;
}
This is my css when it's responsive
#media only screen and (max-width: 1320px) {
.hamburger {
display: block;
cursor: pointer;
}
.hamburger .line {
width: 30px;
height: 3px;
background: #fefefe;
margin: 6px 0;
}
.nav-bar {
height: 0;
position: absolute;
top: 80px;
left: 0;
right: 0;
width: 100vw;
background: #11101b;
transition: 0.2s;
overflow: hidden;
}
.nav-bar.active {
height: 450px;
}
.nav-bar ul {
display: block;
width: fit-content;
margin: 80px auto 0 auto;
text-align: center;
transition: 0.5s;
opacity: 0;
}
.nav-bar.active ul {
opacity: 1;
}
.nav-bar ul li a {
margin-botton: 12px;
}
}
This is my javascript
<script>
hamburger = document.querySelector(".hamburger");
hamburger.onClick = function() {
navBar = document.querySelector(".nav-bar");
navbar.classList.toggle("active");
}
</script>
UPDATE
I revised the solution so that the 2 blocks are for:
In small screen but active is not on
In small screen and active is on
This separation protects the style from broken when transition happen as active toggles.
More styles can be added to the first block to define how this list should look like, such as making it display the list in column.
Example:
.nav-bar ul {
display: flex;
flex-direction: column;
width: fit-content;
margin: 80px auto 0 auto;
text-align: center;
transition: 0.5s;
opacity: 0;
}
.nav-bar.active ul {
opacity: 1;
}
Original
This is because your JS code has some syntax error. Here is what to do:
Use const to declare hamburger and navbar.
Call addEventListener on hamburger to add the function for toggling class of navbar
Follow the below example to revise your code, or visit a live demo of it fixed here: codepen
const hamburger = document.querySelector(".hamburger");
const navbar = document.querySelector(".nav-bar");
hamburger.addEventListener("click", () => navbar.classList.toggle("active"));
Hope this solution will help.
Your code has nothing wrong, just few typos in your JavaScript:
You have onClick instead of onclick
navbar instead of navBar at navbar.classList.toggle("active")
Corrected version
<script>
hamburger = document.querySelector(".hamburger");
hamburger.onclick = function() {
navBar = document.querySelector(".nav-bar");
navBar.classList.toggle("active");
}
</script>
Extra (Change display: block; to display: grid; in .nav-bar ul selector in CSS media query to display dropdown in vertical list)
.nav-bar ul {
display: grid;
width: fit-content;
margin: 80px auto 0 auto;
text-align: center;
transition: 0.5s;
opacity: 0;
}
hamburger = document.querySelector(".hamburger");
hamburger.onclick = function() {
navBar = document.querySelector(".nav-bar");
navBar.classList.toggle("active");
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background-color: #12171c;
}
header {
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 10%;
background: rgba(0, 0, 0, 0.2);
position: fixed;
height: 10%;
}
.logo {
font-size: 30px;
font-weight: bold;
color: white;
letter-spacing: 1.5px;
cursor: pointer;
}
.nav-bar li {
display: inline-block;
list-style: none;
padding: 0px 15px;
}
a,
button {
font-size: 16px;
font-weight: 500;
color: #b7b9bb;
text-decoration: none;
cursor: pointer;
}
button {
background: #967526;
border: 2px solid #ffce1f;
padding: 9px 25px;
}
.header-pic {
width: 100%;
height: 100%;
background-size: cover;
}
.hamburger {
display: none;
}
#media only screen and (max-width: 1320px) {
.hamburger {
display: block;
cursor: pointer;
}
.hamburger .line {
width: 30px;
height: 3px;
background: #fefefe;
margin: 6px 0;
}
.nav-bar {
height: 0;
position: absolute;
top: 80px;
left: 0;
right: 0;
width: 100vw;
background: #11101b;
transition: 0.2s;
overflow: hidden;
}
.nav-bar.active {
height: 450px;
}
.nav-bar ul {
display: grid;
width: fit-content;
margin: 80px auto 0 auto;
text-align: center;
transition: 0.5s;
opacity: 0;
}
.nav-bar.active ul {
opacity: 1;
}
.nav-bar ul li a {
margin-bottom: 12px;
}
}
<header>
<div class="logo">
<p>LEGEND</p>
<div class="hamburger">
<div class="line"></div>
<div class="line"></div>
<div class="line"></div>
</div>
</div>
<nav class="nav-bar">
<ul>
<li>HOME</li>
<li>STORE</li>
<li>MY ACCOUNT</li>
<li>SEARCH</li>
</ul>
</nav>
<button>
<a href="#">
<h4 style="color: #f5f5f5">PLAY DIVINE</h4>
</a>
</button>
</header>
Better Solution
Quote from MDN Web Docs, as in this link:
The recommended mechanism for adding event handlers in web pages is the addEventListener() method
You may use addEventListener() to achieve the same result:
<script>
hamburger = document.querySelector(".hamburger");
hamburger.addEventListener("click", () => {
navBar = document.querySelector(".nav-bar");
navBar.classList.toggle("active");
});
</script>
hamburger = document.querySelector(".hamburger");
hamburger.addEventListener("click", () => {
navBar = document.querySelector(".nav-bar");
navBar.classList.toggle("active");
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background-color: #12171c;
}
header {
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 10%;
background: rgba(0, 0, 0, 0.2);
position: fixed;
height: 10%;
}
.logo {
font-size: 30px;
font-weight: bold;
color: white;
letter-spacing: 1.5px;
cursor: pointer;
}
.nav-bar li {
display: inline-block;
list-style: none;
padding: 0px 15px;
}
a,
button {
font-size: 16px;
font-weight: 500;
color: #b7b9bb;
text-decoration: none;
cursor: pointer;
}
button {
background: #967526;
border: 2px solid #ffce1f;
padding: 9px 25px;
}
.header-pic {
width: 100%;
height: 100%;
background-size: cover;
}
.hamburger {
display: none;
}
#media only screen and (max-width: 1320px) {
.hamburger {
display: block;
cursor: pointer;
}
.hamburger .line {
width: 30px;
height: 3px;
background: #fefefe;
margin: 6px 0;
}
.nav-bar {
height: 0;
position: absolute;
top: 80px;
left: 0;
right: 0;
width: 100vw;
background: #11101b;
transition: 0.2s;
overflow: hidden;
}
.nav-bar.active {
height: 450px;
}
.nav-bar ul {
display: grid;
width: fit-content;
margin: 80px auto 0 auto;
text-align: center;
transition: 0.5s;
opacity: 0;
}
.nav-bar.active ul {
opacity: 1;
}
.nav-bar ul li a {
margin-bottom: 12px;
}
}
<header>
<div class="logo">
<p>LEGEND</p>
<div class="hamburger">
<div class="line"></div>
<div class="line"></div>
<div class="line"></div>
</div>
</div>
<nav class="nav-bar">
<ul>
<li>HOME</li>
<li>STORE</li>
<li>MY ACCOUNT</li>
<li>SEARCH</li>
</ul>
</nav>
<button>
<a href="#">
<h4 style="color: #f5f5f5">PLAY DIVINE</h4>
</a>
</button>
</header>
Alternate Solution
For readers who are more familiar to add() / remove(), here's some alternatives:
<script>
hamburger = document.querySelector(".hamburger");
hamburger.addEventListener("click", () => {
navBar = document.querySelector(".nav-bar");
if (navBar.classList.contains("active")) {
navBar.classList.remove("active");
} else {
navBar.classList.add("active");
}
});
</script>
hamburger = document.querySelector(".hamburger");
hamburger.addEventListener("click", () => {
navBar = document.querySelector(".nav-bar");
if (navBar.classList.contains("active")) {
navBar.classList.remove("active");
} else {
navBar.classList.add("active");
}
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background-color: #12171c;
}
header {
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 10%;
background: rgba(0, 0, 0, 0.2);
position: fixed;
height: 10%;
}
.logo {
font-size: 30px;
font-weight: bold;
color: white;
letter-spacing: 1.5px;
cursor: pointer;
}
.nav-bar li {
display: inline-block;
list-style: none;
padding: 0px 15px;
}
a,
button {
font-size: 16px;
font-weight: 500;
color: #b7b9bb;
text-decoration: none;
cursor: pointer;
}
button {
background: #967526;
border: 2px solid #ffce1f;
padding: 9px 25px;
}
.header-pic {
width: 100%;
height: 100%;
background-size: cover;
}
.hamburger {
display: none;
}
#media only screen and (max-width: 1320px) {
.hamburger {
display: block;
cursor: pointer;
}
.hamburger .line {
width: 30px;
height: 3px;
background: #fefefe;
margin: 6px 0;
}
.nav-bar {
height: 0;
position: absolute;
top: 80px;
left: 0;
right: 0;
width: 100vw;
background: #11101b;
transition: 0.2s;
overflow: hidden;
}
.nav-bar.active {
height: 450px;
}
.nav-bar ul {
display: grid;
width: fit-content;
margin: 80px auto 0 auto;
text-align: center;
transition: 0.5s;
opacity: 0;
}
.nav-bar.active ul {
opacity: 1;
}
.nav-bar ul li a {
margin-bottom: 12px;
}
}
<header>
<div class="logo">
<p>LEGEND</p>
<div class="hamburger">
<div class="line"></div>
<div class="line"></div>
<div class="line"></div>
</div>
</div>
<nav class="nav-bar">
<ul>
<li>HOME</li>
<li>STORE</li>
<li>MY ACCOUNT</li>
<li>SEARCH</li>
</ul>
</nav>
<button>
<a href="#">
<h4 style="color: #f5f5f5">PLAY DIVINE</h4>
</a>
</button>
</header>

Checkbox with classList.toggle isn't toggling the classes. No errors shown

I have a checkbox, that should trigger the menu to slide in from left side of the screen.The problem is when I got the menu hidden on the left, i can't make the function work. When I click the checkbox icon, it's animation works but nothing else happens. The menu is still hidden and I get no errors.
Here is a snippet of my code:
function showMenuSlider() {
var slider = document.querySelector(".menu-slider");
slider.classList.toggle("menu-slider-show");
var sliderOpacity = document.querySelector(".menu-slider-opacity");
sliderOpacity.classList.toggle("menu-slider-opacity-show")
}
* {
margin: 0;
padding: 0;
font-size: 16px;
font-family: Open Sans;
line-height: 1.6;
display: block;
}
html {
scroll-behavior: smooth;
}
main {
position: relative;
}
header {
width: 100%;
position: fixed;
top: 0;
z-index: 95;
box-shadow: 0px -2px 15px rgba(0, 0, 0, 1);
}
.header-container {
background-color: white;
display: flex;
flex-direction: column;
position: relative;
}
.header-upbar {
display: flex;
justify-content: space-between;
align-items: center;
align-content: center;
z-index: 50;
background-color: white;
width: 100%;
margin-top: 9px;
}
.header-upbar p {
font-size: 16px;
font-weight: 500;
color: grey;
}
.header-upbar-item2,
.header-upbar-item3 {
display: flex;
justify-content: center;
align-content: center;
align-items: center;
}
.header-upbar a {
text-decoration: none;
flex-basis: 50%;
display: flex;
justify-content: center;
align-items: center;
align-content: center;
padding: 8px;
border-bottom: 0.5px solid grey;
}
.header-upbar a:first-of-type {
border-right: 0.5px solid grey;
}
.header-upbar-item2 img {
height: 23px;
margin-right: 6px;
}
.header-upbar-item3 img {
height: 23px;
margin: 0px 6px 0px 0px;
}
.header-downbar {
position: relative;
display: flex;
justify-content: space-between;
align-items: center;
align-content: center;
z-index: 51;
background-color: white;
}
.header-downbar-logo {
display: flex;
align-content: center;
align-items: center;
justify-content: center;
}
.header-downbar-logo img {
margin: 18px 18px 18px 18px;
height: 30px;
}
.header-downbar-menu {
height: 40px;
width: 40px;
display: block;
position: fixed;
margin: 15px 18px 15px 18px;
z-index: 502;
right: 5px;
top: 50px;
z-index: 100;
}
#menu {
display: none;
}
.icon {
width: 100%;
height: 100%;
display: block;
cursor: pointer;
position: relative;
}
.icon .menu,
.icon .menu::before,
.icon .menu::after {
content: '';
background-color: rgba(50, 50, 50, 1);
display: block;
position: absolute;
height: 4px;
width: 35px;
transition: background ease .3s, top ease .3s .3s, transform ease .3s;
}
.menu {
top: 17.5px;
}
.menu::before {
top: 12px;
}
.menu::after {
top: -12px;
}
#menu:checked+.menu {
background: transparent;
}
#menu:checked+.menu::before {
transform: rotate(45deg);
}
#menu:checked+.menu::after {
transform: rotate(-45deg);
}
#menu:checked+.menu::before,
#menu:checked+.menu::after {
top: 0;
transition: top ease 0.3s, transform ease 0.3s 0.3s;
}
.menu-slider-opacity {
width: 100%;
height: 100vh;
background-color: rgba(0, 0, 0, 0.6);
z-index: 98;
position: absolute;
top: 0;
left: -100%;
display: block;
}
.menu-slider {
width: 200px;
height: 100vh;
background-color: white;
z-index: 99;
position: absolute;
;
top: 0;
left: -100%;
display: block;
}
.menu-slider-show {
left: 0;
}
.menu-slider-opacity-show {
left: 0;
}
<div class="header-downbar-menu" onclick="showMenuSlider()">
<label for="menu" class="icon"><input type="checkbox" id="menu">
<div class="menu"></div>
</label>
</div>
<div class="menu-slider-opacity"></div>
<div class="menu-slider"></div>
<header id="header">
<div class="header-container">
<div class="header-upbar">
<a href="mailto: ">
<div class="header-upbar-item2">
<img src="img/Fenix-e-mail-icon-white.png" alt="">
<p>blablablabla#o2.pl</p>
</div>
</a>
<a href="tel: ">
<div class="header-upbar-item3">
<img src="img/Fenix-phone-icon-white.png" alt="">
<p>+48 999 999 999</p>
</div>
</a>
</div>
<div class="header-downbar">
<div class="header-downbar-logo">
<img src="img/Fenix-logo-black.png" alt="">
</div>
</div>
</div>
</header>
The button is outside the header, because i need it to be on top of the dark opacity behind the menu. In the future I will make a nice white rounded background to it, so it won't invisible.
Of course if you know better way to do it, be my guest. I'm struggling with this for a while...
The problem is that you add the onclick handler on the header-downbar-menu and not on the checkbox. So when clicking the checkbox you also click on header-downbar-menu so the event is triggered twice. So the class is toggled twice ( added/removed in the same time...almost :) )
Add the click event on the input. ( you could use an onchange event instead of the click event to check the state checked or unchecked , that might help you )
function showMenuSlider() {
var slider = document.querySelector(".menu-slider");
slider.classList.toggle("menu-slider-show");
var sliderOpacity = document.querySelector(".menu-slider-opacity");
sliderOpacity.classList.toggle("menu-slider-opacity-show")
}
html {
scroll-behavior: smooth;
}
main {
position: relative;
}
header {
width: 100%;
position: fixed;
top: 0;
z-index: 95;
box-shadow: 0px -2px 15px rgba(0, 0, 0, 1);
}
.header-container {
background-color: white;
display: flex;
flex-direction: column;
position: relative;
}
.header-upbar {
display: flex;
justify-content: space-between;
align-items: center;
align-content: center;
z-index: 50;
background-color: white;
width: 100%;
margin-top: 9px;
}
.header-upbar p {
font-size: 16px;
font-weight: 500;
color: grey;
}
.header-upbar-item2,
.header-upbar-item3 {
display: flex;
justify-content: center;
align-content: center;
align-items: center;
}
.header-upbar a {
text-decoration: none;
flex-basis: 50%;
display: flex;
justify-content: center;
align-items: center;
align-content: center;
padding: 8px;
border-bottom: 0.5px solid grey;
}
.header-upbar a:first-of-type {
border-right: 0.5px solid grey;
}
.header-upbar-item2 img {
height: 23px;
margin-right: 6px;
}
.header-upbar-item3 img {
height: 23px;
margin: 0px 6px 0px 0px;
}
.header-downbar {
position: relative;
display: flex;
justify-content: space-between;
align-items: center;
align-content: center;
z-index: 51;
background-color: white;
}
.header-downbar-logo {
display: flex;
align-content: center;
align-items: center;
justify-content: center;
}
.header-downbar-logo img {
margin: 18px 18px 18px 18px;
height: 30px;
}
.header-downbar-menu {
height: 40px;
width: 40px;
display: block;
position: fixed;
margin: 15px 18px 15px 18px;
z-index: 502;
right: 5px;
top: 50px;
z-index: 100;
}
#menu {
display: none;
}
.icon {
width: 100%;
height: 100%;
display: block;
cursor: pointer;
position: relative;
}
.icon .menu,
.icon .menu::before,
.icon .menu::after {
content: '';
background-color: rgba(50, 50, 50, 1);
display: block;
position: absolute;
height: 4px;
width: 35px;
transition: background ease .3s, top ease .3s .3s, transform ease .3s;
}
.menu {
top: 17.5px;
}
.menu::before {
top: 12px;
}
.menu::after {
top: -12px;
}
#menu:checked+.menu {
background: transparent;
}
#menu:checked+.menu::before {
transform: rotate(45deg);
}
#menu:checked+.menu::after {
transform: rotate(-45deg);
}
#menu:checked+.menu::before,
#menu:checked+.menu::after {
top: 0;
transition: top ease 0.3s, transform ease 0.3s 0.3s;
}
.menu-slider-opacity {
width: 100%;
height: 100vh;
background-color: rgba(0, 0, 0, 0.6);
z-index: 98;
position: absolute;
top: 0;
left: -100%;
display: block;
}
.menu-slider {
width: 200px;
height: 100vh;
background-color: white;
z-index: 99;
position: absolute;
top: 0;
left: -100%;
display: block;
}
.menu-slider-show {
left: 0;
}
.menu-slider-opacity-show {
left: 0;
}
<div class="header-downbar-menu">
<label for="menu" class="icon"><input type="checkbox" id="menu" onclick="showMenuSlider()">
<div class="menu"></div>
</label>
</div>
<div class="menu-slider-opacity"></div>
<div class="menu-slider"></div>
<header id="header">
<div class="header-container">
<div class="header-upbar">
<a href="mailto: ">
<div class="header-upbar-item2">
<img src="img/Fenix-e-mail-icon-white.png" alt="">
<p>blablablabla#o2.pl</p>
</div>
</a>
<a href="tel: ">
<div class="header-upbar-item3">
<img src="img/Fenix-phone-icon-white.png" alt="">
<p>+48 999 999 999</p>
</div>
</a>
</div>
<div class="header-downbar">
<div class="header-downbar-logo">
<img src="img/Fenix-logo-black.png" alt="">
</div>
</div>
</div>
</header>

Toggle Between Search Icon and Cancel Icon

I need to toggle between two icons (basically search icon and cancel icon) when a particular element is clicked using jQuery. In the case of the code below, the telegram icon changes to whatsapp icon on click. I want to change back to telegram icon when the whatsapp icon is clicked. I would be grateful if the same code can also be written in JavaScript.
$(document).ready(function() {
$(".searchIcon").click(function() {
$(".search").toggleClass("active");
$(".searchIcon").attr(
"src",
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQc3j87kFSpq-XNafMC9V14xUyePHRRXpPMed4O_vH_nGWfLjE-dn0&s=0"
);
});
});
body {
padding: 0 !important;
margin: 0 !important;
font-size: 16px;
background: black;
}
* {
box-sizing: border-box;
}
.container {
background-color: navy;
}
.preTopNav-Items {
display: flex;
flex-flow: row wrap;
padding-top: 10px;
padding-bottom: 10px;
}
.preTopNav-Items img {
width: 20px;
height: 20px;
}
.search {
display: flex;
align-items: center;
justify-content: flex-end;
width: calc(250px + 20px + 7px + 7px);
border-radius: 6px;
padding: 0;
overflow: hidden;
border: none;
position: relative;
height: 28px;
}
.search img:hover {
cursor: pointer;
}
.searchIcon-wrapper {
background-color: navy;
position: absolute;
right: 0;
z-index: 1;
padding: 0 7px;
display: flex;
align-items: center;
border-radius: 4px;
}
.search input {
position: absolute;
right: 0px;
width: 250px;
padding: 3px 10px;
font-size: 16px;
transform: translateX(calc(100% + 34px));
transition: transform 0.5s ease-in-out;
}
.search.active input {
transform: translateX(-34px);
}
.search.active {
box-shadow: 10px 4px 10px 2px rgba(0, 0, 0, 0.5);
transition: box-shadow 1.5s;
}
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="https://kit.fontawesome.com/718022a53c.js" crossorigin="anonymous"></script>
<div class="container">
<div class="preTopNav-Items search">
<input type="text" class="searchBar" placeholder="Search..." />
<div class="searchIcon-wrapper">
<img class="searchIcon" src="https://www.telegram.org/img/t_logo.png" alt="" style: "width: 20px; height:20px;"/>
</div>
</div>
</div>
Have a go with this
I extracted the style (you had a typo -colon after style instead of equal sign) and hid the second icon
.searchIcon {
width: 20px;
height: 20px;
}
.searchIcon:nth-child(2) {
display: none;
}
jQuery
$(function() {
$(".searchIcon").on("click",function() {
$(".search").toggleClass("active");
$(this).toggle()
$(this).siblings().toggle()
});
});
body {
padding: 0 !important;
margin: 0 !important;
font-size: 16px;
background: black;
}
* {
box-sizing: border-box;
}
.container {
background-color: navy;
}
.preTopNav-Items {
display: flex;
flex-flow: row wrap;
padding-top: 10px;
padding-bottom: 10px;
}
.preTopNav-Items img {
width: 20px;
height: 20px;
}
.search {
display: flex;
align-items: center;
justify-content: flex-end;
width: calc(250px + 20px + 7px + 7px);
border-radius: 6px;
padding: 0;
overflow: hidden;
border: none;
position: relative;
height: 28px;
}
.search img:hover {
cursor: pointer;
}
.searchIcon-wrapper {
background-color: navy;
position: absolute;
right: 0;
z-index: 1;
padding: 0 7px;
display: flex;
align-items: center;
border-radius: 4px;
}
.search input {
position: absolute;
right: 0px;
width: 250px;
padding: 3px 10px;
font-size: 16px;
transform: translateX(calc(100% + 34px));
transition: transform 0.5s ease-in-out;
}
.search.active input {
transform: translateX(-34px);
}
.search.active {
box-shadow: 10px 4px 10px 2px rgba(0, 0, 0, 0.5);
transition: box-shadow 1.5s;
}
.searchIcon {
width: 20px;
height: 20px;
}
.searchIcon:nth-child(2) {
display: none;
}
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="https://kit.fontawesome.com/718022a53c.js" crossorigin="anonymous"></script>
<div class="container">
<div class="preTopNav-Items search">
<input type="text" class="searchBar" placeholder="Search..." />
<div class="searchIcon-wrapper">
<img class="searchIcon" src="https://www.telegram.org/img/t_logo.png" />
<img class="searchIcon whatsapp" src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQc3j87kFSpq-XNafMC9V14xUyePHRRXpPMed4O_vH_nGWfLjE-dn0&s=0" />
</div>
</div>
</div>
Vanilla JS
I added a new class
.searchIcon {
display: none;
}
.isVisible {
display:block
}
window.addEventListener("load", function() { // page load
document.querySelector(".searchIcon-wrapper").addEventListener("click", function(e) { // delegation
const tgt = e.target;
if (tgt.classList.contains("searchIcon")) { // one of the images
document.querySelector(".search").classList.toggle("active");
tgt.classList.toggle("isVisible");
const sib = tgt.classList.contains("whatsapp") ? 1 : 2; // which did we click?
document.querySelector(".searchIcon:nth-child("+sib+")").classList.toggle("isVisible");
}
});
});
body {
padding: 0 !important;
margin: 0 !important;
font-size: 16px;
background: black;
}
* {
box-sizing: border-box;
}
.container {
background-color: navy;
}
.preTopNav-Items {
display: flex;
flex-flow: row wrap;
padding-top: 10px;
padding-bottom: 10px;
}
.preTopNav-Items img {
width: 20px;
height: 20px;
}
.search {
display: flex;
align-items: center;
justify-content: flex-end;
width: calc(250px + 20px + 7px + 7px);
border-radius: 6px;
padding: 0;
overflow: hidden;
border: none;
position: relative;
height: 28px;
}
.search img:hover {
cursor: pointer;
}
.searchIcon-wrapper {
background-color: navy;
position: absolute;
right: 0;
z-index: 1;
padding: 0 7px;
display: flex;
align-items: center;
border-radius: 4px;
}
.search input {
position: absolute;
right: 0px;
width: 250px;
padding: 3px 10px;
font-size: 16px;
transform: translateX(calc(100% + 34px));
transition: transform 0.5s ease-in-out;
}
.search.active input {
transform: translateX(-34px);
}
.search.active {
box-shadow: 10px 4px 10px 2px rgba(0, 0, 0, 0.5);
transition: box-shadow 1.5s;
}
.searchIcon {
width: 20px;
height: 20px;
}
.searchIcon {
display: none;
}
.isVisible {
display:block
}
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="https://kit.fontawesome.com/718022a53c.js" crossorigin="anonymous"></script>
<div class="container">
<div class="preTopNav-Items search">
<input type="text" class="searchBar" placeholder="Search..." />
<div class="searchIcon-wrapper">
<img class="searchIcon isVisible" src="https://www.telegram.org/img/t_logo.png" />
<img class="searchIcon whatsapp" src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQc3j87kFSpq-XNafMC9V14xUyePHRRXpPMed4O_vH_nGWfLjE-dn0&s=0" />
</div>
</div>
</div>
So what I personally would do is use psuedo elements on the iconWrapper div and then just toggle a class on and off hiding or showing the respective pseudo element. You can either put the images as their content value or use the background-image property and set the images there.
var el = document.querySelector('.iconWrapper');
el.onclick = function() {
el.classList.toggle('active');
}
.iconWrapper {
width: 100px;
height: 50px;
background: blue;
position: relative;
}
.iconWrapper:before, .iconWrapper:after {
width: 50px;
height: 50px;
content: '';
display: block;
position: absolute;
top: 0;
right: -50px;
}
.iconWrapper:before {
background: green;
display: none;
}
.iconWrapper:after {
background: red;
}
.iconWrapper.active:before { display: block; }
.iconWrapper.active:after { display: none; }
<div class="iconWrapper"></div>
I created a reusable function so that you can change another img src like this in the future if you wanted to.
var searchIcon = document.getElementsByClassName("searchIcon")[0];
function togglesrc(obj, icon_off, icon_on){
if(obj.src == icon_off){
obj.src = icon_on;
}
else{
obj.src = icon_off;
}
}
searchIcon.addEventListener("click",function(){
document.querySelector(".search").classList.toggle("active");
var icon_on = "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQc3j87kFSpq-XNafMC9V14xUyePHRRXpPMed4O_vH_nGWfLjE-dn0&s=0";
var icon_off = "https://www.telegram.org/img/t_logo.png";
togglesrc(this, icon_off, icon_on);
});
body {
padding: 0 !important;
margin: 0 !important;
font-size: 16px;
background: black;
}
* {
box-sizing: border-box;
}
.container {
background-color: navy;
}
.preTopNav-Items {
display: flex;
flex-flow: row wrap;
padding-top: 10px;
padding-bottom: 10px;
}
.preTopNav-Items img {
width: 20px;
height: 20px;
}
.search {
display: flex;
align-items: center;
justify-content: flex-end;
width: calc(250px + 20px + 7px + 7px);
border-radius: 6px;
padding: 0;
overflow: hidden;
border: none;
position: relative;
height: 28px;
}
.search img:hover {
cursor: pointer;
}
.searchIcon-wrapper {
background-color: navy;
position: absolute;
right: 0;
z-index: 1;
padding: 0 7px;
display: flex;
align-items: center;
border-radius: 4px;
}
.search input {
position: absolute;
right: 0px;
width: 250px;
padding: 3px 10px;
font-size: 16px;
transform: translateX(calc(100% + 34px));
transition: transform 0.5s ease-in-out;
}
.search.active input {
transform: translateX(-34px);
}
.search.active {
box-shadow: 10px 4px 10px 2px rgba(0, 0, 0, 0.5);
transition: box-shadow 1.5s;
}
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="https://kit.fontawesome.com/718022a53c.js" crossorigin="anonymous"></script>
<div class="container">
<div class="preTopNav-Items search">
<input type="text" class="searchBar" placeholder="Search..." />
<div class="searchIcon-wrapper">
<img class="searchIcon" src="https://www.telegram.org/img/t_logo.png" alt="" style: "width: 20px; height:20px;"/>
</div>
</div>
</div>

why the height of my sticky navbar disappear when I scroll?

I'm trying to build a website with a sticky nav bar in JavaScript. For the first load of the page everything is okay. But when I scroll, the navbar is flickering and after this the body up (see the pictures). I don't know why.
Just after the navbar I have slideshow and because of this the pictures are cut by the navbar and I'm on the top of the page.
See my code too below...
/*sticky_navbar*/
window.onscroll = function() {
myFunction()
};
var navbar = document.getElementById("header");
var sticky = navbar.offsetTop;
function myFunction() {
if (window.pageYOffset >= sticky) {
navbar.classList.add("sticky")
} else {
navbar.classList.remove("sticky");
}
}
#charset "UTF-8";
/* CSS Document */
body {
margin: 0;
font-size: 28px;
background-color: #00011f;
display: flex;
flex-direction: column;
margin: auto;
}
/* Style the navbar */
#header {
display: flex;
justify-content: flex-end;
background: rgba(139, 139, 157, 1);
z-index: 2;
}
#Title {
margin: 0 auto 0 0;
height: 20px;
margin-top: 20px;
padding-left: 10px;
border-bottom: 1px solid white;
padding-top: 10px;
padding-bottom: 35px;
flex: 1;
}
#navbar {
overflow: hidden;
background: rgba(139, 139, 157, 0);
display: flex;
justify-content: flex-end;
border-bottom: 5px solid white;
padding-bottom: 20px;
padding-top: 20px;
}
.menu:nth-child(1) {
order: 1;
}
.menu:nth-child(2) {
order: 4;
}
.menu:nth-child(3) {
order: 3;
}
.menu:nth-child(4) {
order: 2;
}
.menu:nth-child(5) {
order: 5;
}
IMG.background {
display: block;
margin-left: auto;
margin-right: auto;
z-index: 1;
width: 60%;
}
#navbar a {
display: block;
color: #FFF;
text-align: center;
padding: 10px 16px;
text-decoration: none;
font-size: 17px;
}
#navbar a:hover {
background-color: #ddd;
color: black;
}
#navbar a.active {
background: rgba(217, 78, 68, 0.5);
color: white;
}
.content {
padding: 16px;
color: #ddd;
background-color: #FFF
}
.sticky {
position: fixed;
top: 0;
width: 100%;
}
.sticky+.content {
padding-top: 60px;
}
/*END NAVBAR*/
#display {
display: flex;
}
<div id="header">
<div id="Title">
<img src="IMAGES/PNG/logo.png" alt="logo" />
</div>
<div id="navbar">
<div class="menu"> <a class="active" href="javascript:void(0)">Blog</a></div>
<div class="menu"> Contact</div>
<div class="menu"> L'électrophotonique</div>
<div class="menu"> Qui sommes nous?</div>
</div>
</div>
<div class="content">
<h3>Sticky Navigation Example</h3>
</div>
the body jump to another position because your navbar has height of at least 86px but you gave .sticky+.content only padding-top of 60px.
maybe you can use position: sticky; instead? https://caniuse.com/#feat=css-sticky
or
to prevent flickering give the navbar onload the position fixed
#navbar {
overflow: hidden;
background: rgba(139, 139, 157, 0);
display: flex;
justify-content: flex-end;
border-bottom: 5px solid white;
padding-bottom: 20px;
padding-top: 20px;
position: fixed;
top: 0;
width: 100%;
}
.content {
padding: 60px 16px 16px 16px;
color: #ddd;
background-color: #FFF
}

Categories

Resources