Capítulo 8

Bootstrap e formulários HTML5

"O trabalho é a melhor das regularidades e a pior das intermitências" -- Victor Marie Hugo

8.1 Bootstrap e frameworks de CSS

Uma tendência em alta no mundo front-end é o uso de frameworks CSS com estilos base para nossa página. Ao invés de começar todo projeto do zero, criando todo estilo na mão, existem frameworks que já trazem toda uma base construída de onde partiremos nossa aplicação.

Existem muitas opções mas o Twitter Bootstrap talvez seja o de maior notoriedade. Ele foi criado pelo pessoal do Twitter a partir de códigos que eles já usavam internamente. Foi liberado como opensource e ganhou muitos adeptos. O projeto cresceu bastante em maturidade e importância no mercado a ponto de se desvincular do Twitter e ser apenas o Bootstrap.

http://getbootstrap.com

O Bootstrap traz uma série de recursos:

Como o próprio nome diz, é uma forma de começar o projeto logo com um design e recursos base sem perder tempo com design no início.

Saber inglês é muito importante em TI

Na Alura Língua você reforça e aprimora seu inglês! Usando a técnica Spaced Repetitions o aprendizado naturalmente se adapta ao seu conhecimento. Exercícios e vídeos interativos fazem com que você pratique em situações cotidianas. Além disso, todas as aulas possuem explicações gramaticais, para você entender completamente o que está aprendendo. Aprender inglês é fundamental para o profissional de tecnologia de sucesso!

Pratique seu inglês na Alura Língua.

8.2 Estilo e componentes base

Para usar o Bootstrap, apenas incluímos seu CSS na página:

<link rel="stylesheet" href="css/bootstrap.css">

Só isso já nos traz uma série de benefícios. Um reset é aplicado, e nossas tags ganham estilo e tipografia base. Isso quer dizer que podemos usar tags como um H1 ou um P agora e elas terão um estilo característico do Bootstrap.

Além disso, ganhamos muitas classes com componentes adicionais que podemos aplicar na página. São várias opções. Por exemplo, pra criar um título com uma frase de abertura em destaque, usamos o Jumbotron:

<div class="jumbotron jumbotron-fluid">
    <div class="container">
        <h1 class="display-4">Ótima escolha!</h1>
        <p class="lead">Obrigado por comprar na Mirror Fashion.</p>
    </div>
</div>

No exercício a seguir vamos usar vários outros componentes.

8.3 A página de checkout da Mirror Fashion

Neste capítulo, vamos desenvolver a página de checkout da Mirror Fashion. Após escolher o produto desejado, o usuário cai nessa página para efetivar a compra.

Nossa loja foi otimizada pra compra direta, sem carrinho de compras. O cliente escolhe o produto e compra direto, com um clique. Só precisamos coletar os dados dele e do pagamento.

O foco dessa nova página é a coleta de informações para efetivação da compra. Um grande formulário complexo com os campos necessários. Vamos usar o Bootstrap para desenvolver essa página com mais facilidade e rapidez.

Site visto no Desktop

Figura 8.1: Site visto no Desktop

E, como aprendemos antes, vamos desenvolver tudo mobile-first. Nesse momento, portanto, ainda não teremos o design Desktop mostrado acima, mas uma versão mobile em uma coluna. Veremos como adaptar a versão Desktop com Bootstrap depois.

Site visto no Mobile

Figura 8.2: Site visto no Mobile

