In other words, instead of having to focus only on the logic of your application, you now also have to focus on all the interactions with your custom controls. This extra programming burden is why rolling your own was not recommended at the outset. This is a simple example, too. The more controls you add, the more complex the process becomes and the more potential side-effects you have to consider and account for.
If you still want to pursue your own controls, though, or just want to learn more, the Illinois Center for Information Technology and Web Accessibility maintains a comprehensive set of examples, with working code, that are worth the time to review. You’ll discover much more from their many examples than I could reproduce here. The ARIA authoring practices guide also walks through the process of creating an accessible control.
A quick note on tabindex is also in order, as you no
doubt noticed it on the preceding examples. Although this is actually an HTML
attribute, it goes hand-in-hand with ARIA and custom controls because it allows
you to specify additional elements that can receive keyboard focus, as well the
order in which all elements are traversed (i.e., it improves keyboard
accessibility). It is critical that you add the attribute to your custom
controls, otherwise readers won’t be able to navigate to them.
Here’s another look at our earlier image button again:
<img src="controls/start.png"
id="audio-start"
alt="Start"
role="button"
tabindex="0"/>
By adding the attribute with the value 0, we’ve
enabled direct keyboard access to this img element.
The 0 value indicates that we aren’t giving this
control any special significance within the document, which is the default for
all elements that can be natively tabbed to. To create a tab order, we could
assign incrementing positive integers to the controls, but be aware that this
can affect the navigation of your document, as all elements with a positive
tabindex value are traversed before those set
to 0 or not specified at all (in other words, don’t
add the value 1 because to you it’s the first
element in your control set).