-
Notifications
You must be signed in to change notification settings - Fork 811
Closed
Description
Summary:
Within a modal, it is not possible to tab through elements inside an element with display: contents
Steps to reproduce:
- Create a modal with an element that has display: contents
- Put focus-able elements inside that element (eg inputs)
- Try to tab through the inputs
- No focus change on tab
Expected behavior:
Focus switches to the next input element on tab
Link to example of issue:
See https://codesandbox.io/s/flamboyant-sunset-t3pbm
Open the dialog, then try to tab through the inputs - it won't work. Then change display: "contents" to display: "block" - tabbing no works.
Additional notes:
This is caused by the fact that elements with display: "contents" have a size of 0x0 and tabbable assumes the content is invisible:
react-modal/src/helpers/tabbable.js
Lines 15 to 34 in fb6bab5
| function hidesContents(element) { | |
| const zeroSize = element.offsetWidth <= 0 && element.offsetHeight <= 0; | |
| // If the node is empty, this is good enough | |
| if (zeroSize && !element.innerHTML) return true; | |
| try { | |
| // Otherwise we need to check some styles | |
| const style = window.getComputedStyle(element); | |
| return zeroSize | |
| ? style.getPropertyValue("overflow") !== "visible" || | |
| // if 'overflow: visible' set, check if there is actually any overflow | |
| (element.scrollWidth <= 0 && element.scrollHeight <= 0) | |
| : style.getPropertyValue("display") == "none"; | |
| } catch (exception) { | |
| // eslint-disable-next-line no-console | |
| console.warn("Failed to inspect element style"); | |
| return false; | |
| } | |
| } |
It can be fixed by checking for display: contents, like so:
diff --git a/node_modules/react-modal/lib/helpers/tabbable.js b/node_modules/react-modal/lib/helpers/tabbable.js
index c72bf54..0e8a07a 100644
--- a/node_modules/react-modal/lib/helpers/tabbable.js
+++ b/node_modules/react-modal/lib/helpers/tabbable.js
@@ -27,6 +27,10 @@ function hidesContents(element) {
try {
// Otherwise we need to check some styles
var style = window.getComputedStyle(element);
+ if(style.getPropertyValue("display") === "contents"){
+ // display === "contents" does not hide its contents even if its size is (always) 0x0
+ return false;
+ }
return zeroSize ? style.getPropertyValue("overflow") !== "visible" ||
// if 'overflow: visible' set, check if there is actually any overflow
element.scrollWidth <= 0 && element.scrollHeight <= 0 : style.getPropertyValue("display") == "none";
maxpatiiuk
Metadata
Metadata
Assignees
Labels
No labels