Escrever um bom HTML é mais importante do que você imagina
Tags: webdev, beginners
Published: 2020-08-31 21:19:12

##Por que devo aprender HTML?
Eu já ouvi de mais de uma pessoa que HTML é muito simples e que bastava decorar algumas tags que já era o bastante. Já ouvi também algumas pessoas que programam que se pudessem, trocariam a tag `<body>` por uma `<div>`. Sem dúvidas que apesar dos extremos, essas abordagens funcionam, mas tudo aquilo que poderia ser feito no HTML puro acaba tendo sua responsabilidade transferida para o CSS, Javascript ou pior - pra frameworks. Um bom HTML evita gambiarras com seletores no CSS e Javascript desnecessário, um HTML mal escrito pode ser ilegível pra quem usa outros sentidos que não a visão pra navegar na internet, ou pior, inacessível até pra quem usa todos os sentidos.

Negligenciar o HTML ao iniciar é o equivalente a começar uma peça de teatro, comprar o figurino, escrever o script e contratar poucos atores que, vão acumular papéis que não eram deles ou não vão desempenhar todo seu potencial.

<br/>

--------------

<br/>

##Como começar a estudar HTML?
Pode ser um pouco exaustivo focar apenas no HTML, visto que as nossas expectativas do que é um site não serão contempladas apenas com tags. Na minha opinião, a melhor maneira é começar com o básico, se aprofundar nos atributos de cada tags e aprender sobre acessibilidade.

