ToggleClass() jQuery is not working only on Safari - javascript

I have got one small hope obstacle.
When I click on the menu button it doesn't show the navigation (nav), but ONLY in Safari browser. In all browsers this code working properly. It is so tricky grrrr.
Here is the code:
HTML
<nav>...</nav>
jQuery:
$('#menu-open').click(function () {
$(this).toggleClass('open');
$('.main-rhomboid').toggleClass('hide');
$('nav').toggleClass('visible');
$('body').toggleClass('overflow');
});
Css:
.visible{
display: block;
opacity: 1;}
nav{position: absolute;
z-index: 102;
width: 100%;
height: 100vh;
opacity: 0;
transition: opacity 4s;
background-color: $accent-blue;
display: none;
border: 10px solid $accent-yellow;
box-sizing: border-box;}

Related

Make hovered tooltip disappear when clicking button

I am trying to create a tooltip for whatever that needs it on my website, e.g. a button, text, etc. So far I have something like this:
https://jsfiddle.net/f06q3cLg/
.content {
display: grid;
width: 100vw;
height: 100vh;
place-content: center;
}
.content .parent {
border: 1px red solid;
padding: 10px;
position: relative;
}
.content .parent:hover .tooltip-wrapper {
animation: 0.1s fadeInTooltip;
animation-fill-mode: forwards;
animation-delay: 0.4s;
}
.content .parent:hover:before {
animation: 0.1s fadeInTooltip;
animation-fill-mode: forwards;
animation-delay: 0.4s;
}
.content .parent:active .tooltip-wrapper {
animation: 0.05s fadeOutTooltip;
animation-fill-mode: forwards;
}
.content .parent:active:before {
animation: 0.05s fadeOutTooltip;
animation-fill-mode: forwards;
}
.content .parent:before {
content: "";
display: block;
width: 0;
height: 0;
position: absolute;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
left: 50%;
transform: translateX(-50%);
opacity: 0;
}
.content .parent .tooltip-wrapper {
position: absolute;
display: grid;
left: 0;
width: 300px;
height: 100%;
opacity: 0;
pointer-events: none;
}
.content .parent .tooltip-wrapper.bottom {
top: calc(100% + 8px);
}
.content .parent .tooltip-wrapper .tooltip {
max-width: 300px;
width: fit-content;
padding: 8px;
position: absolute;
display: inline-block;
background: blue;
border-radius: 5px;
padding: 8px;
color: white;
font-size: 11px;
box-shadow: 0px 3px 3px rgba(0, 0, 0, 0.2);
line-height: 1.3;
text-align: left;
}
/* Keyframes */
#keyframes fadeInTooltip {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
#keyframes fadeOutTooltip {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
<div class="content">
<div class="parent">
Hover me
<div class="tooltip-wrapper">
<span class="tooltip">This is my tooltip</span>
</div>
</div>
</div>
As such, it works somewhat fine. My issue is that I would like the tooltip to disappear when I click the button. Now it vanishes, and then comes back with a 0.4s delay as the hover effect actually has. Ideally the tooltip should disappear as long as my mouse is still on the button, but when I remove it and re-enters the button, then the tooltip should re-appear.
I'm not sure if this is even achievable with pure CSS, but any JS would also do.
The problem is that :active is only applied as long as the mouse is down.
mdn: :active:
The :active CSS pseudo-class represents an element (such as a button) that is being activated by the user. When using a mouse, "activation" typically starts when the user presses down the primary mouse button.
What you could do (if you want to stay CSS only) is to use tabindex="0" on the <div class="parent"> and :focus instead of :active. But you need to verify that using tabindex="0" here won't hurt usability.
Ideally the tooltip should disappear as long as my mouse is still on the button, but when I remove it and re-enters the button, then the tooltip should re-appear.
That won't work with :focus either. I'm pretty sure that this behavior can only be achieved with JS. If it is possible with CSS only it likely would be a pretty hacky solution.
But from the perspective of a user, this seems to be counterintuitive that the tooltip won't appear after clicked.
A JavaScript solution that does what you want could look like this.
It is a simplified version of the tooltip to only show the relevant parts.
Every element having a tooltip has an attribute data-has-tooltip.
// event delegation for all mouse down event:
// this ensures that the code also works for elements that have been added to the DOM after that script was executed.
document.addEventListener('mousedown', (evt) => {
// check if the mousedown happened in an element with a tooltip
const element = evt.target.closest('[data-has-tooltip]');
if (element) {
// if the user already clicked on the element ignore the click
if (!element.classList.contains('active')) {
// add the active class to the element so that hover won't show the toolip
element.classList.add('active');
function removeActiveOnLeave() {
// remove the active class
element.classList.remove('active');
// remove the mouseleave event listener again
element.removeEventListener('mouseleave', removeActiveOnLeave)
}
// add an event listener for mouseleave to remove the active class
element.addEventListener('mouseleave', removeActiveOnLeave)
}
}
});
.parent {
display: inline-block;
border: 1px solid red;
padding: 0.5rem;
margin: 0.5rem;
}
.tooltip-wrapper {
display: none;
}
.parent:hover .tooltip-wrapper {
display: block;
}
.parent.active:hover .tooltip-wrapper {
display: none;
}
<div class="content">
<div class="parent" data-has-tooltip>
Hover me A
<div class="tooltip-wrapper">
<span class="tooltip">This is my tooltip A </span>
</div>
</div>
</div>
<div class="content">
<div class="parent" data-has-tooltip>
Hover me B
<div class="tooltip-wrapper">
<span class="tooltip">This is my tooltip B</span>
</div>
</div>
</div>
HTML
<div class="content">
<div class="parent" onClick="myFunction()">
Hover me
<div class="tooltip-wrapper">
<span class="tooltip" id="tooltip">This is mytooltip</span>
</div>
</div>
</div>
Javascript
function myFunction(){
var tooltip=document.getElementById("tooltip");
if (tooltip.style.display=="none") {
document.getElementById("tooltip").style.display="block";
} else {
document.getElementById("tooltip").style.display="none";
}
}
Manipulating 'display' property.
const parent = document.querySelector('.parent');
const toolTip = document.querySelector('.tooltip');
parent.addEventListener('click', () => {
if(toolTip.style.display !== 'none') {
toolTip.style.display = 'none';
}else {
toolTip.style.display = 'grid';
}
});
A solution using jQuery 3.4.1:
$(".parent").click(function () {
$(".tooltip-wrapper").css("display", "none");
});
The only downfall with that solution is once you click and re-hover in the same session, the SCSS :hover doesn't work properly.
No need to stress, just add the following if you want that functionality:
$(".parent").hover(function () {
$(".tooltip-wrapper").css("display", "block");
});
Try it out in the attached snippet:
$(".parent").click(function () {
$(".tooltip-wrapper").css("display", "none");
});
$(".parent").hover(function () {
$(".tooltip-wrapper").css("display", "block");
});
.content {
display: grid;
width: 100vw;
height: 100vh;
place-content: center;
}
.content .parent {
border: 1px red solid;
padding: 10px;
position: relative;
}
.content .parent:hover .tooltip-wrapper {
animation: 0.1s fadeInTooltip;
animation-fill-mode: forwards;
animation-delay: 0.4s;
}
.content .parent:hover:before {
animation: 0.1s fadeInTooltip;
animation-fill-mode: forwards;
animation-delay: 0.4s;
}
.content .parent:active .tooltip-wrapper {
animation: 0.05s fadeOutTooltip;
animation-fill-mode: forwards;
}
.content .parent:active:before {
animation: 0.05s fadeOutTooltip;
animation-fill-mode: forwards;
}
.content .parent:before {
content: "";
display: block;
width: 0;
height: 0;
position: absolute;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
left: 50%;
transform: translateX(-50%);
opacity: 0;
}
.content .parent .tooltip-wrapper {
position: absolute;
display: grid;
left: 0;
width: 300px;
height: 100%;
opacity: 0;
pointer-events: none;
}
.content .parent .tooltip-wrapper.bottom {
top: calc(100% + 8px);
}
.content .parent .tooltip-wrapper .tooltip {
max-width: 300px;
width: fit-content;
padding: 8px;
position: absolute;
display: inline-block;
background: blue;
border-radius: 5px;
padding: 8px;
color: white;
font-size: 11px;
box-shadow: 0px 3px 3px rgba(0, 0, 0, 0.2);
line-height: 1.3;
text-align: left;
}
/* Keyframes */
#keyframes fadeInTooltip {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
#keyframes fadeOutTooltip {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="content">
<div class="parent">
Hover me
<div class="tooltip-wrapper">
<span class="tooltip">This is my tooltip</span>
</div>
</div>
</div>
OR, you can see it working in this Fiddle. with your initial
SCSS.
You can uncomment the second function to see the hover working again after clicking.