8.4 Exercícios: página de checkout

  1. Crie a página checkout.html com HTML simples.

     <!doctype html>
     <html>
         <head>
             <meta charset="UTF-8">
             <meta name="viewport" content="width=device-width">
             <title>Checkout Mirror Fashion</title>
         </head>
         <body>
    
             <h1>Ótima escolha!</h1>
             <p>Obrigado por comprar na Mirror Fashion!
             Preencha seus dados para efetivar a compra.</p>
    
             <h2>Sua compra</h2>
             <dl>
                 <dt>Produto</dt>
                 <dd>Fuzzy Cardigan</dd>
    
                 <dt>Cor</dt>
                 <dd>Verde</dd>
    
                 <dt>Tamanho</dt>
                 <dd>40</dd>
    
                 <dt>Preço</dt>
                 <dd>R$ 129,90</dd>
             </dl>
    
         </body>
     </html>
    
  2. Abra a página checkout.html no navegador e veja que está com o estilo padrão do navegador.

    O primeiro passo é incluirmos o arquivo CSS do bootstrap na nossa página. Você vai ver uma mudança sutil no estilo da página, principalmente em aspectos tipográficos.

    Coloque no <head> da página de checkout o CSS do bootstrap:

     <link rel="stylesheet" href="css/bootstrap.css">
    

    Teste novamente a página.

  3. O primeiro componente pronto do bootstrap que vamos usar é o jumbotron. É basicamente a abertura do site, contendo sua chamada principal. Para usá-lo basta criar uma div com a classe jumbotron e a classe jumbotron-fluid.

    Envolva as chamadas de abertura que já tínhamos com h1 e p em duas <div>. A primeiro div contém class="jumbotron jumbotron-fluid" e a segundo, class="container".

     <div class="jumbotron jumbotron-fluid">
         <div class="container">
    
             <!-- h1 e p que já tínhamos, somente adicionar as respectivas classes -->
             <h1 class="display-4">Ótima escolha!</h1>
             <p class="lead">Obrigado por comprar na Mirror Fashion!
         Preencha seus dados para efetivar a compra.</p>
    
         </div><!-- fim .container dentro do jumbotron -->
     </div><!-- fim .jumbotron -->
    

    Abra a página e note que um estilo diferente aparece. Teste redimensionar o navegador e veja que o tamanho da fonte e espaçamento do componente se ajustam automaticamente. O Bootstrap usa responsive design automaticamente em seus componentes.

    Para saber mais do jumbotron: https://getbootstrap.com/docs/4.1/components/jumbotron/

  4. Use um outro componente do Bootstrap, o card para organizar a seção que mostramos as informações da compra do cliente. Cuidado com o exercício, com os nomes das classes, que confundem bastante.

    Adapte o HTML do h2 "Sua compra" e do dl que temos para se adequar ao componente de card, adicionando o seguinte código após o fechamento da <div class="jumbotron">:

     <div class="card mb-3">
         <div class="card-header">
             Sua compra
         </div><!-- fim .card-header -->
    
         <div class="card-body">
    
             <!-- ... aqui vai o <dl> que já temos ... -->
    
         </div><!-- fim .card-body -->
     </div><!-- fim .card -->
    

    Repare como os nomes das classes, apesar de serem muitos, fazem sentido para isolar cada parte do cartão.

    Teste novamente a página no navegador e veja o resultado. Temos um cartão arredondado com título em destaque no topo.

    Para saber mais sobre cartões do Bootstrap: https://getbootstrap.com/docs/4.1/components/card/

  5. Repare no exercício anterior do jumbotron que o <div class="container"> é responsável por centralizar e dar espaçamento na tela. Muito parecido aliás com o container que havíamos criado antes em nosso projeto, mas agora é uma classe do Bootstrap.

    Crie uma outra div container pra conter o card que acabamos de criar e veja como ele fica melhor posicionado no centro da tela.

     <div class="container">
    
         <!-- ... card aqui ... -->
    
     </div><!-- fim .container da pagina -->
    

  6. Dentro do card-body, logo no topo, acima da lista de definições <dl>, vamos colocar uma foto do produto na cor escolhida.

    Com Bootstrap, podemos ainda acrescentar algumas classes nessa imagem para obter resultados interessantes. A classe img-thumbnail faz a imagem ficar flexível e nunca estourar o tamanho do pai, também faz a imagem ficar centralizada e com uma borda de destaque. A classe mb-3 adiciona uma pequena margem na parte inferior da imagem.

    Adicione a imagem do produto logo acima da lista <dl> dentro do div card-body:

     <img src="img/produtos/foto1-verde.png" alt="Fuzzy Cardigan"
              class="img-thumbnail mb-3">
    

    Teste novamente a página.

Aprenda se divertindo na Alura Start!

Você conhece alguém que tem potencial para tecnologia e programação, mas que nunca escreveu uma linha de código? Pode ser um filho, sobrinho, amigo ou parente distante. Na Alura Start ela vai poder criar games, apps, sites e muito mais! É o começo da jornada com programação e a porta de entrada para uma possível carreira de sucesso. Ela vai estudar em seu próprio ritmo e com a melhor didática. A qualidade da conceituada Alura, agora para Starters.

Conheça os cursos online da Alura Start!

8.5 Formulários a fundo

Quando solicitamos que o usuário informe seu nome, seu endereço de email, se ele quer receber uma newsletter, qualquer informação, precisamos utilizar os elementos corretos. Para isso, vamos conhecer os formulários HTML: a tag <form>.

Já usamos alguns antes. Agora vamos ver a fundo seus desdobramentos.

Atributos do Form

<form action="/efetivar.html" method="POST">
</form>

O formulário exemplificado anteriormente apresenta o atributo obrigatório action. O valor desse atributo é o endereço para onde as informações do formulário serão enviadas, e esse valor depende inteiramente de como é feita a aplicação que receberá essas informações no lado do servidor.

O segundo atributo, method, especifica o método do HTTP pelo qual essa informação será transmitida. O valor post, de maneira simplista, significa que queremos inserir as informações desse formulário, salvá-la de alguma maneira. Outro valor possível para esse atributo, o get, é utilizado quando queremos obter alguma coisa a partir das informações que estamos transmitindo, por exemplo, um formulário de busca.

Componentes

Porém, neste exemplo, não temos nenhum elemento para capturar as informações. Na verdade, somente a marcação da tag <form> não mostra nenhum elemento visível no navegador. Vamos supor que precisemos de uma informação como o nome do visitante do nosso site para guardar em um banco de dados. Vamos adicionar alguns elementos ao nosso formulário anterior:

<form action="/efetivar.html" method="POST">

  <label for="nome">Nome:</label>
  <input type="text" name="nome" id="nome">

  <input type="submit">
</form>

Label

Adicionamos a marcação do elemento <label>. Esse elemento é uma tag de conteúdo, e seu texto é exibido de maneira comum dentro do nosso formulário, a única diferença é que essa marcação faz uma ligação com outro elemento qualquer em nosso formulário. Note que nosso label tem o atributo for, que recebe o valor nome.

Quando clicamos com o mouse sobre o texto marcado com a tag label, o elemento que tem o atributo id com o mesmo valor que o atributo for do label é selecionado para que possamos interagir com ele. No exemplo, esse elemento vinculado ao label é um campo de texto que declaramos com a tag input.

Essa marcação <label> é de extrema importância para a usabilidade e acessibilidade dos nossos formulários.

Input

A maioria dos elementos que utilizamos nos formulários para capturar informações dos usuários são da tag <input>. No exemplo anterior, utilizamos duas variações dessa tag.

Os tipos diferentes de inputs são determinados pelo valor do seu atributo type. A seguir, vamos detalhar os tipos aceitos para essa tag.

text

<input type="text" name="nome_usuario">

Provavelmente o tipo mais comum de input, o que tem o atributo type="text", é utilizado quando queremos que o usuário envie uma informação textual simples, pois esse elemento não permite a entrada de quebras de linha.