1. Aprender a sintaxe e a escrever HTML de maneira semântica
Pra além de div, span e p, quase todos os elementos comuns em páginas web tem tags específicas pra eles. Aprenda as mais comuns e quais são seus [atributos globais](https://www.w3schools.com/tags/ref_standardattributes.asp).

2. Se aprofundar nos atributos de cada tag
Algumas tags tem atributos específicos cujo as mecânicas nativas podem te poupar muito trabalho. Nesse ponto é recomendado ter algum conhecimento em pseudo-seletores de CSS pois com eles é possível criar estilos de acordo com esses atributos, usando-os de forma mais efetiva e personalizável.

3. Aprender sobre acessibilidade
Muito de acessibilidade começa na escrita de um bom HTML. Aprender as melhores práticas de escrita e a implementação de atributos ARIA é um bom começo. Com o Javascript podemos gerenciar o estado desses atributos em interfaces mais complexas.

<br/>

--------------

<br/>

##Erros mais comuns
Todo mundo já cometeu ou vai cometer esses erros em HTML, mas você tiver em mente esses conceitos simples já vai estar escrevendo um código com mais qualidade, mais legível, acessível e usando de todas as funcionalidades que o HTML oferece.

<br/>

--------------

<br/>

###Estilo
**Identação**
Idente os elementos filhos sempre dois espaços do elemento pai, aninhamentos simples como links dentro de listas podem ser na mesma linha.

```html
<ul> <!--Elemento Pai-->
<!--Elemento filho à dois espaços de distância-->
  <li><a href="#">Link na mesma linha</a></li> 
</ul>
```

**Atributos**
Se o seu elemento tem mais de 3 atributos, coloque-os em forma de lista e em ordem alfabética.

```html
<input
  autocomplete
  class="input__field"
  id="#password"
  name="password"
  type="password"
  required
/>
```
<br/>

--------------

<br/>

### Usar CSS inline
CSS inline é a prática de colocar estilos dentro da tag de HTML usando o atributo `style=""`.

```html
<!-- Exemplo de estilo inline -->
<button style="
  background: tomato;
  border: none;
  border-radius: 8px;
  color: white;"> Abrir </button>
```

O problema disso é quando você tem uma folha de estilos. No CSS temos um conceito chamado especificidade que define a hierarquia de estilos CSS. Você estilizar um seletor pelo seu ID tem mais especificidade do que pela sua classe, ou seja, caso os dois contenham o mesmo código, o do ID irá sobrepor o da classe:

```css
/* O estilo do seletor #dropdown irá sobrepor o do .dropdown ao chegar no browser */
#dropdown {
  background: slategrey;
}

.dropdown {
  background: tomato;
}
```
Agora, se nesse mesmo elemento declararmos um estilo inline, ele irá sobrepor a classe e o ID, pois estilos inline tem uma especificidade maior do que CSS externo, isso pode atrapalhar muito na hora de entender qual dos documentos está efetivamente estilizando o que. Outro problema é que diferente de escrever o CSS separadamente, o CSS dentro do HTML não é reutilizável e precisa ser declarado individualmente para cada tag. Resumindo - a não ser que você esteja escrevendo e-mails de HTML, não use.

> A ordem de especificidade global é:
> !important > CSS inline > CSS interno > CSS externo

<br/>

--------------

<br/>

### Mal uso de divs e spans

**Quando usar**
As divs servem de containers pra agrupar elementos que vão herdar os mesmos estilos, caso você precise alinhar uma série de cards, você coloca eles dentro de uma `<div>` e aplica os estilos na div. Se você está alinhando vários elementos agrupados em uma página sem usar o elemento pai, você provavelmente está fazendo gambiarra. Spans são como divs mas ainda menos específicos, a maior diferença é que a propriedade `display` padrão do span é `inline`, o que faz sentido, pois os spans foram feitos para serem utilizados dentro de blocos de texto caso você queira aplicar estilos muito específicos à uma palavra.

```html
<p>Lorem ipsum <span>dolor</span> sit amet 
consectetur adipisicing elit</p>
```

Caso esses estilos sejam textuais - itálico, negrito ou sublinhado, prefira utilizar as tags `<i> <strong> <em>`

**Quando não usar**

Não use divs como botões, links, ou outros elementos que já tem tags específicas. Algumas pessoas fazem isso porque essas tags como os vem com uma série de estilos padrão, mas ao fazer isso você perde as propriedades nativas que esses elementos tem, como exemplo, veja porque não utilizar uma div como botão:

* Botões recebem foco, divs não, você não consegue acessar uma div usando tabulação e isso é **péssimo** pra acessibilidade

* Botões tem comportamento de _submit_ por padrão, ao serem clicados vão tentar enviar o formulário sem código adicional

* Botões tem estilos padrões pra propriedade disabled e os leitores de tela vão ignorá-los por padrão caso estejam desabilitados (em uma div você teria que usar aria-disabled ou tabindex=-1)

* Vai mudar a cor ou o fundo de algum texto? Vai colocar um ícone na mesma linha de um `<li>`? Use spam. De resto, pra subtexto temos o `<small>`, pra citações temos `<blockquote>`, pra subescrito temos `<sub>`, pra palavras estrangeiras temos `<lang>`, você raramente precisará usar o span.

Resumindo, mesmo a div e o span sendo mais fáceis de estilizar, não use no lugar de um elemento que já existe.

<br/>

--------------

<br/>

### Uso de `<br>`
Isso é tabu pra algumas pessoas, mas pra W3C não é, a tag está obsoleta, tudo o que essa tag faz pode e deve ser feito com CSS.

**Eu preciso que meu texto quebre linha de uma maneira específica** :cry:

Você pode definir a largura do container no CSS de acordo com a quantidade de caracteres com unidade `ch`.

> `ch` representa a largura do caractere 0, porém se sua fonte não for _monospace_ ou se você estiver lidando com letras, ele não vai representá-los com exatidão, mas já é um começo

> Dica: Um corpo de texto que tem fácil legibilidade tem entre 45 e 60 caracteres de largura, você pode definir isso no CSS.

```css
p {
  width: 80%;
  min-width: 45ch;
  max-width: 60ch;
}

/*Ou você pode usar clamp, que é menos recomendado 
por ter pouco suporte nos browsers */

p {
  width: clamp(45ch, 80%, 60ch);
}
```

Se você precisa MESMO que o texto tenha quebra de linhas exatas, use a tag `<pre>`, que vem com o estilo padrão `whitespace: pre`. Esse estilo faz com que a frase renderize com a exata formatação que você fez no código (mas é uó quando você precisa adaptar as quebras de linha. 
Pra questões de espaçamento entre elementos, você pode usar a boa e velha propriedade CSS `margin` ou, se esses elementos estiverem dentro de containers flex ou grid, com a propriedade CSS `gap`, a exemplo:

HTML
```html
<ul>
  <li><a href="#">Item 1</a></li>
  <li><a href="#">Item 2</a></li>
  <li><a href="#">Item 3</a></li> 
</ul>
```

CSS
```css
ul {
  display: flex; 
  /*display: grid também funciona*/
  gap: 20px 10px;
  /*define um espaçamento na <coluna> e na <linha>*/
}
```

<br/>

--------------

<br/>

### Construção de formulários com tags genéricas
Você não precisa desse monte de `div` ou `p` dentro desse formulário, sério! Existem uma série de tags semânticas e com funcionalidades nativas que funcionam muito melhor

**Não troque gato por `label`**
Ao criar formulários algumas pessoas substituem a `<label>` pelo `<p>` porque a label por padrão fica na mesma linha que o formulário. Isso se deve pelo fato de que o navegador estiliza as labels por padrão como `display: inline`, enquanto o parágrafo com `display: block`. Mas diferente do parágrafo, ao clicar na label, o foco vai diretamente pro input que essa label pertence (se você tiver especificado ele no seu atributo `for`), a label também é mais acessível por ter a função nativa de dizer qual formulário você está assim que você selecionar o input que ela pertence.

**Você não quer que seu botão envie o formulário?**
A tag `<button>` quando dentro de um formulário tem como função nativa de enviar o mesmo e recarregar a página. É possível desativá-la sem usar javascript mudando o atributo `role` para  `button`.

```html
<button role="button"> Não envie! </button>
```

**Coloque aquilo que pertence ao formulário dentro da tag `<form>`**
Não invente, além de ser mais semântico, o form é uma tag que tem sua função reconhecida pelo navegador e possui uma série de métodos Javascript nativos que você pode acessar pelo objeto `document.forms`.

**Agrupe seus inputs com as as tags `<fieldset>` e `<legend>`**
Além de ser mais semântico agrupar seus formulários dessa forma, você consegue desabilitar todos os inputs de um fieldset de uma vez passando a propriedade `disabled` nele.

**Use e abuse dos atributos globais dos inputs**
Os atributos globais possibilitam uma série de comportamentos e ações que seriam trabalhosos de criar com CSS e JS

* autocomplete
Em inputs textuais possibilita que o navegador sugira o ultimo valor utilizado nesse mesmo input. Não é recomendado utilizar em inputs de cadastro e em inputs tipo `password` em alguns casos.

```html
<input type="text" name="name" autocomplete="on">
```


* autofocus
O input com `autofocus` ganha foco assim que a página carrega.

* inputmode
Diz pro navegador qual teclado deve ser utilizado para preencher determinado input. Se você designar um input com `inputmode="numeric"`, ao clicá-lo no seu celular, ele vai abrir com o teclado numérico.

* readonly, required e disabled
São os 3 mais comuns, `readonly` serve para que o usuário não possa alterar valores de inputs pré-preenchidos, com `required` o navegador avisa pro usuário que um input não foi preenchido quando ele tenta enviar o formulário e `disabled` desabilita o elemento e não permite seu valor ser enviado pelo formulário.

### Usar CSS e Javascript pra resolver problemas que HTML já resolve
O HTML te salva de muito CSS e Javascript à toa, um ótimo exemplo são os colapsáveis:

Colapsáveis são formas de agrupar um conteúdo que só ficará visível quando você clicar na sua legenda
![Exemplo de colapsável que ao clicar ele te mostra o conteúdo de dentro](https://dev-to-uploads.s3.amazonaws.com/i/32u8t9rgvsm7ci4mejkq.gif)

> Caso você não defina a tag `summary`, o navegador coloca "Saiba Mais" como título por padrão (se a linguagem do seu navegador for pt-br)

```html
<details>
  <sumary> Exemplo de colapsável </sumary>
  <p> Sem CSS nem Javascript </p>
</details>
```

E usando apenas CSS você pode estilizar inclusive a animação do conteúdo
![Exemplo de colapsável estilizado](https://dev-to-uploads.s3.amazonaws.com/i/dkuv2rek8dv8890fbaqk.gif)

### Pra fechar
HTML é uma linguagem muito poderosa e pode contribuir pra qualidade geral do seu código em todos os pontos da sua carreira pois tudo o que renderiza na web começa no index.html. Focar em aprender HTML de verdade é a maneira mais assertiva de começar do jeito certo.

<br/>

--------------

<br/>

Se isso foi útil pra você, compartilha com quem você acha que isso vai ajudar. Dúvidas, sugestões? Comente ou manda um salve lá no meu Twitter [@lixeletto](https://twitter.com/lixeletto).