why css transition is not working with js

<button className={this.state.isSaveDraft===true?
"cts_not_allowed stepper_btn_back" : "stepper_btn_back"} onClick={
this.state.isSaveDraft===false && this.approval_submitHandler} >
Update An
<p className='warning_message' >You have changed Metadata, please re calculate pre-opso</p>
</button>
.cts_not_allowed{
// pointer-events: none;
cursor: not-allowed !important;
position: relative;
transition: width 2s;
}
.warning_message{
display: none;
transition: 0.9s ease-in-out;
}
.cts_not_allowed:hover .warning_message{
display: block;
position: absolute;
bottom: 3vw;
right: 1vw;
// background-color: #ffffff;
border: 1px solid #ffffff;
width: 30vw;
color: red;
}
i tried everything also search a lot but dont know where the problem is in code mostly i used this transition with hover and it works for me iam using position relative and absolute thanks for help
Probably something like this:
.cts_not_allowed {
/* pointer-events: none; */
cursor: not-allowed !important;
position: relative;
transition: width 2s; /* is this used anywhere? */
}
.warning_message {
position: absolute;
bottom: 3vw;
right: 1vw;
/* background-color: #ffffff; */
border: 1px solid #ffffff;
width: 30vw;
color: red;
opacity: 0;
pointer-events: none;
transition: opacity 0.9s ease-in-out;
}
.cts_not_allowed:hover .warning_message {
opacity: 1;
pointer-events: auto;
}
Note that commenting out in CSS only works with /* ... */. CSS doesn't understand //, only SCSS does.
Also you cannot transition between display: none and display: block. Use opacity instead.
Depending on where it sits you might want to toggle pointer-events of your warning-message, too.

