Search code examples
javascripthtmlaccessibilitywai-aria

How do I make div or <li> accessible through Up/down arrow keys


So I have a few divs one below the other. I want them to be "web accessible" via arrows keys, i.e, if I press the down key next div should be highlighted and if I press the up key, the previous one should be highlighted.

If I had a button I could have used the tabIndex property to achieve it.

The thing is divs are not actionable items. So it could be confusing for the users if I make them somehow accessible through tabs. Hence, I want it only through arrow keys of the keyboard.

I'm even willing to convert it into <ul><li><li></ul> if the desired behavior could be achieved.

<div>Div 1</div>
<div>Div 2</div>
<div>Div 3</div>
<div>Div 4</div>

This is what I tried with <li>s. But If I click on the first li I cant go and highlight the next one by pressing the down arrow.

<ul role="menu" aria-label="menu">
            <li role="menuitem" tabindex="0">list 1</li>
            <li role="menuitem" tabindex="0">list 2</li>
            <li role="menuitem" tabindex="0">list 3</li>
            <li role="menuitem" tabindex="0">list 4</li>
            <li role="menuitem" tabindex="0">list 5</li>
    </ul>


Solution

  • Hi you should use jquery for what you want. Your last source will be this:

    $(function(){
            document.onkeydown = function(e) {
                var selected = $('.mnu-item:focus').index();
    
                var next = selected + 1;
                var pre = selected - 1;
    
                if(pre < 0)
                    pre = 0;
                if(next > $('.mnu-item').length)
                    next = $('.mnu-item').length;
    
                if(e.which == 38) { // up
                    $('.mnu-item').eq(pre).focus();
                }
                if(e.which == 40) { // down
                    $('.mnu-item').eq(next).focus();
                }
                e.preventDefault(); // prevent the default action (scroll / move caret)
            };
        })
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <ul role="menu" aria-label="menu">
        <li role="menuitem" tabindex="0" class="mnu-item">list 1</li>
        <li role="menuitem" tabindex="0" class="mnu-item">list 2</li>
        <li role="menuitem" tabindex="0" class="mnu-item">list 3</li>
        <li role="menuitem" tabindex="0" class="mnu-item">list 4</li>
        <li role="menuitem" tabindex="0" class="mnu-item">list 5</li>
    </ul>

    I hope this will be useful.