Can't click the button because of the overlay? - html

This is the HTML
<li id="nav1" class="navs"><a unselectable="on" draggable="false" class="Navigation" href="http://youtube.com">YouTube</a></li>
This is the CSS
.navs:after {
content: "";
position: absolute;
top: 0; left: 0; right: 0; bottom: 0;
background: #0d0d0d;
opacity: 0.5;
transform: scaleY(0);
transform-origin: 0 100%;
transition: all .2s ease-out;
}
.navs:hover:after{
transform: scaleY(1);
}
.navs:active:after{
background: #FFFFFF;
}
I think the reason why i can't click the button is because when i click the button, the overlay forms. I do not want to remove the overlay though. Is there any way to click through the overlay?

Option one
You can give your element a higher z-index. This will move your button above the overlay, so you will be able to click it
Option two
You can disable all mouse events on your overlay using pointer-events:none; so the click event will 'fall through' it and the button will register it
Edit: Use pointer-events when you can, let z-index be your backup plan. If you fall back to it, I suggest that you don't use it inline, but write a specific selector for it in your CSS.

use span instead of before and after,
something like
<a href="my link"><img class="" src="my_image" alt="">
<span class="rig-overlay"></span>
<span class="rig-text">
<span>name</span>
<span>function</span>
</span>
</a>
the span will not cover the clickable region

It could be many different things...
Definitely try to check if you've used any z-index properties for other elements that are the parents of the element.
I encountered the exact same problem and I fixed it by troubleshooting:
what I did was pull up a javascript file and console log the target className of where I was clicking (can be done by:
window.addEventListener('click' , (e) => {
const target = e.target.className;
console.log(target);
})
)
Once I did that, click on the button that doesn't seem to be working. Make sure to add a class to your button before this and check if the class is displayed properly. Sometimes, in my case, I had to move the console out of the window.
From this, I found my SVG Animation was actually taking up invisible space that covered the button. All I had to do to fix this problem was give the SVG a z-index of -1.
Hope this helped! I know I took a long time to find a solution so I hope my solution can help others too.
Note: Also check your pointer events (make sure it isn't set to none) for the button and other elements

Related

Accessible nested button inside button?

I'm trying to build a button that looks like Zoom's button.
Here there is a button to pick a device inside the camera button. I'd like to create something similar, where you have a button and another button that expands a picker inside it.
How can you create this in an accessible way?
If I nest buttons in React, it throws errors that you can't nest a button inside another. Zoom's equivalent would be:
<button>
Stop Video
<button>Pick Device</button>
</button>
which doesn't work. How would you create an interface like this so it stays accessible (and valid)?
Preword
Don't nest interactive elements
There is a reason that it isn't valid HTML to nest buttons or hyperlinks, it causes nightmares for knowing which action should be performed on a click (for a start) and for assistive technology this makes things even worse as it can confuse the accessibility tree as to what it should present to screen readers.
The answer
If you look carefully you will see they aren't actually nested, the "picker" button is placed on top of the other button.
Now there is an issue here in terms of accessibility, click / tap target size.
A button / interactive element should be no less than 44px by 44px
So the Zoom example you gave fails this criteria. Additionally the tooltip that says "stop video" looks wrong if you have the picker selected as that should be the tooltip for the button that is currently hovered.
So how could we create an accessible version of what you want?
I would recommend having a large button with a 44 by 44 button placed on top to the right.
This can easily be done with absolute positioning.
To ensure that it is evident visually that the buttons are related I inset the second button by 2px.
The below is not a complete example but I have given you a start.
I added aria-expanded to the button that opens the sub menu, this gets toggled when the menu is opened.
I also added the aria-haspopup attribute to let users know that this button opens a sub menu.
I also added aria-controls to let assistive technology know the relationship between the button and the menu it opens.
Finally you will see I added a <span> with some visually hidden text inside so that screen reader users know that the picker button opens the video controls.
The example maintains logical tab order and is pretty accessible, but there are still things such as being able navigate the menu buttons with the arrow keys, closing the menu with Esc key and returning focus to the button that opened the menu etc. that you need to implement yourself. Oh and styling obviously!
var mainButton = document.querySelector('.main-button');
var menuToggle = document.querySelector('.sub-button');
var menu = document.getElementById('controls');
mainButton.addEventListener('click', function(){
alert("clicked the main button");
});
menuToggle.addEventListener('click', function(){
if(menu.classList.contains('open')){
menu.classList.remove('open');
menuToggle.setAttribute('aria-expanded', false);
}else{
menu.classList.add('open');
menuToggle.setAttribute('aria-expanded', true);
}
});
.container{
position: relative;
width: 144px;
height: 48px;
}
.main-button{
width: 144px;
height: 48px;
padding-right: 50px;
}
.sub-button{
position: absolute;
width: 44px;
height: 44px;
top:2px;
right:2px;
}
.visually-hidden {
border: 0;
padding: 0;
margin: 0;
position: absolute !important;
height: 1px;
width: 1px;
overflow: hidden;
clip: rect(1px 1px 1px 1px); /* IE6, IE7 - a 0 height clip, off to the bottom right of the visible 1px box */
clip: rect(1px, 1px, 1px, 1px); /*maybe deprecated but we need to support legacy browsers */
clip-path: inset(50%); /*modern browsers, clip-path works inwards from each corner*/
white-space: nowrap; /* added line to stop words getting smushed together (as they go onto seperate lines and some screen readers do not understand line feeds as a space */
}
#controls{
display: none;
}
#controls.open{
display: block;
}
<div class="container">
<button class="main-button">Stop Video</button>
<button class="sub-button" aria-expanded="false" aria-haspopup="true" aria-controls="controls">⌄ <span class="visually-hidden">Pick Device</span></button>
<ul id="controls"
role="menu"
aria-labelledby="sub-button">
<li><button>Option 1</button></li>
<li><button>Option 2</button></li>
</ul>
</div>
The react gives a warning if you try to do so and the reason is simple. It has everything to do with semantic HTML and you should never put a button inside a button.
Alternatively to get the desired behaviour you can do something like this:
<div style={{ position: "relative", width: "200px", height: "40px" }}>
<button
onClick={() => console.log("Stop Video")}
style={{ width: "100%", height: "100%" }}
>
Stop Video
</button>
<button
onClick={() => console.log("Pick Device")}
style={{ position: "absolute", right: 0, top: 0 }}
>
Pick Device
</button>
</div>
This will do the same thing you need. Here is the codesandbox example for the same implementing the exact same thing.