Mobile Menu Flashes up After Window Re-sizing (CSS & JS issue)

Scenario
I have a mobile menu that shows when the window is below 736px. There is a javascript toggle on this menu that adds and removes a CSS class that shows the mobile menu ul (and of course the child li items).
When you re-size the window the CSS media query swaps out the desktop menu for the separate mobile menu and the toggle works as planned.
Problem
When I re-size the window and then open and close the mobile menu it all works fine, when the window is then subsequently re-sized again after this, the mobile ul and li flash up for a second when the window hits the CSS media query break point again (736px).
I don't know how to stop this happening, it really is sending me totally around the bend and I seem to have spent hours on this and I'm getting nowhere.
If anyone can help me on this I would be so grateful.
P.S I don't mind the fact the mobile menu is still there after re-sizing if the mobile menu was left open - this is intended behaviour. It's when the mobile menu is closed and the window is resized to desktop and then back to mobile again that the flash of the menu is happening.
codepen: https://codepen.io/emilychews/pen/aVYGPr
JS
var mobileMenuButton = document.getElementById("mobile-menu-button")
var mobileMenuItems = document.getElementById("mobile-nav-menu-items")
// TOGGLE MOBILE MENU
var mobileMenu = false
function toggleMobileMenu() {
if (mobileMenu === false) {
mobileMenuItems.classList.remove("mobileMenuInactive")
mobileMenuItems.classList.add("mobileMenuActive")
mobileMenuButton.innerHTML = "Close"
mobileMenu = true
} else {
mobileMenuItems.classList.add("mobileMenuInactive")
mobileMenuItems.classList.remove("mobileMenuActive")
mobileMenuButton.innerHTML = "Menu"
mobileMenu = false
}
}
mobileMenuButton.addEventListener("click", function() {
toggleMobileMenu()
}, false)
CSS
body, ul {padding: 0; margin: 0}
#main-header {width: 100%; height: 100px;}
/* desktop navigation */
#main-navigation {
position: relative;
width: 100%;
height: 100px;
background: red;
display: flex;
justify-content: space-between;
box-sizing: border-box;
padding: 10px 5% 10px 5%;
align-items: center;
}
#logo-holder {
width: 150px;
height: 66px;
background-color: grey;
}
ul#nav-menu-items {
display: flex;
margin-left: auto;
}
#main-navigation ul li {list-style-type: none;}
#main-navigation ul#nav-menu-items li a {
padding: 10px 15px;
margin: 0 5px;
box-sizing: border-box;
background: yellow;
text-decoration: none;
color:#000;
}
#main-navigation ul#nav-menu-items li a:hover {
color:blue;
transition: color .25s;
}
#mobile-menu-button, ul#mobile-nav-menu-items {
display: none;
}
/* --- MOBILE MENU AND DROPDOWN ---
Below is a separate menu added for mobiles.
*/
#media screen and (max-width : 736px) {
/* hides desktop menu */
ul#nav-menu-items {display: none}
#mobile-menu-button {
display: flex;
justify-content: center;
background: blue;
color: white;
padding: 10px 15px;
min-width: 75px;
cursor: pointer;}
ul#mobile-nav-menu-items {
opacity: 0;
transform: scaleY(0);
display: flex;
flex-direction: column;
align-items: flex-start;
min-width: 150px;
background: blue;
position: absolute;
right: 5%;
top: 100px;
padding: 10px 0px;
}
ul#mobile-nav-menu-items li {
padding: 10px 10px;
}
ul#mobile-nav-menu-items li a {
padding: 10px 15px;
color: white;
text-decoration: none;
transition: color .3s;
}
ul#mobile-nav-menu-items li a:hover {
color: lightblue;
}
/* -------- MOBILE CLASSES ADDED WITH JavaScript*/
#mobile-nav-menu-items.mobileMenuActive {
animation: showMobileMenu .5s ease-in forwards;
}
#keyframes showMobileMenu {
0% {opacity: 0;transform: scaleY(0);}
1% {opacity: 0; transform: scaleY(1);}
100% {opacity: 1; transform: scaleY(1);}
}
#mobile-nav-menu-items.mobileMenuInactive {
animation: removeMobileMenu .5s ease-out forwards;
}
#keyframes removeMobileMenu {
0% {opacity: 1; transform: scaleY(1);}
99% {opacity: 0; transform: scaleY(1);}
100% {opacity: 0; transform: scaleY(0);}
}
} /*END OF MOBILE MENU STYLING*/
HTML
<header id="main-header">
<!-- desktop nav -->
<nav id="main-navigation">
<div id="logo-holder"></div>
<ul id="nav-menu-items">
<li class="menu-item menu-item-1">News</li>
<li class="menu-item menu-item-2">About</li>
<li class="menu-item menu-item-3">Contact</li>
</ul>
<!-- mobile nav -->
<ul id="mobile-nav-menu-items">
<li class="mobile-menu-item mobile-menu-item-1">News</li>
<li class="mobile-menu-item mobile-menu-item-2">About</li>
<li class="mobile-menu-item mobile-menu-item-3">Contact</li>
</ul>
<!-- button for triggering mobile nav -->
<div id="mobile-menu-button">Menu</div>
</nav>
</header>
I have just removed the code below and it worked, maybe because you are manipulating the same event in your CSS and JS file.
#keyframes removeMobileMenu {
0% {opacity: 1; transform: scaleY(1);}
99% {opacity: 0; transform: scaleY(1);}
100% {opacity: 0; transform: scaleY(0);}
}
I realize this is a rather old question, but since there wasn't a great answer here I thought I'd add one for others searching.
I recently came across this exact same issue and ended up figuring out a pretty good solution to it. I documented it all at https://stevenwoodson.com/blog/solving-animation-layout-flickering-caused-by-css-transitions/ if you're still in need of a fix!
The gist is that the transition needs to be added separately in a different class so you can remove it when you're not actively opening or closing the menu.

