in Firefox, click on absolute element inside focusable element does not focus focusable element unless it has a CSS position
Asked Answered
C

4

11

Context: an absolute element inside a focusable element.

In Firefox 36, if the focusable element does not have a CSS position (relative, fixed, or absolute), a click on the inside element will not set focus to the focusable element...

Any idea whether that is a known bug?

Not reproductible on IE11 and Chrome.

For better understanding of the issue, here's an example:

Codepen

/* this is just so that the squares are similarly displayed */
section {
  position: relative;
  display: inline-block;
  margin-right: 75px;  
}

div {
  background-color: red;
  width: 100px;
  height: 100px;
  color: white;
  padding: 5px;
}

div:focus {
  background-color: green;
}

div > span {
  position: absolute;
  display: inline-block;
  top: 50px;
  left: 50px;
  background-color: blue;
  width: 100px;
  height: 100px;
  padding: 5px;
}
Context: an absolute element inside a focusable element.<br>
In  Firefox 36, if the focusable element does not have a "position: relative", a click on the inside element will not set the focus on the focusable element...<br>
(red block turns green when focused)
<br><br>
Edit: none works in IE
<br><br>

<section>
  <div style="position: relative;" tabindex="-1">
    With position: relative
    <span>
      click here
    </span>
  </div>
</section>

<section>
  <div tabindex="-1">
    With no position
    <span>
      click here
    </span>
  </div>
</section>
Crosse answered 27/2, 2015 at 19:27 Comment(5)
Thought I might as well post a bug report on bugzilla. Here it is: bugzilla.mozilla.org/show_bug.cgi?id=1138028Crosse
can u explain why you don't want to or can't use "position: relative;"?Gravamen
Honestly, I don't remember. I think I ended up doing things differently. But that's not the point. The point is that that behavior doesn't make sense.Crosse
i actually think that it does make sense. keeping this comment in mind: bugzilla.mozilla.org/show_bug.cgi?id=1138028#c1Gravamen
This looks fixed in FF 66Surplusage
R
1

In this case, the click event is fired and event propagation will takes place. So click on the inside element will propagate to the parent element and the parent will get focus and style will be applied. For more details go through event propagation event propagation

Romanism answered 6/7, 2016 at 8:29 Comment(0)
C
0

I had same issue and resolved using mousedown event instead.

Cambrian answered 12/3, 2018 at 22:16 Comment(0)
A
-1

It's reproducable in all browsers in the following case:

<!doctype html>
<html lang="en">
<head>
    <title>Focus</title>
    <style>
    button { display: inline-block; width: 30px; height: 30px; background-color: red; }
    button:focus { background-color:green; }
    span { position: absolute; display:inline-block; width:100px }
    </style>
</head>
<body>
      <button>
        <span tabindex="1">
          click here
    </span>
      </button>
</body>
</html>

And tabindex is not guaranteed to add focus due to the following:

an element that is only focusable because of its tabindex attribute will fire a click event in response to a non-mouse activation

Accessibility guidelines describe the workaround as such:

Techniques for providing access to scripts include the following:

Allow the user to configure the user agent so that mouseover/mouseout event handlers are activated by (and activate) focus/blur events. Similarly, allow the user to use a key command, such as enter and Shift-Enter to fire onclick and ondblclick events.

Implement "Document Object Model (DOM) Level 2 Events Specification" [DOM2EVENTS] events with a single activation event and provide a method for firing that event with each supported input device or input API. These should be the same as the click events and mappings provided above (but note that a user agent which is also an editor may wish to use single click events for moving a system caret, and want to provide a different behavior to activate using the mouse).

For example, Amaya [AMAYA] uses a doAction command for activating links and form elements, which can be activated either by the mouse (and it is possible to set it for single-click or double-click) or by the keyboard (it is possible to set it for any key using Amaya's keyboard configuration)

For authors: Document the effects of known important scripts to give users an idea in advance of what they do. Do so by using the relevant elements or attributes of the (markup language) specification, or if there aren't any, make available a description of the script behavior.

Also, this behavior is unspecified:

The :focus pseudo-class applies while an element has the focus (accepts keyboard events or other forms of text input).

An element may match several pseudo-classes at the same time.

CSS does not define which elements may be in the above states, or how the states are entered and left.

Use a focusin/focusout polyfill to normalize the cross-browser behavior:

function focusPolyfill()
  {
  'use strict';
  
  var w = window,
  d = w.document;

  function addPolyfill(e)
    {
    var 
		type = e.type === 'focus' ? 'focusin' : 'focusout',
		event = new CustomEvent(type, { bubbles:true, cancelable:false });
    event.c1Generated = true;
    e.target.dispatchEvent( event );
    }

  function removePolyfill(e)
    {
    if(!e.c1Generated)
      { 
      // focus after focusin, so chrome will the first time trigger tow times focusin
      d.removeEventListener('focus' ,addPolyfill ,true);
      d.removeEventListener('blur' ,addPolyfill ,true);
      d.removeEventListener('focusin' ,removePolyfill ,true);
      d.removeEventListener('focusout' ,removePolyfill ,true);
      }
	}
	
   function removeHandler()
    {
    d.removeEventListener('focusin' ,removePolyfill ,true);
    d.removeEventListener('focusout' ,removePolyfill ,true);
    }
    
  
  if( w.onfocusin === undefined )
    {
    d.addEventListener('focus' ,addPolyfill ,true);
    d.addEventListener('blur' ,addPolyfill ,true);
    d.addEventListener('focusin' ,removePolyfill ,true);
    d.addEventListener('focusout' ,removePolyfill ,true);
    }
  
  w.setTimeout(removeHandler);
  }
   

The following is the typical sequence of events when a focus is shifted between elements, including the deprecated DOMFocusIn and DOMFocusOut events. The order shown assumes that no element is initially focused.

User shifts focus
1.  focusin Sent before first target element receives focus
2.  focus   Sent after first target element receives focus
3.  DOMFocusIn  If supported
User shifts focus
4.  focusout    Sent before first target element loses focus
5.  focusin Sent before second target element receives focus
6.  blur    Sent after first target element loses focus
7.  DOMFocusOut If supported
8.  focus   Sent after second target element receives focus
9.  DOMFocusIn  If supported

References

Aviva answered 27/2, 2015 at 19:28 Comment(1)
Your focusable element has a position. The issue is when it does not have a position (and I don't want a position). I tried simply adding the label, and it still doesn't work.Crosse
G
-1

tried with <p> tag and its working.

div > p{
  display: inline-block;
  top: 50px;
  left: 50px;
  background-color: blue;
  width: 100px;
  height: 100px;
  padding: 5px;
  margin-left:40px;
}
<section>
  <div tabindex="-1">
    With no position
    <p>
      click here
    </p>
  </div>
</section>

link http://codepen.io/anon/pen/MYLeLp

Guitarfish answered 24/3, 2015 at 8:36 Comment(1)
Of course it is, your p is not absolute. The point is that the element must have an absolute position.Crosse

© 2022 - 2024 — McMap. All rights reserved.