Ao enviarmos o formulário, a informação digitada pelo usuário é acessível no lado do servidor por meio do atributo name, utilizado para identificar cada informação contida nos parâmetros da requisição. Para ter acesso à informação digitada quando tratamos o formulário com algum tipo de script, para validar o conteúdo por exemplo, é necessário obter o conteúdo da propriedade value do objeto no DOM.

password

O input que recebe o atributo type="password" é similar ao anterior, do tipo text, com a diferença de que ele não exibe exatamente o texto digitado pelo usuário, e sim uma série de símbolos * ou outro, dependendo do navegador e sistema operacional.

<input type="password" name="senha">

checkbox

O elemento input do tipo checkbox exibe uma caixa para marcação, é muito utilizado quando temos uma opção que pode ser marcada como sim ou não, por exemplo "Aceito os termos de contrato do usuário", ou "Manter a sessão ativa" em formulários de login.

Apesar de muito utilizado com o valor true, é possível determinar qualquer valor para o checkbox.

<input id="contrato" name="contrato" type="checkbox" value="sim">
<label for="contrato">Aceito os termos do contrato.</label>

radio

  <input type="radio" name="idade" id="idade5" value="5">
  <label for="idade5">Menos de 5 anos</label>

  <input type="radio" name="idade" id="idade10" value="10">
  <label for="idade10">Menos de 10 anos</label>

  <input type="radio" name="idade" id="idade15" value="15">
  <label for="idade15">Menos de 15 anos</label>

  <input type="radio" name="idade" id="idade20" value="20">
  <label for="idade20">Menos de 20 anos</label>

Quando desejamos que o usuário escolha somente uma entre uma série de opções, podemos utilizar elementos input do tipo radio. Quando há mais de um elemento desse tipo com o mesmo valor no atributo name, somente um pode ser selecionado.

image

<input type="image" name="botao" src="images/enviar.png"
                alt="Botão para enviar o formulário" width="20" height="18">

É possível substituir o botão de envio do formulário por uma imagem, possibilitando criar um visual mais atrativo para o formulário.

Hoje em dia, com o CSS3, podemos adicionar imagens que não fazem parte do conteúdo, são somente estilo, com Image Replacement no CSS, como fizemos na página index.html.

file

<input type="file" name="anexo">

Quando é necessário que o usuário envie um arquivo para a aplicação no lado do servidor é necessário o uso do input do tipo file. Para o correto envio dos arquivos, muitas vezes também é necessário adicionar o atributo enctype="multipart/form-data" na tag <form>.

hidden

<input type="hidden" name="codigo" value="abc012xyz789">

Muitas vezes precisamos enviar e receber informações que não têm utilidade direta para o usuário e, portanto, não devem ser exibidos no formulário. Para essa finalidade, existe o input do tipo hidden, que somente carrega um valor.

button

<input type="button" name="mostra_dialogo" value="Clique aqui!">

O elemento input com o atributo type="button" renderiza um botão dentro do formulário, mas esse botão não tem nenhuma função direta nele e é comumente utilizado para disparar eventos para a execução de scripts.

O texto do botão é determinado pelo valor do atributo value.

submit

<input type="submit" name="enviar" value="Enviar">

O elemento input com o atributo type="submit" é similar ao type="button", mas quando acionado esse elemento inicia a chamada que envia as informações do formulário para o endereço indicado no atributo action do <form>.

reset

<input type="reset" name="reset" value="Limpar">

O input com type="reset" elimina os valores digitados anteriormente nos elementos de um formulário, permitindo que o usuário limpe o mesmo.

<input> e <button>

A tag <input> dos tipos button, submit e reset pode ser substituída pela tag <button>. Neste caso, o texto do botão passa a ser indicado como conteúdo da tag. Ainda assim é necessário especificar o valor do atributo type, inclusive se ele for button:

<button type="button" name="mostra_dialogo">Clique aqui!</button>
<button type="submit" name="enviar">Enviar</button>
<button type="reset" name="reset">Limpar</button>

Textarea

Quando desejamos que o usuário insira uma quantidade grande de informações textuais, incluindo quebras de linha, é necessário o uso da tag textarea

<textarea name="texto"></textarea>

Select, Optgroup e Option

Quando desejamos que o usuário selecione entre diversas opções, com a possibilidade de flexibilizar a maneira com que ele interage com o componente do formulário, podemos utilizar a tag <select>.

<select name="cidades">
  <option value="bsb">Brasília</option>
  <option value="rj">Rio de Janeiro</option>
  <option value="sp">São Paulo</option>
</select>

Em sua configuração padrão, o controle select exibe o que conhecemos como menu drop-down, permitindo que somente uma das opções possa ser selecionada. Caso seja adicionado o atributo multiple, é possível selecionar mais de uma opção da mesma maneira que selecionamos diversos arquivos no explorador do sistema operacional.

<select name="cidades" multiple>
  <option value="bsb">Brasília</option>
  <option value="rj">Rio de Janeiro</option>
  <option value="sp">São Paulo</option>
</select>

Caso necessário, dependendo do número de opções apresentadas ao usuário, pode ser interessante agrupá-las:

<select name="bairro">
  <optgroup label="Brasília">
    <option value="asan_bsb">Asa Norte</option>
    <option value="asas_bsb">Asa Sul</option>
  </optgroup>
    <optgroup label="Rio de Janeiro">
        <option value="botafogo_rj">Botafogo</option>
        <option value="centro_rj">Centro</option>
    </optgroup>
  <optgroup label="São Paulo">
    <option value="vlmariana_sp">Vila Mariana</option>
    <option value="centro_sp">Centro</option>
  </optgroup>
</select>