Css transform animation from right to left

I am working with a navigation bar that has slides a menu from right to left.
With my code, when the user picture is being clicked, it will show the menu.
So when it is loaded, menu is hidden and when it is clicked will be showed. I used to add class hidden and show to toggle to menu.
$(document).ready(function(){
$(".img-profile").click(function(){
$(".menu-wrapper").addClass("show");
});
$(".menu-bg").click(function(){
$(".menu-wrapper").removeClass("show");
});
});
CSS
.show{
display: inline-block !important;
}
.hidden{
display: none;
}
The problem is it's not animating even if I added the transition: all 0.2s linear 0s and the transform from 250px to 0
.menu-wrapper > .login-menu{
background-color: #fff;
height: 100%;
overflow-y: auto;
position: fixed;
right: 0;
width: 250px;
z-index: 5;
padding: 30px 20px;
text-align: center;
transition: all 0.2s linear 0s;
transform: translateX(0px);
}
.menu-wrapper .show > .login-menu{
transform: translateX(250px);
}
Also, I want to animate it on menu-close from right to left.
My full code is at JSFIDDLE
Changing the display CSS attribute does not trigger animations. Use the visibility attribute instead. This one triggers animations.
If you have good reason to use display (which is completely possible), you'll need to set the display attribute first to show the element, but keep the visibility on hidden. Set the visibility: visible attribute right after and the animation will be triggered.
Edit: I had a look at your fiddle. Don't use the .hidden class, because bootstrap sets display:none on .hidden elements. Just use the .show class alone, putting visibility:visible in the show class, and setting visibility:hidden on the .menu-wrapper element. Remove all the display:none lines in your CSS and you'll be fine.
Try to do it with this trick.
<header class="header">
<div class="container">
<a class="logo" href="/"></a>
<div class="login">
<div class="img-profile" style="background-image: url('http://graph.facebook.com/4/picture?width=100&height=100')"></div>
<div class="login-menu">
<div class="img-profile" style="background-image: url('http://graph.facebook.com/4/picture?width=100&height=100')"></div>
<p>Mark Zuckerberg</p>
<button type="button" class="btn btn-danger btn-block">Logout</button>
</div>
<div class="menu-bg"></div>
</div>
</div>
.header{
width: 100%;
height: 50px;
background: #fff;
border-bottom: 2px solid #ececec;
}
.header > .container{
height: 100%;
position: relative;
}
.logo {
background: url("http://d12xrwn9fycdsl.cloudfront.net/static/images/sv_logo.png") no-repeat scroll center center / contain ;
display: inline-block;
width: 23rem;
height: 100%;
}
.select-lang {
display: inline-block;
position: absolute;
top: 15px;
}
.login{
position: absolute;
right: 0;
top: 0;
}
.img-profile{
background: no-repeat scroll center center / contain;
position: relative;
top: 3px;
border-radius: 40px;
width: 40px;
height: 40px;
display: block;
margin: auto;
}
.login > .menu-wrapper{
display: none;
position: fixed;
left: 0;
top: 0;
bottom: 0;
z-index: 5;
height: 100%;
width: 100%;
}
.login-menu{
background-color: #fff;
height: 100%;
overflow-y: auto;
position: fixed;
top: 40px;
right: -250px;
width: 250px;
z-index: 5;
padding: 30px 20px;
text-align: center;
transition: all 0.2s linear 0s;
}
.show{
right: 0;
}
.hidden{
right: -250px;
}
.login-menu > .img-profile {
border-radius: 70px;
height: 70px;
width: 70px;
}
.login-menu > p {
font-weight: bold;
margin: 10px 0 20px;
}
.menu-wrapper > .menu-bg{
background-color: rgba(0, 0, 0, 0.6);
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
}
$(document).ready(function(){
$(".img-profile").click(function(){
$(".login-menu").addClass("show");
});
$(".img-profile").click(function(){
$("body").removeClass("show");
});
});
Take a look here https://jsfiddle.net/SkiWether/KFmLv/
this is working for me
$(".myButton").click(function () {
// Set the effect type
var effect = 'slide';
// Set the options for the effect type chosen
var options = { direction: $('.mySelect').val() };
// Set the duration (default: 400 milliseconds)
var duration = 500;
$('#myDiv').toggle(effect, options, duration);
});

