Think accessibility first (and mobile second)
Designing and creating web components first and thinking about accessibility afterwards is a common mistake. Adding accessibility afterwards makes it unnecessary difficult. This counts for the very first approach to design (scope and structure), for the visual details (color, clarity and contrast), content (labeling, readability) but also for the implementation (flow and semantics). The latter is the main problem in your example.
The idea is to start making the list accessible for keyboard and screen reader users. After that you can add the visuals needed. This is how your code could change, below is an explanation:
<div class="label" id="fav-animal-label">Favorite animal</div>
<div class="dropdown">
<div class="btn" aria-hidden="true" tabindex="0" data-toggle="dropdown" id="dropdown-toggle-btn-1" data-value="">
Choose an animal
</div>
<fieldset>
<legend id="fav-animal-legend" class="sr-only" aria-describedby="fav-animal-label">Choose your favorite animal</legend>
<div class="dropdown-content">
<input name="fav-animal" type="radio" id="option-1" value="cat" class="sr-only"><label class="dropdown-item" for="option-1">Cat</label>
<input name="fav-animal" type="radio" id="option-2" value="dog" class="sr-only"><label class="dropdown-item" for="option-2">Dog</label>
<input name="fav-animal" type="radio" id="option-3" value="elephant" class="sr-only"><label class="dropdown-item" for="option-3">Elephant</label>
</div>
</fieldset>
</div>
Please note that I added the code as an example, it doesn't have to be the definite code.
First I added a label above the dropdown. It is not a semantical label because it is not directly linked to an input field.
A dropdown is a control that helps keeping the visual space clean, obviously screen reader users don't benefit from this and you don't have to mimic this behavior for them. That's why I hide the button for screen reader users since all they need is the fieldset which is supported well by most screen readers. No need to make that a semantical <button>
too, just add the visuals to make it appeal like one. With tabindex="0"
it is still accessible with a keyboard. The options are radio buttons that are put together in a fieldset so that users never loose context. This is assured with a clear text for the legend element. This legend can be visually hidden just like the radio buttons.
To show that and how it works I have created this fiddle with minimal style and javascript.
Note: This is just example code to show how to think about accessibility in the context of the given code example. As said in the comments this code has still some issues and should not be used as is. Please feel free to improve the fiddle and add it in the comments.
When you want to add a search to the dropdown, things get more complicated, but the approach should be the same. And don't forget to test it. Try using my fiddle with NVDA or VoiceOver for example.
<option>
s to a<select>
(and edit them) so that is no issue with regards to dynamic option creation. Unfortunately the above example is not accessible at all, using<a>
for options is one big issue, not using an<ul>
for the options (so it announces the number of options) is another. Plus you have to implement all the keyboard functionality yourself which is hard work.combobox
(autocomplete) or aselect
, they are both very different in how you implement them. this article is a good starting point, you will still need to make adjustments such as using an<ul>
but it shows the correctaria
attributes and explains some considerations such as keyboard controls and expected behaviour. Could you explain further / make it more clear why you can't just use a<select>
as you are heading for a lot of work creating your own.