Debate that never happened
Tags: meta, healthydebate
Published: 2019-06-14 23:01:02

---
title: Debate that never happened
published: true
description: History of one argument on the internet
tags: [meta, healthydebate]
cover_image: https://thepracticaldev.s3.amazonaws.com/i/re9joch7hubrec00b0ds.jpg
---

Recently I wrote [the article](https://dev.to/stereobooster/styled-components-one-more-time-5g0l) and I got a comment about it. The comment was about code snippet in the article, it basically said: use `<button>` instead of `<div role="button" tabindex="0">`, because it is best practice, and if you don't follow best practices code is bad.

I tried to start a conversation: I asked to explain the difference, but after this everything went south.

I feel frustrated about this thread, I would prefer to have a constructive conversation, so in this post, I want to compensate missed opportunity and write down how the more constructive conversation on the given subject could look like.

## Code in question

```jsx
const Label = styled.div("Label");
Label.defaultProps = { role: "button" };
```

## Healthier debate

**A**: Why don't you use a button? This is a bad code because it doesn't follow best practice.

**B**: The real reason I don't use the button here is that it was copy pasted from another article. But is it really that bad code? What the difference between `<button>` and `<div role="button" tabindex="0">`?

**A**: Semantics and behavior.

**B**: Which kind of semantics are we talking about? Semantics is meaning, meaning doesn't exist on its own, it needs a receiver (audience). Meaning for who or for what? I will go on and assume that recievers, in this case, are a11y applications (like screen readers). 

> Adding role="button" will make an element appear as a button control to a screen reader.
> -- [MDN](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/button_role)

So my conclusion is that they both have the same semantics from the a11y point of view. Can you be more specific about the difference in the behavior?

**A**: keyboard friendly (responds to enter and space and focusable), disabling via fieldset, different states (`:active`, `:disabled`, `:focus`).

**B**: Ok. I copy pasted this code from [my other article about how to write accessible accordion](https://dev.to/stereobooster/accessible-react-accordion-component-4p99) and my code is keyboard friendly (thanks to `tabIndex=0` elements are focusable), I don't need disabling via fieldset (my component doesn't allow to disabled accordion panels), I don't need `:active` state because I show it with arrows up/down (`▲/▼`). Is it fair to say that code is bad anyway even though it follows WAI-ARIA spec?

**A**: Yes, it is bad practice, because with a button you would need less JS code.

**B**: Ok, let's compare line by line

| `<button`                                     | `<div`                         | element itself                                                                                                         |
|----------------------------------------------|-------------------------------|------------------------------------------------------------------------------------------------------------------------|
| type="button"                                | -                             | prevent form submit                                                                                                    |
| -                                            | role="button"                 | add semantics                                                                                                          |
| -                                            | tabindex="0"                  | make element focusable, to be fair I need to "undo" focusable state for some buttons with tabindex="-1" so it's a draw |
| {padding: 0; background: none; border: none} | {display: inline-block}       | reset styles                                                                                                           |
| -                                            | onKeyDown for enter and space | I need to handle onKeyDown to support up/down arrows, home, end so it is just one more switch case                     |

That is not much more code.

**A**: Still bad practice, because it is not extensible, what if you would need to support the disabled state in the future you would need to write more code, where is with the button it would work out of the box.

**B**: I agree that to use button is the best practice in this case (agreed with it even before the conversation started, as you saw [I posted a link to my article where I wrote about button](https://dev.to/stereobooster/comment/bj5j)). But this best practice doesn't justify calling this code "bad", because you don't know which requirements this code has.

**A**: Are there cases when `<div role="button" tabindex="0">` would be better than `<button>`?

**B**: There are some edge cases

case 1:

> Firefox will, unlike other browsers, by default, persist the dynamic disabled state of a `<button>` across page loads. Setting the value of the autocomplete attribute to off disables this feature. See bug [654072](https://bugzilla.mozilla.org/show_bug.cgi?id=654072).
> -- [MDN about button](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#Notes)

case 2:

In Safari `<button type="button">`s are not "tapable" e.g. you can't reach them with Tab button, `tabindex=1` doesn't help (I tested it Safari version 12.0 (14606.1.36.1.9)). But `<div tabindex=1>`s are "tapable".

**The end**

## Conclusion

I agree that in most cases it is good practice to use `<button type="button">` as a button, but this is a rule of thumb. There are edge cases when the rule doesn't work. I don't think it is possible to judge code out of the context (maybe in some very simple cases) - you need to understand requirements and reasons behind it.

## What went wrong?

### Aggressive start and defensive response

As you can see conversation (from Healthier debate) starts and ends with the same question "why button?". Why it doesn't arrive at a conclusion sooner? Because the first statement contains attack ("the code is bad"). So second response is defensive ("What the difference between `<button>` and `<div role="button" tabindex="0">`?" Can you prove it is bad?)

**Alternative example**

{% devcomment bj8d %}

{% devcomment bj8g %}

### No argumentation

How one suppose to understand the POV of otherone without details? 

**Alternative example**

{% devcomment bin8 %}

{% devcomment bip9 %}

I don't agree with it, but I understand argumentation. As well I learned something new. I chose not to argue in this case, but I could...

## I'm wrong as well

I'm no saint myself, I got triggered the other day:

{% devcomment bj43 %}

The phrase "W3C Validator? Seriously? Did you travel here from 1999?" is inappropriate, I regret I said it.

I want to be more patient. 

> Photo by FuYong Hua on Unsplash