8.6 Novos componentes do HTML5

Com a nova especificação do HTML, é possível utilizar uma série de novos componentes que facilitam bastante o desenvolvimento de formulários. Até o momento em que essa apostila foi escrita, muitos componentes são incompatíveis com os navegadores, mas mostram, na maioria dos casos, um campo de texto permitindo a entrada de qualquer tipo de informação.

A maioria dos novos tipos de componentes de formulário foram criados para permitir que o navegador adapte o método de entrada para o mais adequado em cada um dos casos. Alguns desses componentes já são compatíveis com navegadores de dispositivos móveis.

email

<input type="email" name="email">

O input do tipo email permite que os dispositivos móveis, principalmente, exibam um teclado adaptado para facilitar esse tipo de entrada. Por exemplo, o iPhone exibe um teclado com o caractere @ e com as opções de domínio .com.

number

<input type="number" max="100" step="5">

O input do tipo number, além de exibir um teclado numérico em dispositivos móveis, nos navegadores modernos exibe um controle que permite incrementar ou decrementar o valor do campo clicando em uma seta para cima ou para baixo.

Além dessa diferença visual, é possível determinar valores mínimos, máximos e se há uma escala de valores válidos. No exemplo anterior, o elemento deve aceitar números múltiplos de 5 com o limite do valor "100".

url

<input type="url" name="endereco">

O elemento input com tipo url permite que os dispositivos exibam um teclado como, no exemplo do iPhone, opções como www e .com.

range

<input type="range" name="volume">

O elemento input do tipo range exibe um controle deslizante nos navegadores modernos, permitindo uma interação mais agradável quando precisamos de um valor numérico em escala. O controle guarda um valor numérico em seu atributo value. Assim como o input do tipo number, é possível especificar um valor mínimo, máximo e uma escala.

A renderização mais comum desse controle, em um Chrome:

date, month, week, time, datetime e datetime-local

<input type="date" name="validade">

Os controles de "date picker" são feitos para coletar uma informação de data ou hora. São várias as possibilidades de formato de data ou hora. No navegador Opera, quando utilizado esse tipo de controle, o usuário pode selecionar uma data a partir de um calendário. É possível especificar datas mínima e máxima.

Em geral, os navegadores devem oferecer alguma funcionalidade de escolha de datas para o usuário, como no Chrome:

Ou no iPhone:

color

<input type="color" name="cor_olhos">

O elemento input do tipo color permite que seja exibido um "color picker" para o preenchimento do seu valor. O Chrome no Mac, por exemplo, exibe o color picker padrão do sistema:

search

<input type="search" results="10">

O input do tipo search exibe um campo específico para busca. O atributo "results" determina quantas últimas buscas serão armazenadas e lembradas, além de exibir uma lupa dentro do campo (Safari e Chrome).

tel

<input type="tel" name="telefone">

O input do tipo tel foi especificado para coletar um número de telefone.

Em dispositivos com teclados virtuais como smartphones e tablets, é comum o teclado ser adaptado para exibir apenas opções relevantes à entrada de números telefônicos, como no iPhone:

8.7 Novos atributos HTML5 em elementos de formulário

Na especificação do HTML5 estão definidos novos atributos para os elementos de formulário, visando implementar algumas necessidades comuns que antes não eram possíveis de serem atendidas puramente com a marcação do formulário.

autofocus

Sua presença indica que aquele campo deve iniciar com foco quando a página for carregada. O usuário já pode começar a digitar algo sem nenhum clique.

<input type="text" name="nome" autofocus>

placeholder

<input type="text" name="nome" placeholder="Insira seu nome">

O atributo placeholder exibe o texto contido em seu valor dentro do elemento do formulário caso o seu valor seja vazio.

autocomplete, list e datalist

É possível implementar uma funcionalidade de sugestão de valores com mais facilidade.

<input type="text" list="cidades" autocomplete="on">
<datalist id="cidades">
  <option value="Brasília">
  <option value="Rio de Janeiro">
  <option value="São Paulo">
</datalist>

A implementação de autocomplete sem o atributo list no campo, ligando-o a um datalist, vai utilizar os últimos valores utilizados em outros campos ou em outros formulários, dando prioridade a valores adicionados em inputs com o mesmo valor no atributo name.

Existem diversas maneiras de utilizar os componentes de formulários, tanto os novos do HTML5 como os já existentes. Mesmo com a oportunidade de inovar e criar uma interação totalmente diferente do usuário com um formulário, é importante manter o mesmo método que adotamos anteriormente. A marcação correta do formulário facilita muito o uso dele em diversos navegadores e em outros tipos de clientes também, como por exemplo navegadores especiais para deficientes visuais.

Seus livros de tecnologia parecem do século passado?

Conheça a Casa do Código, uma nova editora, com autores de destaque no mercado, foco em ebooks (PDF, epub, mobi), preços imbatíveis e assuntos atuais.
Com a curadoria da Caelum e excelentes autores, é uma abordagem diferente para livros de tecnologia no Brasil.

Casa do Código, Livros de Tecnologia.

8.8 Ícones

O Bootstrap não inclui uma biblioteca de ícones por padrão, mas eles recomendam algumas bibliotecas para escolher. As recomendadas são:

Para saber mais detalhes: https://getbootstrap.com/docs/4.1/extend/icons/

Aqui vamos usar o Iconic, que é um código aberto com 223 ícones nos formatos SVG e fonte customizada.

Para usarmos essa biblioteca é necessário baixar um arquivo .css e adicionar no HTML:

<link rel="stylesheet" href="css/open-iconic-bootstrap.css">

Depois disso é muito simples utilizar os ícones:

<span class="oi oi-thumb-up"></span>