CSS transform moves click handler?

I tend to use the following SCSS #mixin for an animation effect to let users know what is interactive on my projects.
#mixin clickAnimation($opacity: 0.5, $distance: -1px, $time: 75ms) {
opacity: 1;
transition: $time ease;
cursor: pointer;
&:hover {
transform: translateY($distance);
opacity: $opacity;
}
&:active {
transform: translateY(2px);
}
}
I'll tend to use it across the site like this:
a:not(.disabled) {
#include clickAnimation();
}
Recently I've noticed a quirky issue with this.
If the user hovers the <a> element on the bottom pixel of the <a>, the <a> will transform up to -1px. When the user clicks the <a>, the :active css state will perform (in this case, translating down to 2px), but the click action will not register. So no click handlers will fire, and no links will cause redirects.
Has anyone had this issue before and know what I could do to fix it?
As requested, here is a fiddle which demonstrates the issue: https://jsfiddle.net/bf9yk0tn/
Apparently, the DOM looses track of the element since its moving from its original position and there's nothing at the time click event occurs (somehow it manages the hover though).
You can go for a workaround like this to fill the void but Im not sure if its the best solution.
a:hover::after {
content: '';
position: absolute;
bottom: -1px;
left: 0;
height: 1px;
width: 100%;
}
Here's the update jsfiddle

HTML - Removing an element's "presence" on the page but keeping its visibility?

I have an element that overlays another element. The main element is a canvas where elements constantly have mouse interactions and the element directly overtop of it just shows elements that act as little markers. Same position, same size and it's important the overlay is overtop of the canvas.
What would it mean to make this "overlay" only exist visibility wise? As in having no possible user input because for its purposes it's not really there to be interacted with, just showing something.
Removing selection in CSS stops you from clicking on it but it's still overtop of the other element and doesn't allow mouse events. Hiding the element removes its presence but also makes it invisible.
In a normal desktop application you would just draw something to the screen and add functionality if you wanted but with HTML those two things are inherently the same.
I believe adding in the CSS the following code solves your issue:
.no-interaction {
z-index : -5
}
OR
.interaction {
z-index : 5
}
Turns out all it took was setting the pointer-events CSS attribute to none on whatever you want to have no presence.
I figured it would be a little more interesting than that, but there's a built in way in CSS.
<div id="canvas"></div>
<div id="overlay"></div>
#canvas, #overlay {
width: 500px;
height: 500px;
position: absolute;
}
#canvas {
background: blue;
}
#overlay {
background: red;
pointer-events: none; // right here
}
$('#canvas').click(function() {
alert('Clicked');
});
https://jsfiddle.net/ufsy33aw/