How to create change image option on mousehover like in gmail account?

I am trying to create change image functionality like we can do in GMail account for changing our image.
On mousehover event it shows change image option.
Maybe it is some kind of new concept that I don't know. I am not very good in CSS and JavaScript but I guess that it is a div with changed z-index showing change image option.
Could you please explain how to achieve that kind of effect?
Here is a version using the css pseudo-element :after:
demo
HTML:
<a href="#" class="image">
<img src="http://www.gravatar.com/avatar/c0b4455b645967c1431d73beea9d9c54?s=128&d=identicon&r=PG">
</a>
CSS:
.image img{
width: 100px;
text-decoration: none;
}
.image:after{
content: "Change Image";
display: block;
position: relative;
top: -25px;
width: 100px;
background-color: rgba(77, 144, 254, 0.7);
color: white;
font-weight: bold;
text-decoration: none;
opacity: 0;
transition: opacity 300ms;
}
.image:hover:after{
opacity: 1;
}
If you want a pure CSS solution than you can try it like this
Demo
div.wrap {
position: relative;
display: inline-block;
}
div.wrap img {
position: absolute;
}
div.wrap img:nth-of-type(1) {
opacity: 0;
transition: opacity 3s;
}
div.wrap:hover img:nth-of-type(1) {
z-index: 2;
opacity: 1;
}
div.wrap img:nth-of-type(2) {
opacity: 1;
transition: opacity 3s;
}
div.wrap:hover img:nth-of-type(2) {
opacity: 0;
}
is this what you mean?
CSS
.image {
width: 100px;
height: auto;
}
.popup {
top: -25px;
left: 25px;
width: 150px;
height: 75px;
position: relative;
display: none;
background-color: grey;
border-style: solid;
border-width: 1px;
border-radius: 3px;
}
.image:hover + .popup {
display: block;
}
.popup:hover {
    display: block;
}
HTML
<img class="image" src="http://img83.imageshack.us/img83/1905/dsc005142kc.jpg" />
<div class="popup">Change Image</div>
On jsfiddle
I'm not sure I understand what you want but I'd say something like that :
HTML :
<img src="yourimage" />
change
CSS :
a.appearOnHover {
display: none;
}
a.appearOnHover {
display: block;
background-color: #777777;
}

Categories

Resources