Os ícones são disponibilizados através de uma fonte de texto customizada. A vantagem de se usar fontes para ícones é que o desenho fica escalável, como uma letra. Ele não perde qualidade em nenhum tamanho ou resolução por ser vetorial. E, assim como uma letra, podemos aplicar efeitos de texto como sombras e cores.

A desvantagem é que cada ícone só pode ter um path no desenho e uma única cor. Não é possível usar ícones complexos com fontes.

8.9 Exercícios: Formulários

  1. O formulário de compra possui campos para o cliente digitar informações pessoais e informações sobre o pagamento. Para melhor organização, vamos separar os campos em dois fieldsets.

    Vamos criar o <form> logo depois do card, e ainda dentro do container. Neste form, crie o primeiro <fieldset> usando <legend> para identificar os Dados Pessoais.

    Esse primeiro fieldset, dos Dados Pessoais, deve conter os campos Nome, Email, CPF e um checkbox para o usuário optar ou não por receber newsletter.

     <form>
         <fieldset>
             <legend>Dados pessoais</legend>
    
             <div class="form-group">
                 <label for="nome">Nome completo</label>
                 <input type="text" class="form-control" id="nome" name="nome">
             </div>
    
             <div class="form-group">
                 <label for="email">Email</label>
                 <input type="email" class="form-control" id="email" name="email">
             </div>
    
             <div class="form-group">
                 <label for="cpf">CPF</label>
                 <input type="text" class="form-control" id="cpf" name="cpf">
             </div>
    
             <div class="form-group custom-control custom-checkbox">
                 <input type="checkbox" class="custom-control-input" id="newsletter"
                                 value="sim" checked>
                 <label class="custom-control-label" for="newsletter">
                     Quero receber Newsletter da Mirror Fashion
                 </label>
             </div>
         </fieldset>
     </form>
    

    Repare que cada campo possui um input e um label. Para agrupá-los, usamos uma div form-group do Bootstrap. Cada input deve ter uma classe form-control, atenção que para o input com type="checkbox" é necessário adicionar outras classes do Bootstrap.

    Teste a página no navegador e observe o estilo padrão que ganhamos apenas por usar o Bootstrap.

  2. Adicione mais um <fieldset> ainda dentro do form (logo após a tag de fechamento do <fieldset> do exercício anterior) com os Dados do Cartão. Esse fieldset tem três campos: um com código do cartão, outro com a bandeira do cartão e outro com data de validade. Neste último, usaremos o input month do HTML5.

     <fieldset>
         <legend>Cartão de crédito</legend>
    
         <div class="form-group">
             <label for="numero-cartao">Número - CVV</label>
             <input type="text" class="form-control" id="numero-cartao" name="numero-cartao">
         </div>
    
         <div class="form-group">
             <label for="bandeira-cartao">Bandeira</label>
             <select class="custom-select" id="bandeira-cartao">
                 <option disabled selected>Selecione uma opção...</option>
                 <option value="master">MasterCard</option>
                 <option value="visa">VISA</option>
                 <option value="amex">American Express</option>
             </select>
         </div>
    
         <div class="form-group">
             <label for="validade-cartao">Validade</label>
             <input type="month" class="form-control" id="validade-cartao" name="validade-cartao">
         </div>
     </fieldset>
    

    Teste novamente no navegador.

  3. Para finalizar, é necessário adicionar um botão antes do fechamento da tag form, que cuidará do envio dos dados digitados (vamos usar um btn-primary do Bootstrap).

     <button type="submit" class="btn btn-primary">
         Confirmar Pedido
     </button>
    
  4. Adicione o atributo placeholder do HTML5 nos campos email e CPF com dicas de preenchimento:

     <input type="email" class="form-control" id="email" name="email" placeholder="email@exemplo.com">
    
     ...
    
     <input type="text" class="form-control" id="cpf" name="cpf" placeholder="000.000.000-00">
    

    Adicione o atributo autofocus do HTML5 no input nome:

     <input type="text" class="form-control" id="nome" name="nome" autofocus>
    
  5. Vamos incentivar o clique no botão de confirmação do pedido com um ícone além do texto. Use os Iconic pra isso. Primeiro adicione o link para essa biblioteca dentro da tag <head>.

     <link rel="stylesheet" href="css/open-iconic-bootstrap.css">
    

    Em seguida, dentro do botão, apenas adicione a linha que declara o ícone:

     <button type="submit" class="btn btn-primary">
         <span class="oi oi-thumb-up"></span>
         Confirmar Pedido
     </button>
    

    Para saber mais sobre os ícones: https://useiconic.com/open/

  6. Use outras classes do Bootstrap para ajustar mais detalhes. No botão, adicione a classe btn-lg para deixar o botão maior.

    Veja mais opções de botões com Bootstrap: https://getbootstrap.com/docs/4.1/components/buttons/

  7. (opcional) O Bootstrap tem outros recursos para formulários, como os input groups. Teste trocando o código do campo email para isso:

     <div class="form-group">
         <label for="email">Email</label>
    
         <div class="input-group mb-3">
             <div class="input-group-prepend">
                 <span class="input-group-text">@</span>
             </div>
             <input type="email" class="form-control" id="email" name="email"
                             placeholder="email@exemplo.com">
         </div>
     </div>
    

    Veja outro exemplo do uso do input groups. Troque o código do campo Bandeira do cartão de crédito para isso:

     <div class="form-group">
         <div class="input-group mb-3">
             <div class="input-group-prepend">
                 <label class="input-group-text" for="bandeira-cartao">Bandeira</label>
             </div>
             <select class="custom-select" id="bandeira-cartao">
                 <option disabled selected>Selecione uma opção...</option>
                 <option value="master">MasterCard</option>
                 <option value="visa">VISA</option>
                 <option value="amex">American Express</option>
             </select>
         </div>
     </div>
    

    Implemente também em outros campos, inclusive usando ícones.

    Veja mais opções do Bootstrap para formulários: https://getbootstrap.com/docs/4.1/components/forms/