HTML: Changing default cursor does not work until pointer is moved

I have an overlayWaitDiv defined as follows with CSS:
#overlayWaitDiv {
cursor: wait;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 99;
}
The idea is that this overlay is put on top of the other elements, taking all window space, and shows a wait cursor.
I am showing/hiding this by using the following HTML:
To display the overlay:
<div id="overlayWaitDiv" style></div>
To hide the overlay:
<div id="overlayWaitDiv" style="display: none; "></div>
This is working fine: the cursor is changing from normal to wait, and back, according to the events happening in my page. The only problem that I have is that, in order for this cursor switch to happen, the user needs to move the pointer.
How can I make the browser immediately change the pointer, without the need for the user to move it?
put cursor:auto; then it will ok
Try setting the cursor value using java script as shown below.
$("#overlayWaitDiv").css("cursor","wait") ;
Why don't you try add a class to the body tag?
Like this:
.waiting {
cursor: wait;
}
When you need to show the waiting cursor use $("body").addClass("waiting") and $("body").removeClass("waiting") to hide.

Firefox does not show tooltips on disabled input fields

Firefox doesn't display tooltips on disabled fields.
The following displays tooltip in IE/Chrome/Safari except Firefox:
<input type="text" disabled="disabled" title="tooltip text."/>
Why doesn't Firefox display tooltip on disabled fields? Is there a work around this?
Seems to be a (very old, and very abandoned) bug. See Mozilla Bugs #274626 #436770
I guess this could also be explained as intended behaviour.
One horrible Workaround that comes to mind is to overlap the button with an invisible div with a title attribute using z-index; another to somehow re-activate the button 'onmouseover' but to cleverly intercept and trash any click event on that button.
I guess you are using some frameworks like bootstrap. If so, it add pointer-events: none to the 'disabled' element, so all the mouse events are ignored.
.btn[disabled] {
pointer-events: auto !important;
}
can fix the problem.
You can work around this with jQuery code like:
if ($.browser.mozilla) {
$(function() {
$('input[disabled][title]')
.removeAttr('disabled')
.addClass('disabled')
.click(function() {return false})
})
}
The z-indexing thing could be done like this:
.btnTip
{
position: absolute;
left: 0%;
right: 0%;
z-index: 100;
width: 50px;
/*background-color: red;*/
height: 17px;
}
(…)
<div style="background-color: gray; width: 400px;">
Set width of the tip-span to the same as the button width.
<div style="text-align: center;">
<span style="position:relative;">
<span class="btnTip" title="MyToolTip"> </span>
<input type="button" name="" disabled="disabled" value="Save" style="width: 50px;height:17px;" />
</span>
</div>
Left and right helps positioning the host on top of the disabled element.
The z-index defines what kind of layer you put an element in.
The higher number of a z-layer the more ‘on top’ it will be.
The z-index of the host and/or the disabled element should be set dynamically.
When the disabled element is disabled you want the tooltip host on top and vice versa - at least if you want to be able to click your element (button) when it is NOT disabled.
I have faced the similar issue and i could fix it using juery and small css class, you would require to create two new span elements and a css class which are as follows
Just add these in a general js and css file which is used in all over the application or web site
.DisabledButtonToolTipSpan
{
position :absolute;
z-index :1010101010;
display :block;
width :100%;
height :100%;
top :0;
}
To display tooltip for disabled button in firefox browser.
$(window).load(function() {
if ($.browser.mozilla) {
$("input").each(function() {
if ((this.type == "button" || this.type == "submit") && this.disabled) {
var wrapperSpan = $("<span>");
wrapperSpan.css({ position: "relative" });
$(this).wrap(wrapperSpan);
var span = $("<span>");
span.attr({
"title": this.title,
"class": "DisabledButtonToolTipSpan"
});
$(this).parent().append(span);
}
});
}
});
Hope this helps,
Preetham.
You could use javascript. Use the mouseover event.
(A lot of libraries like JQuery and Mootools have tooltip plugins available. Using these you can even style the tooltips).