Web Analytics Made Easy -
StatCounter Select element, keyboard navigation and accessibilty - CodingForum

Announcement

Collapse
No announcement yet.

Select element, keyboard navigation and accessibilty

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Select element, keyboard navigation and accessibilty

    I’m wondering two things:
    1. Is there an event or state that is triggered when a <select> element is not just focused but activated (i. e. its options opened)?
    2. Is there a standard specification which keys are usable to open the options?
    For anyone curious, here’s what I’m trying to do:
    I’m trying to get fancy and replace the default <select> element with a custom control for visual ehancement. I know we can style the select element itself pretty much how we want but the options are still hard/impossible to style.
    And don’t try to convince me otherwise, I’m determined to do this, and I promise, I’m gonna keep it usable for all people.

    So, my approach is to have a standard select element and use JS to construct a new UI control that mirrors the interaction on the select. I’m then going to hide the select by positioning it outside of the viewport. My special concern is keeping it usable for people that use the keyboard to navigate through the form and select. Here is the (simplified) JavaScript I have so far:
    Code:
    var obj = {
    	config: {
    		// storing keycodes for use with keyboard navigation
    		keys: {
    			tab:		9,
    			enter:	13,
    			esc:		27,
    			space:	32,
    			left:	 	37,
    			up:		 	38,
    			right:	39,
    			down:	 	40
    		}
    	},
    	init: function() {
    		mhd.enhanceSelects();
    	},
    	enhanceSelects: function() {
    		var selectFields = document.querySelectorAll('select'),
    				newSelectBox = document.createElement('div'),
    				newOptionsList = document.createElement('ul'),
    				newOption = document.createElement('li');
    		newSelectBox.classList.add('box');
    		newSelectBox.setAttribute('aria-hidden', 'true');
    		newOptionsList.classList.add('options');
    		newOptionsList.setAttribute('aria-hidden', 'true');
    		for(let i=0;i<selectFields.length;i++) {
    			let el = selectFields[i],
    					selectBox = newSelectBox.cloneNode(true),
    					optionsList = newOptionsList.cloneNode(true);
    			selectBox.textContent = el.value;
    			el.insertAdjacentElement('afterend',optionsList);
    			el.insertAdjacentElement('afterend',selectBox);
    			for(let i=0;i<el.options.length;i++) {
    				let option = newOption.cloneNode(true);
    				option.textContent = el.options[i].text;
    				optionsList.appendChild(option);
    			}
    			el.addEventListener('focus', function() {
    				selectBox.classList.add('focus');
    			});
    			el.addEventListener('blur', function() {
    				selectBox.classList.remove('focus');
    			});
    			el.addEventListener('keydown', function(e) {
    				var keys = obj.config.keys;
    				if(e.which === keys.space) {
    					console.log('space');
    				}
    				else {
    					console.log('other');
    				}
    			});
    			el.addEventListener('change', function() {
    				selectBox.textContent = el.value;
    			});
    		}
    	}
    }
    mhd.init();
    So, I’ve already constructed the custom control, the styling and stuff is all done with CSS. Eventually, users with a pointing device (mouse/pen/finger/whatever) will interact with the custom control for which I’ll employ the click event and then change the select value depending on the option list item clicked. Users using the keyboard will interact with the select element directly, and this will be reflected visually in the custom control.

    Now, the only things I’m wondering is whether the keyup event is the only way to check whether a select has been activated, and whether the keys used are common in all browsers or are there any gotchas?
    Stop solving problems you don’t yet have!

  • #2
    You could get inspiration from https://select2.org
    The computer is always right. The computer is always right. The computer is always right. Take it from someone who has programmed for over ten years: not once has the computational mechanism of the machine malfunctioned.
    André Behrens, NY Times Software Developer

    Comment


    • #3
      Honestly, this is why I use radio buttons + CSS for what you're describing. Just group and style the labels.

      Can end up a bit hefty if you have a lot of them since you need to mate the labels to their input, and have said input before the dialog they are paired to, though ::focus-within can get you around that now if you don't give a flying purple fish about IE any more. (and you could use scripting to polyfill that)

      Think about it, a select when doing single selections is just a FIELDSET of radio INPUT with fancy styling. When multi-select, they're a FIELDSET of normal checkbox INPUT! It even makes the ability to label the set make more sense, since then you can use LEGEND properly instead of LABEL. (with INPUT+LABEL as your OPTION)

      Using a mix of :focus and adjacent sibling selectors you should be able to pull it off with little to no scripting hooks or other trickery needed.
      I'll kill you and your dreams tonight, begin new life.
      Bleed your death upon me, let your bloodline feed my youth.
      https://cutcodedown.com

      Comment


      • #4
        Thanks for your input. It’s funny that you mention radio buttons, deathshadow, because I did just that in a prior approach, and it kind of works, although replicating the exact interaction pattern is tricky since radio buttons have no parent element that has to be focused before making a selection, and you can’t just tab over the radio buttons altogether, as you would tab over a select field, so that opens a whole nother can of worms regarding keyboard navigation.

        But the main reason for using a select element is that I want the native selection UI on mobile devices (i. e. small viewports), and I think that I’m pretty close with my approach already. It’s only this tiny part of actually activating the options that I’m wondering about.

        And Dormilich, thanks for that link. Unfortunately (or not) I’m bound to using vanilla JavaScript and can’t resort to jQuery for this project. And at the moment I’m a little too impatient to dig through the source code to find out how they are doing it. What I can tell already, however, is that activating the options with this jQuery plugin doesn’t work with the up/down arrow keys (at least in Firefox), unlike with native selects. So, apparently something is missing there.

        But is there some official specification on which keys can activate select options? I know of space, up and down. Can users specify this in their OS or is this fixed?
        Stop solving problems you don’t yet have!

        Comment


        • #5
          Originally posted by VIPStephan View Post
          tricky since radio buttons have no parent element that has to be focused before making a selection
          :focus-within

          https://developer.mozilla.org/en-US/.../:focus-within

          It's a game changer. Though you still need a hair of scripting to blur the element when a selection is made, it still takes most of the grunt-work out of your hands. You just put a DIV around the "options" and hide it. When the DIV:focus-within triggers, show the contents. As you tab through, the outer DIV (or fieldset) will pick up that you've focused a child of it!

          There's a LOT of really cool new CSS stuff we're all coming to grips with.
          Last edited by deathshadow; May 9, 2020, 08:18 AM.
          I'll kill you and your dreams tonight, begin new life.
          Bleed your death upon me, let your bloodline feed my youth.
          https://cutcodedown.com

          Comment


          • #6
            Oh, and side note? I hate selects. They're usability crap.
            I'll kill you and your dreams tonight, begin new life.
            Bleed your death upon me, let your bloodline feed my youth.
            https://cutcodedown.com

            Comment


            • #7
              Turns out that options can’t be hidden (in some browsers) at all costs, i. e. even if you move the select out of view, once you activate it (e. g. via keyboard), the options will appear inside the viewport. Select really is a strange element.
              Stop solving problems you don’t yet have!

              Comment


              • #8
                Originally posted by VIPStephan View Post
                if you move the select out of view, once you activate it (e. g. via keyboard), the options will appear inside the viewport.
                One of the myriad of reasons I hate SELECT both as a programmer and as a user... and why I favor radio button or checkbox fieldsets over them even without styling them to act like selects.

                Select is hard to style, hard for users to use the moment you have more than a half dozen choices, behaves inconsistently across browsers, are generally NOT all that usable/useful in non-visual UA's, etc, etc, etc.

                ... and I swear the next website I come across where some asshat is using them + javascript to do a group of anchor's job, or three separate ones as date pickers, I'm tracking down the creator and shoving my size nine where it don't shine.
                I'll kill you and your dreams tonight, begin new life.
                Bleed your death upon me, let your bloodline feed my youth.
                https://cutcodedown.com

                Comment

                Working...
                X