8.10 Validação HTML5

Entre as muitas novidades de formulários que vimos no HTML5, há ainda toda uma parte de validação de dados com restrições expressas diretamente no código HTML.

required

Podemos indicar na marcação do formulário quando um campo é de preenchimento obrigatório.

<input type="text" name="nome" required>

Esse atributo permite uma validação fraca no lado do cliente.

pattern

Conseguimos também especificar um formato requerido através do atributo pattern, adicionando uma expressão regular como valor:

<input type="text" pattern="^@\w{2,}" name="usuario_twitter">

O atributo pattern também permite uma validação fraca do campo.

Validação no CSS

A maioria dos novos componentes de formulário e os atributos que funcionam como validadores de campos na verdade somente aplicam uma pseudo-classe específica no campo que não está atendendo ao padrão ou requisito especificado.

Essa pseudo-classe é a :invalid, e pode ser utilizada para dar um retorno visual imediato caso o usuário não esteja atendendo aos requisitos dos campos do formulário.

:invalid {
  outline: 1px solid #CC0000;
}

Essa validação é fraca pois de maneira direta não é possível impedir que o usuário envie as informações do formulário, mesmo que incompletas ou incorretas. É possível porém alterar o botão de submit e deixá-lo desabilitado caso seja possível selecionar algum elemento por essa pseudo-classe no formulário. Essa verificação e alteração do elemento submit pode ser feita por JavaScript e jQuery de maneira simples.

Suporte nos navegadores

A validação HTML5 está implementada no Chrome, Firefox, Safari, Opera e IE10. Dos navegadores móveis, temos suporte em Chrome, Firefox, Opera, IE e Blackberry:

http://caniuse.com/form-validation

Se você quiser suportar navegadores mais antigos, recomendamos o uso de um polyfill:

https://github.com/aFarkas/webshim

Agora é a melhor hora de respirar mais tecnologia!

Se você está gostando dessa apostila, certamente vai aproveitar os cursos online que lançamos na plataforma Alura. Você estuda a qualquer momento com a qualidade Caelum. Programação, Mobile, Design, Infra, Front-End e Business! Ex-aluno da Caelum tem 15% de desconto, siga o link!

Conheça a Alura Cursos Online.

8.11 Exercícios: validação com HTML5

  1. Adicione o atributo required nos campos Nome e CPF.

    Teste submeter o formulário sem preencher esses campos.

  2. Algumas validações já são implícitas apenas por usarmos o input type correto. Por exemplo, tente submeter o formulário preenchendo o email com um valor inválido (com dois @ por exemplo).

  3. Podemos estilizar no CSS quando um campo está inválido:

     .form-control:invalid {
         border: 1px solid #CC0000;
     }
    

8.12 Grid responsivo do Bootstrap

Umas das dificuldades mais comuns de um projeto front-end é o posicionamento de elementos, sobretudo em designs multi coluna. A solução mais comum é uso de grids, uma ideia antiga que veio dos próprios designers.

Divide-se a tela em colunas e vamos encaixando os elementos dentro desse grid.

Todo framework CSS moderno traz um grid pronto para utilização. Todo código CSS necessário para correto posicionamento já foi escrito e só precisamos usar as classes certas. O Bootstrap tem um grid pronto e várias classes para usarmos.

O grid do Bootstrap trabalha com a ideia de 12 colunas e podemos escrever nosso código escolhendo quantas colunas ocupar. Alguns exemplos:

Essas classes de coluna são as que definem o tamanho de cada elemento na página com base nas 12 partes do grid padrão. Em código:

<div class="row">
    <div class="col-md-4">
        ...
    </div>

    <div class="col-md-8">
        ...
    </div>
</div>

No código anterior, deixamos a primeira <div> ocupando 4/12 da tela e a outra, 8/12. Repare que, para o grid funcionar, ao redor das colunas usamos uma <div> com a classe row. Ela é necessária para que o layout fique correto.

Podemos ainda criar grids dentro de outro grid, sempre obedecendo a divisão de 12 colunas em cada. Por exemplo:

<div class="row">
    <div class="col-md-4">
        ...
    </div>

    <div class="col-md-8">
        <div class="row">
            <div class="col-md-6">
                ...
            </div>
            <div class="col-md-6">
                ...
            </div>
        </div>
    </div>
</div>

Esse exemplo criou um segundo grid dentro da coluna da direita do primeiro grid. Nesse segundo grid há duas colunas ocupando metade cada uma (6/12). Mas como um grid está dentro do outro, na prática, ele vai ocupar metade do tamanho da <div> que tem 8/12 de tamanho.

Responsivo

Um dos pontos mais interessantes dos grids é que eles são responsivos. Isso quer dizer que podemos aplicar diferentes layouts de colunas no nosso código ao mesmo tempo e cada um deles vai valer só em determinada situação.

Nos códigos anteriores, por exemplo, usamos classes como col-md-6. O md nessa classe significa que vamos ocupar 6 colunas do grid apenas em telas maiores que 768px de largura. Em telas menores, automaticamente nosso grid será de uma coluna só.

E, claro, temos classes pra outros tamanhos de tela também. No Bootstrap temos essas famílias de classes de grids já prontas:

Podemos aplicar mais de uma classe ao mesmo tempo no mesmo elemento:

<div class="row">
    <div class="col-xs-6 col-sm-4">
        ...
    </div>

    <div class="col-xs-6 col-sm-8">
        ...
    </div>
