最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Why does my Shadow DOM button (tabindex="0") get focus after the regular button (tabindex=&qu

programmeradmin1浏览0评论

I'm trying to ensure that a button inside a Shadow DOM gets tab focus before a regular button in the main DOM. one button have tabindex="0", and the other one is 10 but the regular button outside the shadow is always focused first.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        button{
            padding: 1%;
            border-radius: 10px;
            width: 100px;
            height: 50px;   
            
        }
        button:focus {
        background-color: red;
        }

    </style>
</head>
<body>
      
        <div id="shdow">
            
        </div>

        <button  tabindex="10">focus me </button>


        <script>
            // set shadow root with button taindex 0
            document.querySelector('#shdow').attachShadow({mode: 'open'}).innerHTML = `
                <style>
        button{
            padding: 1%;
            border-radius: 10px;
            width: 100px;
            height: 50px;   
            
        }
        button:focus {
        background-color: green;
        }

    </style>
            <button tabindex="0">focus me </button>`;

        </script>

</body>
</html>

I'm trying to ensure that a button inside a Shadow DOM gets tab focus before a regular button in the main DOM. one button have tabindex="0", and the other one is 10 but the regular button outside the shadow is always focused first.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        button{
            padding: 1%;
            border-radius: 10px;
            width: 100px;
            height: 50px;   
            
        }
        button:focus {
        background-color: red;
        }

    </style>
</head>
<body>
      
        <div id="shdow">
            
        </div>

        <button  tabindex="10">focus me </button>


        <script>
            // set shadow root with button taindex 0
            document.querySelector('#shdow').attachShadow({mode: 'open'}).innerHTML = `
                <style>
        button{
            padding: 1%;
            border-radius: 10px;
            width: 100px;
            height: 50px;   
            
        }
        button:focus {
        background-color: green;
        }

    </style>
            <button tabindex="0">focus me </button>`;

        </script>

</body>
</html>

Share Improve this question asked Jan 19 at 12:56 ShobiDobiShobiDobi 2462 silver badges15 bronze badges 3
  • document.querySelector("button[tabindex='0']").focus() the <button> is at the shadowRoot, correct? – zer00ne Commented Jan 20 at 6:39
  • no javascript that the point here – ShobiDobi Commented Jan 20 at 8:26
  • There's a JavaScript tag you should probably remove. – zer00ne Commented Jan 20 at 8:37
Add a comment  | 

3 Answers 3

Reset to default 1

That's something known. You shouldn't use tabindex with values other than 0 and -1.

When there are naturally focusable elements without tabindex and elements having tabindex=0 mixed with elements having tabindex>0, then all the former ones get the focus after all the later ones, or the converse. The tab order quickly becomes uncontrollable.

If you use somewhere tabindex>0, then all focusable elements must have tabindex>0 to make sure it remains consistent. Hence it's very easy to completely break the tab order and accessibility. And of course it's one more step harder to keep consistency at all times if elements are added or removed, shown and hidden dynamically. That's a nightmare.

See doc about tabindex attribute on MDN for more info: in particular, well read this note: tabindex="0" means that the element should be focusable in sequential keyboard navigation, after any positive tabindex values. but in fact, it can be the opposite, have all tabindex>0 first and then all others.

Shadow DOM Button Integration: The button inside the Shadow DOM is included in a focusSequence array, along with the main document button.

Custom Tabbing Logic:

The keydown event listens for the Tab key. The currentIndex determines which element in focusSequence gets focus next. The default browser tabbing is disabled (event.preventDefault()). Focus Cycling: The focusSequence ensures that the Shadow DOM button is treated as part of the global focus order, giving it priority when cycling through focusable elements.

Testing Steps: Load the page. Press the Tab key. The focus will first land on the Shadow DOM button, then the main DOM button. This approach directly manages focus order and should resolve any issues with Shadow DOM focus priority.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Shadow DOM Focus</title>
    <style>
        button {
            padding: 1%;
            border-radius: 10px;
            width: 100px;
            height: 50px;
        }
        button:focus {
            background-color: red;
        }
    </style>
</head>
<body>
    <div id="shadow-container"></div>
    <button tabindex="10">Main DOM Button</button>

    <script>
        // Attach Shadow DOM and add the shadow button
        const shadowContainer = document.querySelector('#shadow-container');
        const shadowRoot = shadowContainer.attachShadow({ mode: 'open' });
        shadowRoot.innerHTML = `
            <style>
                button {
                    padding: 1%;
                    border-radius: 10px;
                    width: 100px;
                    height: 50px;
                }
                button:focus {
                    background-color: green;
                }
            </style>
            <button tabindex="0">Shadow DOM Button</button>
        `;

        const shadowButton = shadowRoot.querySelector('button');
        const mainButton = document.querySelector('button[tabindex="10"]');

        // Custom focus management
        let focusSequence = [shadowButton, mainButton];
        let currentIndex = 0;

        document.addEventListener('keydown', (event) => {
            if (event.key === 'Tab') {
                // Prevent default tabbing behavior
                event.preventDefault();

                // Determine the next element to focus
                currentIndex = (currentIndex + 1) % focusSequence.length;
                focusSequence[currentIndex].focus();
            }
        });
    </script>
</body>
</html>

The solution i found is to set the tab index onto the shadow root element then the next focus will be what comes inside

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论