Coisas que você talvez não saiba sobre botões no HTML
Tags: webdev, beginners, html, braziliandevs
Published: 2023-09-22 03:00:00

Um dos componentes mais comuns, mas muitas vezes pode visto de forma leviana pela sua simplicidade. Minha meta com esse artigo é você terminar sabendo pelo menos uma coisa nova sobre o queridinho dos polegares.

----

<br/>

## Semântica e acessiblidade

- Botões precisam ter um texto interno por questões de acessibilidade. Botões de ícone podem ter um texto descritivo também se você ocultar seu conteúdo interno pelo CSS, como por exemplo, usando [uma classe `.sr-only`](https://codepen.io/ffoodd/pen/gwKeyq). Outra forma é atribuindo ao botão uma `aria-label`. Existem várias formas de dar um nome acessível a um conteúdo, a atribuição `name` pode ser preenchida de forma hierárquica por desde texto interno, até atributos `title` e labels _aria_.

> 🔎  Falo mais sobre nome acessível e outras coisas no meu post sobre Semântica Web aqui no DevTo.
{% embed https://dev.to/lixeletto/semantica-no-html-por-debaixo-dos-panos-g5l#:~:text=e%20State.-,Name,-S%C3%A3o%20os%20dados %}

&nbsp;

- Botões e outros elementos considerados "superfícies interativas" precisam ter um tamanho de no mínimo 44px <small>x</small> 44px, salvo se forem inline (links e inputs, por exemplo). [O critério de sucesso 2.5.5 - Target Size](https://www.w3.org/WAI/WCAG21/Understanding/target-size.html) da WCAG existe pra auxiliar pessoas com deficiência de visibilidade ou destreza a terem uma boa área de click, tornando a experiência menos frustrante ou difícil.

> Leia mais sobre [nesse post do Access Guide](https://www.accessguide.io/guide/large-target-size)

&nbsp;

- O botão tem o `type` implícito de `submit`, mas pra ele realmente submeter um formulário, ele precisa interceptar uma ativação implícita do evento submit. A implementação de HTMLFormElement busca a ocorrência de *1)* um elemento button no escopo do formulário *2)* um elemento button associado ao formulário via atributo `form`. Na presença desses elementos,  a variável `m_isActivatedSubmit` é definida como `true. Se `m_isActivatedSubmit` e `m_type` forem `true`, o botão engatilha o evento de submit.

<figure>
  <img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nqi4anpmm80or4xgv9m1.png" alt="C" />
  <figcaption> Implementação do HTMLButtonElement <a href="https://chromium.googlesource.com/chromium/blink/+/refs/heads/main/Source/core/html/HTMLButtonElement.cpp#40">no código fonte do Blink, engine do Google Chrome.</a> 
 </figcaption>
</figure>

&nbsp;

<br/>

---

<br/>

## Estilo e design

- O tamanho do botão geralmente é relativo ao texto que ele contém, né? Se declararmos o padding com em, pra aumentarmos o botão basta aumentar o font-size dele. Isso acontece pois a unidade [`em` escala proporcionalmente ao tamanho da fonte declarada no elemento ou seu parente](https://www.w3.org/Style/Examples/007/units.en.html). Na imagem abaixo, o `padding` e o `border-radius` foram redeclarados com `rem` e note como as bordas e padding vão parecer bem desproporcionais ao aumentar o tamanho do botão.

| Com `em` | Com `rem` |
| ---- | ---- |
| ![Button com em](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k75f7na0ezrd0t8vmazp.png) | ![Button com rem](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e1ts9fozj26hzxub1xdg.png) | 
<small>Ambos com `font-size` de 3rem</small>

&nbsp;

- Use a propriedade `gap` pra separar o botão caso possa haver ícone! O espaçamento vai ser nulo quando tiver apenas o texto.
Se o height do botão for fixo, use flexbox ou CSS grid com `align-items` pra centralizar, se você não tiver declarado height, usar `padding` igual no top e no bottom já alinham o conteúdo no centro perfeitamente.

![Dois botões, um com ícone e outro sem ícone, ambos mantendo espaçamentos proporcionais graças à propriedade gap](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nzssugn2komzua0kjq5j.png)

&nbsp;

- Texto do botão precisava estar em uma linha só e tá quebrando em duas? Já escrevi sobre isso ein? O segredo é priorizar medidas intrínsecas como `max-content` e em último caso bloquear o wrapping no `white-space`.
{% embed https://dev.to/lixeletto/como-fazer-pro-texto-nao-quebrar-de-linha-no-css-5440 %}

&nbsp;

## Pra fechar, botão ou link?

Usar botão ou link?
- Ação? *Botão*
- Muda de localização? *Link*

Um guia muito bom pra tomar essa decisão é esse aqui:
{% embed https://css-tricks.com/a-complete-guide-to-links-and-buttons/ %}