</div>

Nesse exemplo, nosso grid divide no meio (6 pra cada lado) em telas muito pequenas mas depois divide em 4 e 8 pra telas um pouco maiores.

8.13 Exercícios: grids

  1. Nosso design mobile-first funciona muito bem em telas pequenas. Mas conforme vamos aumentando o browser, notamos que tudo fica meio grande. O card e o form esticam 100%, o que é um exagero em telas maiores.

    Vamos usar grids do Bootstrap para transformar nosso design em 2 colunas em telas maiores. Por padrão, o Bootstrap já traz media queries para adaptação em 768px. A ideia é deixar o card ocupar 4/12 e o form ocupar 8/12.

    São três alterações necessárias:

    • Criar uma <div> com classe row dentro do container;
    • Criar uma <div> com classe col-md-4 ao redor do cartão;
    • Aplicar a classe col-md-8 no formulário.

      Faça essas alterações e cuidado com o resultado final e os milhões de divs misturados. O código deve ficar mais ou menos assim:

      <div class="container">
        <div class="row">
      
            <div class="col-md-4">
                <div class="card mb-3">
                    <!-- ... cartão todo aqui ... -->
                </div>
            </div>
      
            <form class="col-md-8">
                <!-- ... todos os campos aqui ... -->
            </form>
      
        </div> <!-- fim .row -->
      </div> <!-- fim .container -->
      

      Teste a página e redimensione para um tamanho em torno de 768px pra ver o resultado.

  2. Repare que o Bootstrap ajusta várias coisas responsivamente pra gente de maneira automática. Além de aplicar as classes do grid, repare como os tamanhos e fontes aumentam de acordo com a resolução, sem precisarmos fazer nada.

    Faça os testes.

  3. Quando aumentamos bastante a tela, tudo ainda se ajusta na proporção de 4 pra 8 que definimos. Mas o formulário fica grande demais. Em telas maiores, talvez seja legal deixar o formulário em 2 colunas.

    Vamos usar outras classes do grid do Bootstrap que se aplicam em layouts maiores que 992px. Vamos dividir o formulário em 2 partes iguais, ou seja 6/12 (lembre que o grid do Bootstrap tem 12 partes como base). Conseguimos isso tudo usando a classe col-lg-6.

    As mudanças necessárias são:

    • Crie uma <div> com classe row ao redor dos 2 fieldsets;
    • Aplique a classe col-lg-6 em cada um dos fieldsets.

      No final, a estrutura deve estar parecida com essa:

      <form ...>
        <div class="row">
            <fieldset class="col-lg-6">
                ...
            </fieldset>
            <fieldset class="col-lg-6">
                ...
            </fieldset>
        </div>
        <button ...>
      </form>
      

      Teste a página e redimensione para um tamanho em torno de 992px pra ver o resultado.

  4. (opcional) É possível usar mais de uma classe de grid ao mesmo tempo no mesmo elemento. Por exemplo: dividimos a tela em 4/12 para o cartão e 8/12 para o formulário. Mas se, em telas maiores, você quiser mudar essa proporção para 3/12 e 9/12, basta adicionar as classes col-xl-3 e col-xl-9 em conjunto as que tínhamos antes.

    Implemente essa mudança no projeto.

    Exemplo:

     <div class="col-md-4 col-xl-3">
         ...
     <form class="col-md-8 col-xl-9">
    

    A série col-xl- aplica em resoluções acima de 1200px.

    Para saber mais sobre os grids do Bootstrap: https://getbootstrap.com/docs/4.1/layout/grid/

  5. (opcional) Além de alterar o grid nas diferentes resoluções, o Bootstrap também permite esconder/exibir certos elementos apenas em uma resolução específica.

    Por exemplo: imagine que, para otimizar o espaço pequeno no design para smartphone, vamos esconder a imagem do produto. Podemos fazer isso adicionando as classes d-none e d-sm-block na <img>.

    A classe d-none esconde o elemento independente da resolução da tela. E a classe d-sm-block faz com que o elemento apareça em telas com resoluções maiores que 576px.

    Para saber mais sobre as classes auxiliares para responsivo do Bootstrap: https://getbootstrap.com/docs/4.1/extend/approach/#responsive

Editora Casa do Código com livros de uma forma diferente

Editoras tradicionais pouco ligam para ebooks e novas tecnologias. Não dominam tecnicamente o assunto para revisar os livros a fundo. Não têm anos de experiência em didáticas com cursos.
Conheça a Casa do Código, uma editora diferente, com curadoria da Caelum e obsessão por livros de qualidade a preços justos.

Casa do Código, ebook com preço de ebook.

8.14 Para saber mais: componentes JS do Bootstrap

Além de componentes CSS puro do Bootstrap como card e jumbotron, temos outros componentes mais avançados que envolvem interatividade e JavaScript.

Há muita coisa disponível por padrão no Bootstrap, pelo menos os componentes mais comuns como janela modal, galeria de imagens, dropdowns, menus de navegação e mais.

https://getbootstrap.com/docs/4.1/getting-started/javascript/

No exercício, vamos usar o menu superior (navbar).

8.15 Exercícios opcionais: navbar e JavaScript

  1. Um componente muito famoso do Bootstrap é seu menu superior, chamado de navbar. O HTML é um pouco mais complexo pois se trata de um menu completo, mas é relativamente fácil.

    Implemente um navbar em nossa página acima do jumbotron, logo no topo da página:

     <nav class="navbar navbar-expand-lg navbar-light bg-light">
       <a class="navbar-brand" href="index.html">Mirror Fashion</a>
    
         <ul class="navbar-nav">
             <li class="nav-item active">
                 <a class="nav-link" href="sobre.html">Sobre</a>
             </li>
         <li class="nav-item">
                 <a class="nav-link" href="#">Ajuda</a>
             </li>
         <li class="nav-item">
                 <a class="nav-link" href="#">Perguntas frequentes</a>
             </li>
         <li class="nav-item">
                 <a class="nav-link" href="#">Entre em contato</a>
             </li>
         </ul>
     </nav>
    

    Teste o resultado no navegador.

  2. Teste o menu em resoluções menores. Note que o Bootstrap ajusta automaticamente o navbar em telas menores. Por padrão, o comportamento é mudar o menu de horizontal para vertical em mobile.

    Veja esse comportamento redimensionando o browser.

  3. Uma outra solução para menus em telas pequenas é de juntar as opções em uma espécie de dropdown que só abre quando ativado. Isso é, criar um botão para ativar o menu (geralmente com o famoso ícone do sanduíche).

    É bem simples fazer isso com Bootstrap, a funcionalidade está toda pronta.

    Para fazer o menu colapsar em telas pequenas, basta adicionar uma <div> nova em volta do <ul> e 2 classes nessa <div>: a collapse e a navbar-collapse.

     <div class="collapse navbar-collapse">
         <ul class="navbar-nav">
             ...
         </ul>
     </div>
    

    Se você testar agora, vai notar que o menu some nas telas menores. Para exibi-lo, precisamos fazer o próximo passo: criar o ícone que ativa o menu.

    Dentro do navbar, logo acima do <a>, crie um botão de ativação. Dentro do botão crie um <span> com a classe navbar-toggler-icon. Esse <span> será o nosso ícone hamburguer.

    Para fazer a ligação entre o botão que vamos usar para collapsar a nossa <div> e a botão em si, use um id na <div>. No caso usamos um id navbarToggleExternalContent na <div> e um data-target="#navbarToggleExternalContent" no button, para indicar que esse button aponta para o id navbarToggleExternalContent.

     <nav class="navbar navbar-expand-lg navbar-light bg-light">
       <button class="navbar-toggler" type="button"
                         data-toggle="collapse" data-target="#navbarToggleExternalContent">
         <span class="navbar-toggler-icon"></span>
       </button>
       <a class="navbar-brand" href="index.html">Mirror Fashion</a>
    
       <div class="collapse navbar-collapse" id="navbarToggleExternalContent">
         <ul class="navbar-nav">
           <li class="nav-item active">
                     <a class="nav-link" href="sobre.html">Sobre</a>
                 </li>
           <li class="nav-item">
                     <a class="nav-link" href="#">Ajuda</a>
                 </li>
           <li class="nav-item">
                     <a class="nav-link" href="#">Perguntas frequentes</a>
                 </li>
           <li class="nav-item">
                     <a class="nav-link" href="#">Entre em contato</a>
                 </li>
         </ul>
       </div>
     </nav>
    

    Se testar agora, vai notar que o menu aparece mas não funciona quando clicado. É porque essa funcionalidade no Bootstrap é implementada com JavaScript. A boa notícia é que não precisamos escrever uma linha de código JS sequer, mas para tudo funcionar precisamos adicionar o JavaScript do Bootstrap.

    No fim da página, logo antes de fechar o </body>, chame o arquivo do Bootstrap e do jQuery:

     <script type="text/javascript" src="js/jquery.js"></script>
     <script type="text/javascript" src="js/bootstrap.js"></script>
    

    Teste novamente e veja o plugin funcionando. Usamos o JavaScript do Bootstrap implicitamente.

    Atributos customizados no HTML5

    Até a versão 4 do HTML, não havia uma forma padronizada de colocar atributos customizados.

    A partir do HTML5, atributos começando com data- em qualquer tag são considerados atributos customizados e não quebram a validade do nosso código HTML. Esses atributos são bastante úteis para passar informação para um código JavaScript, como fizemos agora, passando informação para o código do Bootstrap.

  4. Há muitas opções possíveis para o navbar. Por exemplo, podemos inverter as cores e usar um esquema mais escuro apenas trocando as classes navbar-light e bg-light pelas classes navbar-dark e bg-dark.

    Para saber mais sobre o navbar: https://getbootstrap.com/docs/4.1/components/navbar/

  5. Adicione a classe fixed-top dentro da tag <nav>. Repare que o menu fica fixo no topo mesmo com scroll.

    Você talvez queira aplicar um padding-top no body pro conteúdo não ficar por baixo do navbar:

     body {
         padding-top: 55px;
     }
    

8.16 Para saber mais: outros frameworks CSS

O Bootstrap não é o único framework CSS do mercado. É talvez o mais famoso e com mais usuários, mas há muitas outras opções que às vezes podem ser até melhores para seu caso.

Três opções famosas:

De maneira geral, esses frameworks permitem fazer as mesmas coisas, mas cada um com seu estilo. Um botão principal por exemplo:

<!-- Bootstrap -->
<button class="btn btn-primary btn-lg">Clique aqui</button>

<!-- Foundation -->
<button class="large button">Clique aqui</button>

<!-- Semantic UI -->
<button class="large ui button">Clique aqui</button>

<!-- Pure -->
<button class="pure-button pure-button-primary pure-button-large">
    Clique aqui
</button>

Já conhece os cursos online Alura?

A Alura oferece centenas de cursos online em sua plataforma exclusiva de ensino que favorece o aprendizado com a qualidade reconhecida da Caelum. Você pode escolher um curso nas áreas de Programação, Front-end, Mobile, Design & UX, Infra e Business, com um plano que dá acesso a todos os cursos. Ex aluno da Caelum tem 15% de desconto neste link!

Conheça os cursos online Alura.