Você está na página 1de 222

Machine Translated by Google

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

HTML5: instalado e funcionando

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

HTML5: instalado e funcionando

Marco Peregrino

Pequim Cambridge Farnham Colônia Sebastopol Taipei Tóquio

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

HTML5: instalado e
funcionando por Mark Pilgrim

Copyright © 2010 Mark Pilgrim. Todos os direitos reservados.


Impresso nos Estados Unidos da América.

Publicado por O'Reilly Media, Inc., 1005 Gravenstein Highway North, Sebastopol, CA 95472.

Os livros da O'Reilly podem ser adquiridos para uso educacional, comercial ou promocional de vendas. Edições online
também estão disponíveis para a maioria dos títulos (http:// my.safaribooksonline.com). Para mais informações, entre em
contato com nosso departamento de vendas corporativas/institucionais: (800) 998-9938 ou corporate@oreilly.com.

Editor: Mike Loukides Indexador: Fred Brown


Editor de Produção: Adam Zaremba Designer da capa: Karen Montgomery
Editora: Rachel Head Designer de Interiores: David Futato
Revisora: Emily Quill Ilustrador: Roberto Romano

Histórico de impressão:
Agosto de 2010: Primeira edição.

Nutshell Handbook, o logotipo Nutshell Handbook e o logotipo O'Reilly são marcas registradas da O'Reilly Media, Inc.
HTML5: Up and Running, a imagem de uma camurça alpina e imagem comercial relacionada são marcas registradas da
O'Reilly Media, Inc.

Muitas das designações utilizadas pelos fabricantes e vendedores para distinguir os seus produtos são reivindicadas como
marcas comerciais. Onde essas designações aparecem neste livro, e a O'Reilly Media, Inc. estava ciente de uma
reivindicação de marca registrada, as designações foram impressas em letras maiúsculas ou iniciais.

Embora todas as precauções tenham sido tomadas na preparação deste livro, o editor e o autor não assumem nenhuma
responsabilidade por erros ou omissões, ou por danos resultantes do uso das informações aqui contidas.

MT

Este livro usa RepKover™, uma encadernação plana durável e flexível.

ISBN: 978-0-596-80602-6

[M]

1281030545

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Índice

Prefácio. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ix

1. Como chegamos aqui? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1


Mergulhando 1
nos tipos MIME 1
Uma longa digressão sobre como os padrões são criados Uma 2
linha ininterrupta Uma 7
linha do tempo de desenvolvimento HTML de 1997 a 2004 Tudo o 9
que você sabe sobre XHTML está errado Uma visão 10
competitiva Qual grupo 11
de trabalho? 12
De volta ao W3C 13
Pós-escrito 14
Leitura adicional 14

2. Detectando recursos HTML5. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15


Mergulhando 15
Técnicas de detecção 15
Modernizr: uma biblioteca de detecção HTML5 16
Tela 16
Texto em tela 17
Vídeo 18
Formatos de vídeo 19
Armazenamento local 21
Trabalhadores da Web 23
Aplicativos da Web off-line 23
Geolocalização 24
Tipos de entrada 25
Texto de espaço reservado 27
Foco automático de formulário 27
Microdados 28

em

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Leitura adicional 29

3. O que tudo isso significa? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31


Mergulhando 31
O tipo de documento 31
O elemento raiz 33
O elemento <head> 34
Codificação de caracteres 35
Amigos e relacionamentos (link) 36
Novos elementos semânticos em HTML5 41
Uma longa digressão sobre como os navegadores lidam com elementos desconhecidos 42
Cabeçalhos 45
Artigos 47
Datas e horários 49
Navegação 51
Rodapés 52
Leitura adicional 54

4. Vamos chamá-lo de superfície de desenho. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57


Mergulhando 57
em formas simples 58
Coordenadas da tela 60
61
63
Caminhos 67
Texto 70
Gradientes Imagens E quanto ao IE? 73
Um exemplo completo de 75
leitura adicional 79

5. Vídeo na Web. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
Mergulhando 81
em contêineres de 81
vídeo Codecs de 83
vídeo 84
Codecs 84
de 85
áudio H.264 85
Theora VP8 MPEG-1 Audio 86
Layer 3 Codificação de áudio 87
87
avançada Vorbis O que funciona 88
na Web Problemas de licenciamento com vídeo H.264 90

vi | Índice

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Codificação de vídeo Ogg com Firefogg 91


Codificação em lote Vídeo Ogg com ffmpeg2theora Codificação 98
de vídeo H.264 com HandBrake Codificação em 100
lote Vídeo H.264 com HandBrake Codificação de vídeo 107
WebM com ffmpeg Finalmente, os tipos MIME 108
de marcação levantam 110
sua cabeça feia E quanto ao IE? 113
114
Um exemplo completo de 114
leitura adicional 115

6. Você está aqui (e todos os outros também). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117


Mergulhando 117
na API de geolocalização 117
Mostre-me as opções de 118
tratamento de erros 120
de código! Eu exijo escolhas! 121
E quanto ao IE? 123
geo.js para o resgate Um 123
exemplo completo Leitura 125
adicional 126

7. O passado, o presente e o futuro do armazenamento local para aplicativos da Web. . . . . . . 127


...
Mergulhando 127
Uma breve história de hacks de armazenamento local antes do HTML5 128
Apresentando o armazenamento HTML5 129
Usando armazenamento HTML5 130
Rastreando alterações na área de armazenamento HTML5 131
Limitações nos navegadores atuais 132
Armazenamento HTML5 em ação 132
Além dos pares chave/valor nomeados: visões concorrentes 134
Leitura adicional 135

8. Vamos colocar isso off-line. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137


Mergulhando 137
O Manifesto de Cache 138
Seções de rede 139
Seções substitutas 140
O Fluxo de Eventos A 141
Bela Arte da Depuração, também conhecida como “Kill Me! Me mate agora!" 142
Vamos construir um! 145
Leitura adicional 146

Índice | vii

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

9. Uma forma de loucura. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147

Mergulhando 147
Texto de espaço reservado 147
Campos de foco automático 148
Endereço de e-mail 150
Endereços da Web 151

Números como caixas giratórias 153


Números como controles 155
deslizantes, 156
selecionadores de 158
data, caixas de 160

pesquisa, selecionadores de cores e mais uma coisa... 160

Leitura adicional 161

10. “Distribuído”, “Extensibilidade” e outras palavras sofisticadas. . . . . . . . . . . . . . . . . . . . . . . 163


Mergulhando 163
no que são microdados? 164
O modelo de dados de microdados 165

Marcando pessoas 168

Apresentando os Rich Snippets do Google 174

Marcando organizações Marcando 176

eventos O retorno dos 180

Rich Snippets do Google Marcando comentários 184

Leitura adicional 185


189

Apêndice: O guia quase alfabético completo para detectar tudo . . . . . . . . 191

Índice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201

viii | Índice

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Prefácio

Mergulhando

O que é HTML5? HTML5 é a próxima geração de HTML, substituindo HTML 4.01, XHTML 1.0 e
XHTML 1.1. HTML5 fornece novos recursos necessários para aplicativos da web modernos. Ele
também padroniza muitos recursos da plataforma web que os desenvolvedores web usam há anos,
mas que nunca foram examinados ou documentados por um comitê de padrões. (Você ficaria
surpreso ao saber que o objeto Window nunca foi formalmente documentado? Além dos novos
recursos, o HTML5 é a primeira tentativa de documentar formalmente muitos dos padrões “de fato”
que os navegadores da Web suportam há anos.)

Assim como seus antecessores, o HTML5 foi projetado para ser multiplataforma. Você não precisa
executar Windows ou Mac OS X ou Linux ou Multics ou qualquer sistema operacional específico
para aproveitar as vantagens do HTML5. A única coisa que você precisa é de um navegador
moderno. Existem navegadores modernos disponíveis gratuitamente para todos os principais
sistemas operacionais. Talvez você já tenha um navegador da Web compatível com determinados recursos do HTML5.
As versões mais recentes do Apple Safari, Google Chrome, Mozilla Firefox e Opera suportam muitos
recursos HTML5. (Você encontrará tabelas mais detalhadas de compatibilidade de navegadores ao
longo deste livro.) Todos os navegadores móveis pré-instalados em iPhones, iPads e telefones
Android têm excelente suporte para HTML5. Até a Microsoft anunciou que a próxima versão 9 do
Internet Explorer suportará algumas funcionalidades do HTML5.

Este livro se concentrará em oito tópicos:

• Novos elementos semânticos como <header>, <footer> e <section> (Capítulo 3) • Canvas,


uma superfície de desenho bidimensional que você pode programar com JavaScript
(Capítulo 4)
• Vídeo que você pode incorporar em suas páginas da web sem recorrer a plug-ins de terceiros
ins (Capítulo 5)
• Geolocalização, onde os visitantes podem optar por compartilhar suas localizações físicas com
seu aplicativo web (Capítulo 6) •
Armazenamento local persistente sem recorrer a plug-ins de terceiros (Capítulo 7)

ix

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

• Aplicativos web off-line que funcionam mesmo após a interrupção do acesso à rede
(Capítulo 8) •

Melhorias nos formulários web HTML (Capítulo 9) • Microdados

que permitem criar seus próprios vocabulários além do HTML5 e estender suas páginas web com
semântica personalizada (Capítulo 10)

O HTML5 foi projetado, tanto quanto possível, para ser compatível com versões anteriores dos navegadores
da web existentes. Novos recursos baseiam-se em recursos existentes e permitem fornecer conteúdo
substituto para navegadores mais antigos. Se precisar de um controle ainda maior, você pode detectar
suporte para recursos HTML5 individuais (Capítulo 2) usando algumas linhas de JavaScript. Não confie na
detecção frágil de navegadores para decidir quais navegadores suportam HTML5! Em vez disso, teste os
recursos necessários usando o próprio HTML5.

Convenções utilizadas neste livro

As seguintes convenções tipográficas são usadas neste livro:

Itálico
Indica novos termos, URLs, endereços de e-mail, nomes de arquivos e extensões de arquivos.
Largura constante

Usado para listagens de programas, bem como dentro de parágrafos para se referir a elementos de
programas, como nomes de variáveis ou funções, bancos de dados, tipos de dados, variáveis de
ambiente, instruções e palavras-chave.
Largura constante negrito
Mostra comandos ou outro texto que deve ser digitado literalmente pelo usuário.
Largura constante em itálico

Mostra o texto que deve ser substituído por valores fornecidos pelo usuário ou por valores
determinados pelo contexto.

Este ícone significa uma dica, sugestão ou nota geral.

Este ícone indica um aviso ou cuidado.

x | Prefácio

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Usando exemplos de código

Este livro está aqui para ajudá-lo a realizar seu trabalho. Em geral, você pode usar o código deste livro em
seus programas e documentação. Você não precisa entrar em contato conosco para obter permissão, a
menos que esteja reproduzindo uma parte significativa do código. Por exemplo, escrever um programa
que utilize vários trechos de código deste livro não requer permissão. Vender ou distribuir um CD-ROM
com exemplos de livros da O'Reilly requer permissão. Responder a uma pergunta citando este livro e
citando código de exemplo não requer permissão. Incorporar uma quantidade significativa de código de
exemplo deste livro na documentação do seu produto requer permissão.

Agradecemos, mas não exigimos, atribuição. Uma atribuição geralmente inclui título, autor, editora e ISBN.
Por exemplo: “HTML5: instalado e funcionando por Mark Pilgrim.
Copyright 2010 O'Reilly Media, Inc., 978-0-596-80602-6.”

Se você acha que o uso de exemplos de código está fora do uso justo ou da permissão dada acima, sinta-
se à vontade para nos contatar em permissions@oreilly.com.

Uma nota sobre as edições deste livro

Este livro é derivado de sua fonte HTML5, encontrada em http://diveintohtml5.org/ e mantida pelo autor.
As edições do e-book e do Safari Books Online incluem todos os hiperlinks originais, enquanto a edição
impressa inclui apenas um subconjunto dos hiperlinks, definidos como URLs entre parênteses. Se você
estiver lendo a edição impressa, consulte uma das outras edições – ou a fonte original – para uma
experiência de vinculação mais rica. Como o autor mantém http://diveintohtml5.org/ em HTML5, o site
inclui exemplos dinâmicos do código descrito neste livro, muitos dos quais tiveram que ser modificados
para publicação.
Visite http://diveintohtml5.org/ para ver esses exemplos, mas esteja ciente de que sua renderização pode
variar entre os navegadores.

Livros on-line do Safari®

Safari Books Online é uma biblioteca digital sob demanda que permite pesquisar facilmente
mais de 7.500 livros e vídeos de referência de tecnologia e criativos para encontrar
rapidamente as respostas que você precisa.

Com uma assinatura, você pode ler qualquer página e assistir a qualquer vídeo de nossa biblioteca online.
Leia livros em seu celular e dispositivos móveis. Acesse novos títulos antes que estejam disponíveis para
impressão e tenha acesso exclusivo aos manuscritos em desenvolvimento e poste feedback para os
autores. Copie e cole exemplos de código, organize seus favoritos, baixe capítulos, marque seções
principais, crie notas, imprima páginas e aproveite vários outros recursos que economizam tempo.

Prefácio | XI

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

A O'Reilly Media carregou este livro no serviço Safari Books Online. Para ter acesso digital completo a este livro
e outros sobre temas semelhantes da O'Reilly e de outros editores, inscreva-se gratuitamente em http://
my.safaribooksonline.com.

Como entrar em contato conosco

Por favor, envie comentários e perguntas sobre este livro à editora: O'Reilly Media, Inc.

1005 Gravenstein Highway North Sebastopol,


CA 95472 800-998-9938 (nos
Estados Unidos ou Canadá) 707-829-0515 (internacional ou
local) 707-829-0104 (fax)

Temos uma página web para este livro, onde listamos erratas, exemplos e qualquer informação adicional. Você
pode acessar esta página em:

http://oreilly.com/catalog/9780596806026/ Para

comentar ou tirar dúvidas técnicas sobre este livro, envie e-mail para: bookquestions@oreilly.com

Para obter mais informações sobre nossos livros, conferências, Centros de Recursos e a Rede O'Reilly, consulte
nosso website em: http://www.oreilly.com

xii | Prefácio

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

CAPÍTULO 1

Como chegamos aqui?

Mergulhando

Recentemente, me deparei com uma citação de um desenvolvedor da Mozilla sobre a tensão


inerente à criação de padrões:

Implementações e especificações precisam fazer uma dança delicada juntas. Você não quer
que as implementações aconteçam antes da conclusão da especificação, porque as pessoas
começam a depender dos detalhes das implementações e isso restringe a especificação. No
entanto, você também não quer que a especificação seja concluída antes que haja
implementações e experiência do autor com essas implementações, porque você precisa do feedback.
Há uma tensão inevitável aqui, mas só temos que seguir em frente.
Mantenha esta citação em mente e deixe-me explicar como o HTML5 surgiu.

Tipos MIME

Este livro é sobre HTML5, não sobre versões anteriores de HTML e não sobre qualquer versão de
XHTML. Mas para entender a história do HTML5 e as motivações por trás dele, você precisa
primeiro entender alguns detalhes técnicos. Especificamente, tipos MIME.

Cada vez que seu navegador solicita uma página, o servidor web envia vários cabeçalhos antes de
enviar a marcação real da página. Esses cabeçalhos normalmente são invisíveis, embora existam
várias ferramentas de desenvolvimento web que os tornarão visíveis se você estiver interessado.
Os cabeçalhos são importantes porque informam ao navegador como interpretar a marcação da
página a seguir. O cabeçalho mais importante é chamado Content-Type e tem a seguinte aparência:

Tipo de conteúdo: texto/html

text/html é chamado de “tipo de conteúdo” ou “tipo MIME” da página. Este cabeçalho é a única
coisa que determina o que realmente é um recurso específico e, portanto, como ele deve ser
renderizado. As imagens têm seus próprios tipos MIME (image/jpeg para imagens JPEG, image/
png para imagens PNG e assim por diante). Os arquivos JavaScript têm seu próprio tipo MIME. CSS

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

folhas de estilo têm seu próprio tipo MIME. Tudo tem seu próprio tipo MIME. A Web funciona em tipos
MIME.

Claro, a realidade é mais complicada do que isso. Os primeiros servidores web (estou falando de
servidores web de 1993) não enviavam o cabeçalho Content-Type , porque ele ainda não existia.
(Ele não foi inventado até 1994.) Por motivos de compatibilidade que datam de 1993, alguns navegadores
populares irão ignorar o cabeçalho Content-Type sob certas circunstâncias. (Isso é chamado de “sniffing
de conteúdo”.) Mas, como regra geral, tudo o que você já viu na Web – páginas HTML, imagens, scripts,
vídeos, PDFs, qualquer coisa com URL – foi servido para você com um tipo MIME específico no cabeçalho
Content-Type .

Coloque isso debaixo do seu chapéu. Voltaremos a isso.

Uma longa digressão sobre como os padrões são feitos


Por que temos um elemento <img> ? Não creio que essa seja uma pergunta que você se faça com
frequência. Obviamente alguém deve ter criado isso. Essas coisas não aparecem do nada. Cada elemento,
cada atributo, cada recurso do HTML que você já usou — alguém os criou, decidiu como deveriam
funcionar e escreveu tudo.
Essas pessoas não são deuses, nem são perfeitas. Eles são apenas pessoas. Pessoas inteligentes, com
certeza. Mas apenas pessoas.

Uma das grandes vantagens dos padrões desenvolvidos “aberto” é que você pode voltar no tempo e
responder a esse tipo de pergunta. As discussões ocorrem em listas de discussão, que geralmente são
arquivadas e podem ser pesquisadas publicamente. Então, decidi fazer um pouco de “arqueologia de e-
mail” para tentar responder à questão do elemento <img> . Tive que voltar antes de existir uma organização
chamada World Wide Web Consortium (W3C).
Voltei aos primórdios da Web, quando era possível contar o número de servidores Web nos dedos de
ambas as mãos, e talvez em alguns dedos dos pés.

Em 25 de fevereiro de 1993, Marc Andreessen escreveu:*

Gostaria de propor uma nova tag HTML opcional:


imagem

O argumento obrigatório é SRC="url".

Isso nomeia um arquivo bitmap ou pixmap para o navegador tentar puxar pela rede e interpretar como uma
imagem, para ser incorporada ao texto no ponto de ocorrência da tag.

Um exemplo é:

<IMG SRC="file://foobar.com/foo/bar/blargh.xbm">
(Não há tag de fechamento; esta é apenas uma tag independente.)

* http:// 1997.webhistory.org/ www.lists/ www-talk.1993q1/0182.html. O tópico descrito nas próximas


páginas pode ser seguido clicando nos links “Próxima mensagem” e “Mensagem anterior”.

2 | Capítulo 1: Como chegamos aqui?

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Esta tag pode ser incorporada em uma âncora como qualquer outra; quando isso acontece, ele se
torna um ícone sensível à ativação, assim como uma âncora de texto normal.

Os navegadores devem ter flexibilidade quanto aos formatos de imagem que suportam. Xbm e Xpm
são bons para suporte, por exemplo. Se um navegador não puder interpretar um determinado
formato, ele poderá fazer o que quiser (o X Mosaic exibirá um bitmap padrão como espaço
reservado).

Esta é uma funcionalidade necessária para o X Mosaic; temos isso funcionando e pelo menos
usaremos internamente. Certamente estou aberto a sugestões sobre como isso deve ser tratado no
HTML; se você tiver uma ideia melhor do que a que estou apresentando agora, por favor me avise.
Sei que isso é confuso em relação ao formato da imagem, mas não vejo alternativa a não ser
apenas dizer “deixe o navegador fazer o que pode” e esperar que apareça a solução perfeita (MIME,
algum dia, talvez).

Esta citação requer alguma explicação. Xbm e Xpm eram formatos gráficos populares em sistemas Unix.

“Mosaic” foi um dos primeiros navegadores da web. (“X Mosaic” era a versão executada em sistemas Unix.)
Quando escreveu esta mensagem no início de 1993, Marc ainda não havia fundado a empresa que o tornou
famoso, a Mosaic Communications Corporation, nem havia começado a trabalhar no principal produto dessa
empresa. , “Mosaico Netscape”. (Você pode conhecê-los melhor pelos seus nomes posteriores, “Netscape
Corporation” e “Netscape Navigator”.)

“MIME, algum dia, talvez” é uma referência à negociação de conteúdo, um recurso do HTTP onde um cliente
(como um navegador da web) informa ao servidor (como um servidor da web) quais tipos de recursos ele
suporta (como imagem/jpeg) para que o o servidor pode retornar algo no formato preferido do cliente. “O HTTP
original conforme definido em 1991” (a única versão implementada em fevereiro de 1993) não tinha como os
clientes informarem aos servidores quais tipos de imagens eles suportavam, daí o dilema de design que Marc
enfrentou.

Algumas horas depois, Tony Johnson respondeu:

Eu tenho algo muito semelhante no Midas 2.0 (em uso aqui no SLAC, e com lançamento público
previsto para qualquer semana), exceto que todos os nomes são diferentes e tem um argumento
extra NAME="name". Tem quase exatamente a mesma funcionalidade da tag IMG proposta. por

exemplo, <ICON name="NoEntry" href="http://note/foo/bar/NoEntry.xbm">

A ideia do parâmetro name era permitir que o navegador tivesse um conjunto de imagens
“integradas”. Se o nome corresponder a uma imagem “integrada”, ele a usaria em vez de ter que
sair e buscar a imagem. O nome também pode servir como uma dica para navegadores de “modo
linha” sobre que tipo de símbolo colocar no lugar da imagem.

Não me importo muito com os nomes dos parâmetros ou tags, mas seria sensato se usássemos
as mesmas coisas. Não ligo muito para abreviações, ou seja, por que não IMAGE= e SOURCE=.
Eu prefiro um pouco o ÍCONE, pois implica que a IMAGEM deve ser pequena, mas talvez o ÍCONE
seja uma palavra sobrecarregada?

Midas foi outro dos primeiros navegadores, contemporâneo do X Mosaic. Era multiplataforma; ele rodava em
Unix e VMS. “SLAC” refere-se ao Stanford Linear Accelerator Center, agora SLAC National Accelerator
Laboratory, que sediou o

Uma longa digressão sobre como os padrões são feitos | 3

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

primeiro servidor web nos Estados Unidos (na verdade, o primeiro servidor web fora da Europa). Quando
Tony escreveu esta mensagem, o SLAC era um veterano na WWW, tendo hospedado cinco páginas
em seu servidor web por impressionantes 441 dias.

Tony continuou:

Enquanto estamos no assunto de novas tags, tenho outra tag, um tanto semelhante, que gostaria de oferecer
suporte no Midas 2.0. Em princípio é:

<INCLUIR HREF="...">
A intenção aqui seria que o segundo documento fosse incluído no primeiro documento no local onde ocorreu a
etiqueta. Em princípio o documento referenciado poderia ser qualquer coisa, mas o objetivo principal era permitir
que imagens (neste caso de tamanho arbitrário) fossem incorporadas aos documentos. Novamente, a intenção
seria que, quando o HTTP2 aparecesse, o formato do documento incluído fosse negociado separadamente.

“HTTP2” é uma referência ao HTTP Básico conforme definido em 1992. Neste ponto, no início de 1993,
ainda estava em grande parte não implementado. O rascunho conhecido como “HTTP2” evoluiu e
acabou sendo padronizado como “HTTP 1.0”. O HTTP 1.0 incluía cabeçalhos de solicitação para
negociação de conteúdo, também conhecido como “MIME, algum dia, talvez”.

Tony continuou:

Uma alternativa que eu estava considerando

era: <A HREF="..." INCLUDE>Ver foto</A> Não

gosto muito de adicionar mais funcionalidades à tag <A> , mas a ideia aqui é manter a compatibilidade com os
navegadores que não pode respeitar o parâmetro INCLUDE . A intenção é que os navegadores que entendem
INCLUDE substituam o texto âncora (neste caso “Ver foto”) pelo documento incluído (imagem), enquanto
navegadores mais antigos ou mais burros ignorem completamente a tag INCLUDE .

Esta proposta nunca foi implementada, embora a ideia de fornecer texto caso falte uma imagem seja
uma importante técnica de acessibilidade isso estava faltando na proposta inicial de Marc <IMG> .
Muitos anos depois, esse recurso foi implementado como o <img alt> atributo, que o Netscape
prontamente quebrou ao tratá-lo erroneamente como uma dica de ferramenta.

Poucas horas depois de Tony postar sua mensagem, Tim Berners-Lee respondeu:

Eu imaginava que as figuras seriam representadas como <a

name=fig1 href="fghjkdfghj" REL="EMBED, PRESENT">Figura </a>

onde os valores de relacionamento significam


EMBUTIR Incorpore isso aqui ao apresentá-lo
PRESENT Apresenta sempre que o documento fonte é apresentado

Observe que você pode ter várias combinações destes e, se o navegador não suportar nenhum deles, ele não
falha.

[Eu] vejo que usar isso como um método para ícones selecionáveis significa aninhar âncoras. Hmmm.
Mas eu não queria uma etiqueta especial.

4 | Capítulo 1: Como chegamos aqui?

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Esta proposta nunca foi implementada, mas o atributo rel ainda existe (veja “Amigos e Relações (Link)” na página 36).

Jim Davis acrescentou:

Seria bom se houvesse uma maneira de especificar o tipo de conteúdo, por exemplo

<IMG HREF="http://nsa.gov/pub/sounds/gorby.au" CONTENT-TYPE=audio/basic> Mas

estou totalmente disposto a aceitar a exigência de especificar o tipo de conteúdo por extensão de
arquivo.

Esta proposta nunca foi implementada, mas a Netscape adicionou posteriormente suporte para incorporação arbitrária de
objetos de mídia com o elemento <embed> .

Jay C. Weber perguntou:

Embora as imagens estejam no topo da minha lista de tipos de mídia desejados em um navegador
WWW, não acho que devamos adicionar ganchos idiossincráticos para a mídia, um de cada vez. O
que aconteceu com o entusiasmo pelo uso do mecanismo de digitação MIME?

Marc Andreessen respondeu:

Isto não substitui o futuro uso do MIME como mecanismo de documento padrão; isso fornece uma
implementação necessária e simples de funcionalidades independentemente do MIME.

Jay C. Weber respondeu:

Vamos esquecer temporariamente o MIME, se isso atrapalhar o problema. A minha objecção foi à
discussão de “como vamos apoiar imagens incorporadas” em vez de “como vamos apoiar objecções
incorporadas em vários meios de comunicação”.

Caso contrário, na próxima semana alguém irá sugerir “vamos colocar uma nova tag <AUD SRC="file://
foobar.com/foo/bar/blargh.snd">” para áudio.

Não deveria haver muito custo em optar por algo que generaliza.

Olhando retrospectivamente, parece que as preocupações de Jay eram bem fundamentadas. Demorou um pouco mais de
uma semana, mas o HTML5 finalmente adicionou um novo <video> e <áudio> elementos.

Respondendo à mensagem original de Jay, Dave Raggett disse: É verdade!

Quero considerar toda uma gama de possíveis tipos de imagem/arte de linha, juntamente com a possibilidade
de negociação de formato. A observação de Tim sobre o suporte a áreas clicáveis nas imagens também é
importante.

Mais tarde, em 1993, Dave HTML+ proposto como uma evolução do padrão HTML. A proposta nunca foi implementada e
foi substituída pelo HTML 2.0. HTML 2.0 era uma “especificação retro”, o que significa que formalizava recursos já de uso
comum: “Esta especificação reúne, esclarece e formaliza um conjunto de recursos isso corresponde aproximadamente às
capacidades do HTML de uso comum antes de junho de 1994.”

Uma longa digressão sobre como os padrões são feitos | 5

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Mais tarde, Dave escreveu HTML 3.0, baseado em seu rascunho HTML+ anterior. Fora da implementação
de referência do próprio W3C, Arena, HTML 3.0 nunca foi implementado. Foi substituído pelo HTML
3.2, que também era uma “especificação retro”: “HTML 3.2 adiciona recursos amplamente implantados
como tabelas, miniaplicativos e fluxo de texto em torno de imagens, ao mesmo tempo que fornece
compatibilidade retroativa total com o padrão existente HTML 2.0.

Mais tarde, Dave foi coautor do HTML 4.0, desenvolveu HTML Tidy, e passou a ajudar com XHTML,
XForms, MathML e outras especificações modernas do W3C.

Voltando a 1993, Marc respondeu a Dave:

Na verdade, talvez devêssemos pensar em uma linguagem gráfica processual de uso geral, na qual
possamos incorporar hiperlinks arbitrários anexados a ícones, imagens, texto ou qualquer coisa.
Alguém mais viu as capacidades da Intermedia em relação a isso?

Intermediário foi um projeto de hipertexto da Brown University. Foi desenvolvido de 1985 a 1991 e
funcionou em A/UX, um sistema operacional semelhante ao Unix para os primeiros computadores Macintosh.

A ideia de uma “linguagem gráfica processual de uso geral” acabou pegando.


Os navegadores modernos suportam SVG (marcação declarativa com script incorporado) e <canvas>
(uma API gráfica de modo direto processual), embora esta última tenha começado como uma extensão
proprietária antes de ser “especificado retroativamente” pelo Grupo de Trabalho O QUE.

Bill Janssen respondeu:

Outros sistemas que possuem essa noção (bastante valiosa) são Andrew e Slate.
Andrew é construído com _insets_, cada um dos quais possui algum tipo interessante, como texto,
bitmap, desenho, animação, mensagem, planilha, etc. A noção de incorporação recursiva arbitrária
está presente, de modo que uma inserção de qualquer tipo pode ser incorporada em qualquer outro
tipo que suporte incorporação. Por exemplo, uma inserção pode ser incorporada em qualquer ponto do
texto do widget de texto, ou em qualquer área retangular do widget de desenho, ou em qualquer célula
da planilha.

“Andrew” é uma referência ao Sistema de Interface de Usuário Andrew, embora naquela época fosse
conhecido simplesmente como Projeto Andrew.

Enquanto isso, Thomas Fine teve uma ideia diferente:

Aqui está minha opinião. A melhor maneira de fazer imagens na WWW é usando MIME. Tenho certeza
de que o postscript já é um subtipo suportado no MIME e lida muito bem com a mistura de texto e
gráficos.

Mas não é clicável, você diz? Sim, você está certo. Suspeito que já exista uma resposta para isso no
display postscript. Mesmo que não haja adição ao postscript padrão, é trivial.
Defina um comando âncora que especifique a URL e use o caminho atual como uma região fechada
para o botão. Como o postscript lida muito bem com caminhos, isso torna triviais os formatos arbitrários
de botões.

Exibir PostScript foi uma tecnologia de renderização na tela desenvolvida em conjunto pela Adobe e
NeXT.

Esta proposta nunca foi implementada, mas a ideia de que a melhor maneira de corrigir o HTML é
substituí-lo por algo completamente diferente ainda surge de vez em quando.

6 | Capítulo 1: Como chegamos aqui?

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Em 2 de março de 1993, Tim Berners-Lee comentou:

HTTP2 permite que um documento contenha qualquer tipo que o usuário disse que pode manipular, não
apenas tipos MIME registrados. Portanto, pode-se experimentar. Sim, acho que há um caso para
postscript com hipertexto. Não sei se o display postscript é suficiente. Eu sei que a Adobe está tentando
estabelecer seu próprio “PDF” baseado em postscript, que terá links e poderá ser lido por sua marca
proprietária de visualizadores.

Achei que uma linguagem genérica de sobreposição para âncoras (baseada em HyTime?) permitiria que
o hipertexto e os padrões gráficos/vídeo evoluíssem separadamente, o que ajudaria ambos.

Deixe a tag IMG ser INCLUDE e faça referência a um tipo de documento arbitrário. Ou EMBED se
INCLUDE soar como um cpp include que as pessoas esperam fornecer o código-fonte SGML para ser
analisado inline - não o que se pretendia.

HyTime foi um dos primeiros sistemas de documentos de hipertexto baseado em SGML. Ele teve grande importância em
muitas das primeiras discussões sobre HTML e, posteriormente, sobre XML.

A proposta de Tim para uma tag <INCLUDE> nunca foi implementada, embora você possa ver ecos dela em
<object>, <embed> e no elemento <iframe>.

Finalmente, em 12 de março de 1993, Marc Andreessen revisitou o tópico:

De volta ao tópico de imagens embutidas novamente - estou chegando perto de lançar o Mosaic v0.10,
que oferecerá suporte a imagens/bitmaps GIF e XBM embutidos, conforme mencionado anteriormente. [...]

Não estamos preparados para apoiar INCLUDE/EMBED neste momento. [...] Então provavelmente iremos
usar <IMG SRC="url"> (não ICON, já que nem todas as imagens embutidas podem ser chamadas de
ícones de forma significativa). Por enquanto, as imagens embutidas não serão explicitamente digitadas
por conteúdo; no futuro, planejamos apoiar isso (juntamente com a adaptação geral do MIME). Na
verdade, as rotinas de leitura de imagens que usamos atualmente descobrem o formato da imagem na
hora, então a extensão do nome do arquivo nem será significativa.

Uma linha ininterrupta

Estou extraordinariamente fascinado por todos os aspectos desta conversa de quase 17 anos que levou à criação de
um elemento HTML que foi usado em praticamente todas as páginas da web já publicadas. Considere isto:

• O HTTP ainda existe. Ele evoluiu com sucesso de 0.9 para 1.0 e posteriormente para 1.1, e ainda
ele evolui.

• HTML ainda existe. Esse formato de dados rudimentar (nem suportava imagens inline!) evoluiu com sucesso
para 2.0, 3.2 e 4.0. HTML é uma linha contínua. Uma linha retorcida, nodosa e emaranhada, com certeza –
havia muitos “galhos mortos” na árvore evolucionária, lugares onde as pessoas com mentalidade padronizada
se adiantavam (e à frente dos autores e implementadores) – mas ainda assim, aqui nós são em 2010, e as
páginas da web de 1990 ainda são renderizadas em navegadores modernos. Acabei de carregar um no
navegador do meu celular Android de última geração e nem fui solicitado a “aguarde enquanto importa o
formato legado...”

Uma linha ininterrupta | 7

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

• HTML sempre foi uma conversa entre criadores de navegadores, autores, especialistas em padrões e outras
pessoas que simplesmente apareciam e gostavam de falar sobre colchetes angulares. A maioria das versões
bem-sucedidas do HTML foram “especificações retroativas”, alcançando o mundo e, ao mesmo tempo,
tentando empurrá-lo na direção certa.
Qualquer um que lhe diga que o HTML deve ser mantido “puro” (presumivelmente ignorando os fabricantes
de navegadores, ou ignorando os autores, ou ambos) está simplesmente mal informado. O HTML nunca foi
puro e todas as tentativas de purificá-lo foram fracassos espetaculares, só igualados pelas tentativas de
substituí-lo.

• Nenhum dos navegadores em uso em 1993 ainda existe em qualquer forma reconhecível. O Netscape
Navigator foi abandonado em 1998 e reescrito do zero para criar o Mozilla Suite, que foi então bifurcado para
criar o Firefox. O Internet Explorer teve seu “começo” humilde no “Microsoft Plus! para Windows 95”, onde
veio com alguns temas de desktop e um jogo de pinball; mas é claro que esse navegador também pode ser
rastreado.

• Alguns dos sistemas operacionais de 1993 ainda existem, mas nenhum deles é relevante para a Web moderna.
A maioria das pessoas hoje que “experimentam” a Web o fazem em um PC com Windows 2000 ou posterior,
um Mac com Mac OS X, um PC com alguma versão do Linux ou um dispositivo portátil como um iPhone. Em
1993, o Windows estava na versão 3.1 (e competia com o OS/2), os Macs rodavam o System 7 e o Linux
era distribuído via Usenet. (Quer se divertir? Encontre um homem de barba grisalha e sussurre “Trumpet
Winsock” ou “MacPPP”.) • Algumas das mesmas pessoas ainda estão por aí e ainda envolvidas no que hoje
chamamos simplesmente de “padrões da web”.

Isso depois de quase 20 anos. E alguns estiveram envolvidos em antecessores do HTML, desde a década de
1980 e antes.

• Falando em antecessores... Com a eventual popularidade do HTML e da Web, é fácil esquecer os formatos e
sistemas contemporâneos que influenciaram seu design. Antes de ler este capítulo, você já tinha ouvido
falar de André? Intermediário?
HyTime? E o HyTime não era um projeto de pesquisa acadêmica vulgar; era um padrão ISO aprovado para
uso militar. Foi um grande negócio. E você mesmo pode ler sobre isso em http://www.sgmlsource.com/history/
hthist.htm.

Mas nada disso responde à pergunta original: por que temos um elemento <img>? Por que não um elemento
<icon>? Ou um elemento <include>? Por que não um hiperlink com um atributo include ou alguma combinação de
valores rel? Por que um elemento <img>? Simplesmente, porque Marc Andreessen enviou um e o código de envio
vence.

Isso não quer dizer que todos os códigos de envio vencem; afinal, Andrew, Intermedia e HyTime também enviaram
código. O código é necessário, mas não suficiente para o sucesso. E certamente não quero dizer que o código
de envio antes de um padrão produzirá a melhor solução. O elemento <img> de Marc não exigia um formato
gráfico comum; não definia como o texto fluía em torno dele; não suportava alternativas de texto ou conteúdo
alternativo para navegadores mais antigos. E 17 anos depois, ainda estamos lutando contra a detecção de
conteúdo, e isso ainda é uma fonte de vulnerabilidades de segurança malucas. Você pode rastrear isso através do
Grande

8 | Capítulo 1: Como chegamos aqui?

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Browser Wars, desde 25 de fevereiro de 1993, quando Marc Andreessen comentou espontaneamente:
“MIME, algum dia, talvez”, e então enviou seu código de qualquer maneira.

Uma linha do tempo de desenvolvimento HTML de 1997 a 2004

Em dezembro de 1997, o World Wide Web Consortium (W3C) publicou o HTML 4.0 e imediatamente
encerrou o Grupo de Trabalho HTML. Menos de dois meses depois, um grupo de trabalho separado do
W3C publicou o XML 1.0. Apenas três meses depois disso, o W3C realizou um workshop chamado
“Moldando o Futuro do HTML” para responder à pergunta: “O W3C desistiu do HTML?” Esta foi a resposta:

Nas discussões, foi acordado que seria difícil estender ainda mais o HTML 4.0, assim como
converter o 4.0 em um aplicativo XML. A maneira proposta de se libertar dessas restrições é
começar do zero com a próxima geração de HTML baseada em um conjunto de conjuntos de
tags XML.

O W3C reorganizou o Grupo de Trabalho HTML para criar este “conjunto de conjuntos de tags XML”. O
primeiro passo dos membros, em dezembro de 1998, foi redigir uma especificação provisória que
simplesmente reformulasse o HTML em XML sem adicionar quaisquer novos elementos ou atributos. Esta
especificação mais tarde ficou conhecida como “XHTML 1.0”. Ele definiu um novo tipo MIME para
documentos XHTML, application/xhtml+xml. No entanto, para facilitar a migração de páginas HTML 4
existentes, também incluiu o Apêndice C, que “resume as diretrizes de design para autores que desejam
que seus documentos XHTML sejam renderizados em agentes de usuário HTML existentes”. O Apêndice C
dizia que você tinha permissão para criar as chamadas páginas “XHTML”, mas ainda assim servi-las com o
tipo MIME text/html.

O próximo alvo foram os formulários da web. Em agosto de 1999, o mesmo Grupo de Trabalho HTML
publicou um primeiro rascunho do XHTML Extended Forms. Os seus membros estabeleceram as
expectativas logo nas primeiras frases deste projecto de documento:

Após cuidadosa consideração, o Grupo de Trabalho HTML decidiu que os objetivos para a
próxima geração de formulários são incompatíveis com a preservação da compatibilidade
retroativa com navegadores projetados para versões anteriores de HTML. Nosso objetivo é
fornecer um novo modelo de formulários limpo (“XHTML Extended Forms”) baseado em um
conjunto de requisitos bem definidos. Os requisitos descritos neste documento baseiam-se na
experiência com um amplo espectro de aplicações de formulários.

Alguns meses depois, “XHTML Extended Forms” foi renomeado como “XForms” e transferido para seu
próprio Grupo de Trabalho. Esse grupo trabalhou em paralelo com o HTML Working Group e finalmente
publicou a primeira edição do XForms 1.0 em outubro de 2003.

Enquanto isso, com a transição para XML concluída, os membros do Grupo de Trabalho HTML decidiram
criar “a próxima geração de HTML”. Em maio de 2001, eles publicaram a primeira edição do XHTML 1.1,
que adicionou apenas alguns recursos menores ao XHTML 1.0, mas eliminou a lacuna do “Apêndice C”. A
partir da versão 1.1, todos os documentos XHTML deveriam ser servidos com um tipo MIME de application/
xhtml+xml.

Uma linha do tempo de desenvolvimento HTML de 1997 a 2004 | 9

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Tudo o que você sabe sobre XHTML está errado

Por que os tipos MIME são importantes? Por que continuo voltando para eles? Três palavras: tratamento
draconiano de erros. Os navegadores sempre foram “clementes” com o HTML. Se você criar uma página HTML,
mas esquecer de atribuir um <title> a ela, os navegadores exibirão a página de qualquer maneira, mesmo que o
elemento <title> sempre tenha sido obrigatório em todas as versões do HTML. Certas tags não são permitidas em
outras tags, mas se você criar uma página que as coloque dentro de qualquer maneira, os navegadores
simplesmente lidarão com isso (de alguma forma) e seguirão em frente sem exibir uma mensagem de erro.

Como seria de esperar, o fato de a marcação HTML “quebrada” ainda funcionar em navegadores da Web levou
os autores a criar páginas HTML quebradas. Muitas páginas quebradas. Segundo algumas estimativas, mais de
99% das páginas HTML na Web hoje apresentam pelo menos um erro. Mas como esses erros não fazem com que
os navegadores exibam mensagens de erro visíveis, ninguém os corrige.

O W3C viu isso como um problema fundamental da Web e decidiu corrigi-lo.


O XML, publicado em 1997, rompeu com a tradição de perdoar os clientes e determinou que todos os programas
que consumissem XML tratassem os chamados erros de “boa formação” como fatais. Este conceito de falha no
primeiro erro ficou conhecido como “tratamento draconiano de erros”, em homenagem ao líder grego Draco, que
instituiu a pena de morte para infrações relativamente pequenas das suas leis. Quando o W3C reformulou o HTML
como um vocabulário XML, os responsáveis determinaram que todos os documentos servidos com o novo tipo

MIME application/xhtml+xml estariam sujeitos a um tratamento draconiano de erros. Se houvesse um único erro
em sua página XHTML, os navegadores da web não teriam escolha a não ser interromper o processamento e
exibir uma mensagem de erro ao usuário final.

Essa ideia não era universalmente popular. Com uma taxa de erro estimada em 99% nas páginas existentes, a
sempre presente possibilidade de exibir erros ao usuário final e a escassez de novos recursos em XHTML 1.0 e
1.1 para justificar o custo, os autores da web basicamente ignoraram application/xhtml+xml . Mas isso não significa
que eles ignoraram completamente o XHTML. Ah, definitivamente não. O Apêndice C da especificação XHTML
1.0 deu aos autores da web de todo o mundo uma brecha: “Use algo que se pareça com a sintaxe XHTML, mas
continue servindo-o com o tipo MIME text/html.” E foi exatamente isso que milhares de desenvolvedores web
fizeram: eles “atualizaram” para a sintaxe XHTML, mas continuaram servindo-a com um tipo MIME text/html.

Ainda hoje, embora muitas páginas da web afirmem ser XHTML, elas começam com o doctype XHTML na primeira
linha, usam nomes de tags em minúsculas, usam aspas em torno de valores de atributos e adicionam uma barra
final após elementos vazios como <br /> e <hr /> — apenas uma pequena fração dessas páginas é servida com o
tipo MIME application/xhtml+xml que acionaria o tratamento draconiano de erros do XML. Qualquer página
veiculada com um tipo MIME de texto/html, independentemente de seu tipo de documento, sintaxe ou estilo de
codificação, será analisada usando um “perdoador”
Analisador de HTML, ignorando silenciosamente quaisquer erros de marcação e nunca alertando os usuários finais (ou
qualquer outra pessoa), mesmo que a página esteja tecnicamente quebrada.

10 | Capítulo 1: Como chegamos aqui?

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

O XHTML 1.0 incluía essa brecha, mas o XHTML 1.1 a fechou, e o XHTML 2.0, nunca finalizado, continuou a tradição de exigir
tratamento draconiano de erros. E é por isso que existem bilhões de páginas que afirmam ser XHTML 1.0, e apenas algumas
que afirmam ser XHTML 1.1 (ou XHTML 2.0). Então, você está realmente usando XHTML? Verifique seu tipo MIME. (Na
verdade, se você não sabe que tipo MIME está usando, posso garantir que ainda está usando text/html.) A menos que você
esteja servindo suas páginas com um tipo MIME de application/xhtml+xml , o chamado “XHTML” é XML apenas no nome.

Uma visão competitiva

Em junho de 2004, o W3C realizou o Workshop sobre Aplicações Web e Documentos Compostos. Estiveram presentes neste
workshop representantes de vários fornecedores de navegadores, empresas de desenvolvimento web e outros membros do
W3C. Um grupo de partes interessadas, incluindo a Mozilla Foundation e a Opera Software, fizeram uma apresentação sobre
suas visões concorrentes do futuro da Web: uma evolução do padrão HTML 4 existente para incluir novos recursos para
desenvolvedores de aplicações web modernas:

Os sete princípios a seguir representam o que acreditamos serem os requisitos mais críticos para este trabalho:

Compatibilidade com versões anteriores, caminho de


migração claro As tecnologias de aplicativos da Web devem ser baseadas em tecnologias com as quais os
autores estão familiarizados, incluindo HTML, CSS, DOM e JavaScript.

Os recursos básicos de aplicativos da Web devem ser implementáveis usando comportamentos, scripts e
folhas de estilo no IE6 hoje, para que os autores tenham um caminho de migração claro. Qualquer solução
que não possa ser usada com o atual agente de usuário de alta participação de mercado sem a necessidade
de plug-ins binários tem grande probabilidade de não ser bem-sucedida.

Tratamento de erros bem definido


O tratamento de erros em aplicações Web deve ser definido em um nível de detalhe onde os Agentes de
Usuário (UAs) não precisem inventar seus próprios mecanismos de tratamento de erros ou fazer engenharia
reversa de outros Agentes de Usuário.

Os usuários não devem ser expostos a erros de criação. As


especificações devem especificar o comportamento exato de recuperação de erros para cada cenário de
erro possível. O tratamento de erros deve, em sua maior parte, ser definido em termos de recuperação
elegante de erros (como em CSS), em vez de falhas óbvias e catastróficas (como em XML).
Uso pratico
Cada recurso incluído nas especificações de aplicativos da Web deve ser justificado por um caso de uso
prático. O inverso não é necessariamente verdadeiro: cada caso de uso não garante necessariamente um
novo recurso.

Os casos de uso devem preferencialmente ser baseados em sites reais onde os autores usaram
anteriormente uma solução ruim para contornar a limitação.

Os scripts vieram para ficar,


mas devem ser evitados onde uma marcação declarativa mais conveniente puder ser usada.
O script deve ser neutro em relação ao dispositivo e à apresentação, a menos que tenha um escopo específico para
o dispositivo (por exemplo, a menos que seja incluído no XBL).

Uma visão competitiva | 11

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

O perfil específico do dispositivo deve ser evitado


Os autores devem poder contar com os mesmos recursos implementados nas versões desktop e
móvel do mesmo UA.
Processo
aberto A Web beneficiou do facto de ter sido desenvolvida num ambiente aberto. As aplicações
Web serão fundamentais para a Web e o seu desenvolvimento também deverá ocorrer
abertamente. As listas de discussão, os arquivos e os projetos de especificações devem estar
continuamente visíveis ao público.

Numa enquete, os participantes do workshop foram questionados: “O W3C deveria desenvolver extensões
declarativas para HTML e CSS e extensões imperativas para DOM, para atender aos requisitos de aplicações Web
de nível médio, em oposição a APIs sofisticadas e completas em nível de sistema operacional?” A votação foi de
11 a 8 contra. No resumo do workshop, os membros do W3C escreveram: “Atualmente, o W3C não pretende
colocar quaisquer recursos no terceiro tópico da pesquisa: extensões para HTML e CSS para aplicações Web,
além das tecnologias que estão sendo desenvolvidas sob o estatuto dos atuais grupos de trabalho do W3C.”

Diante dessa decisão, as pessoas que propuseram a evolução dos formulários HTML e HTML tinham apenas duas
opções: desistir ou continuar seu trabalho fora do W3C. Eles escolheram este último, registraram o domínio
whatwg.org e, em junho de 2004, nasceu o Grupo de Trabalho WHAT.

Qual grupo de trabalho?

O que diabos é o QUE Grupo de Trabalho? Vou deixar que explique por si:

O Grupo de Trabalho de Tecnologia de Aplicações de Hipertexto da Web é uma colaboração livre, não
oficial e aberta de fabricantes de navegadores da Web e partes interessadas. O grupo pretende
desenvolver especificações baseadas em HTML e tecnologias relacionadas para facilitar a implantação
de aplicações Web interoperáveis, com a intenção de submeter os resultados a uma organização de
normalização. Esta submissão formaria então a base do trabalho de extensão formal do HTML na trilha
de padrões.

A criação deste fórum decorre de vários meses de trabalho por e-mail privado sobre especificações
para tais tecnologias. O foco principal até agora tem sido estender os Formulários HTML4 para suportar
recursos solicitados pelos autores, sem quebrar a compatibilidade retroativa com o conteúdo existente.
Este grupo foi criado para garantir que o desenvolvimento futuro destas especificações será
completamente aberto, através de uma lista de discussão aberta e arquivada publicamente.

A frase-chave aqui é “sem quebrar a compatibilidade com versões anteriores”. XHTML (sem a lacuna do Apêndice
C) não é compatível com versões anteriores de HTML. Requer um tipo MIME totalmente novo e exige um tratamento
draconiano de erros para todo o conteúdo servido com esse tipo MIME. XForms não é compatível com versões
anteriores de formulários HTML, porque só pode ser usado em documentos que são servidos com o novo tipo
XHTML MIME, o que significa que XForms também exige tratamento draconiano de erros. Todos os caminhos
levam ao MIME.

12 | Capítulo 1: Como chegamos aqui?

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Em vez de descartar o investimento de mais de uma década em HTML e inutilizar 99% das páginas da Web
existentes, o Grupo de Trabalho O QUE decidiu adotar uma abordagem diferente: documentar os algoritmos
“complacentes” de tratamento de erros que os navegadores realmente usavam. Os navegadores da Web
sempre perdoaram os erros de HTML, mas ninguém jamais se preocupou em escrever exatamente como eles
faziam isso. O NCSA Mosaic tinha seus próprios algoritmos para lidar com páginas quebradas e a Netscape
tentou combiná-los. Então o Internet Explorer tentou igualar o Netscape. Então o Opera e o Firefox tentaram
igualar o Internet Explorer. Então o Safari tentou igualar o Firefox. E assim por diante, até os dias atuais. Ao
longo do caminho, os desenvolvedores gastaram milhares e milhares de horas tentando tornar seus produtos
compatíveis com os de seus concorrentes.

Se isso parece uma quantidade absurda de trabalho, é porque é. Ou melhor, foi. Demorou vários anos, mas
(módulo de alguns casos extremos obscuros) o Grupo de Trabalho O QUE documentou com sucesso como
analisar HTML de uma forma que seja compatível com o conteúdo da web existente. Em nenhum lugar do
algoritmo final existe uma etapa que determina que o consumidor HTML pare o processamento e exiba uma
mensagem de erro ao usuário final.

Enquanto toda aquela engenharia reversa acontecia, o Grupo de Trabalho O QUE também trabalhava
discretamente em algumas outras coisas. Uma delas foi uma especificação, inicialmente chamada de Web
Forms 2.0, que adicionou novos tipos de controles aos formulários HTML. (Você aprenderá mais sobre
formulários web no Capítulo 9.) Outra foi um rascunho de especificação chamado “Aplicativos Web 1.0” que
incluía novos recursos importantes, como uma tela de desenho em modo direto (veja o Capítulo 4) e suporte
nativo para áudio e vídeo. sem plug-ins (veja o Capítulo 5).

De volta ao W3C

Durante vários anos, o W3C e o Grupo de Trabalho WHAT ignoraram-se em grande parte.
Enquanto o Grupo de Trabalho O QUE se concentrava em formulários web e novos recursos HTML, o Grupo
de Trabalho HTML do W3C estava ocupado com a Versão 2.0 do XHTML. Mas em outubro de 2006, ficou claro
que o Grupo de Trabalho O QUE havia ganhado um grande impulso, enquanto o XHTML 2 ainda estava
definhando na forma de rascunho, não implementado por nenhum grande navegador. Em outubro de 2006, Tim
Berners-Lee, o fundador do próprio W3C, anunciou que o W3C trabalharia em conjunto com o Grupo de
Trabalho WHAT para evoluir o HTML: Algumas coisas ficam mais claras em retrospectiva de vários anos. É

necessário evoluir o HTML de forma incremental. A tentativa de fazer com que o mundo mudasse
para XML, incluindo aspas em torno de valores de atributos e barras em tags e namespaces vazios
de uma só vez, não funcionou. O grande público gerador de HTML não se mexeu, em grande parte
porque os navegadores não reclamaram. Algumas comunidades grandes mudaram e estão a colher
os frutos de sistemas bem formados, mas não todas. É importante manter o HTML de forma
incremental, bem como continuar a transição para um mundo bem formado e desenvolver mais
poder nesse mundo.

O plano é fundar um grupo HTML completamente novo. Ao contrário do anterior, este será destinado
a fazer melhorias incrementais no HTML, e também no XHTML paralelo. Terá um presidente e
contato de equipe diferentes. Funcionará em HTML e XHTML juntos. Temos um forte apoio a este
grupo, vindo de muitas pessoas com quem conversamos, incluindo fabricantes de navegadores.

De volta ao W3C | 13

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Também haverá trabalho em formulários. Esta é uma área complexa, pois os formulários HTML e
XForms existentes são linguagens de formulários. Os formulários HTML são implantados de forma
onipresente e há muitas implementações e usuários de XForms. Enquanto isso, o envio de
Webforms sugeriu extensões sensatas para formulários HTML. O plano é, informado pela
Webforms, estender os formulários HTML.

Uma das primeiras coisas que o recém-reformado Grupo de Trabalho HTML do W3C decidiu foi
renomear “Aplicações Web 1.0” para “HTML5”. E aqui estamos, mergulhando no HTML5.

Pós-escrito

Em outubro de 2009, o W3C encerrou o Grupo de Trabalho XHTML 2 e emitiu esta declaração
para explicar a decisão:
Quando o W3C anunciou os Grupos de Trabalho HTML e XHTML 2 em março de 2007,
indicamos que continuaríamos monitorando o mercado de XHTML 2. O W3C reconhece
a importância de um sinal claro para a comunidade sobre o futuro do HTML.
Embora reconheçamos o valor das contribuições do Grupo de Trabalho XHTML 2 ao longo
dos anos, após discussão com os participantes, a administração do W3C decidiu permitir
que o estatuto do Grupo de Trabalho expirasse no final de 2009 e não renová-lo.

Os que ganham são os que enviam.

Leitura adicional

• “The History of the Web”, um rascunho antigo de Ian Hickson •


“HTML/History”, de Michael Smith, Henri Sivonen e outros • “A Brief History
of HTML”, de Scott Reynen

14 | Capítulo 1: Como chegamos aqui?

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

CAPÍTULO 2

Detectando recursos HTML5

Mergulhando

Você pode perguntar: “Como posso começar a usar HTML5 se navegadores mais antigos não o suportam?”
Mas a questão em si é enganosa. HTML5 não é grande coisa; é uma coleção de recursos individuais.
Portanto, você não pode detectar “suporte HTML5”, porque isso não faz sentido. Mas você pode detectar
suporte para recursos individuais, como tela, vídeo ou geolocalização.

Técnicas de detecção

Quando seu navegador renderiza uma página da web, ele constrói um Document Object Model (DOM), uma
coleção de objetos que representam os elementos HTML da página. Cada elemento – cada <p>, cada
<div>, cada <span> – é representado no DOM por um objeto diferente. (Existem também objetos globais,
como janela e documento, que não estão vinculados a elementos específicos.)

Todos os objetos DOM compartilham um conjunto de propriedades comuns, mas alguns objetos possuem
mais que outros. Em navegadores que suportam recursos HTML5, determinados objetos terão propriedades
exclusivas. Uma rápida olhada no DOM lhe dirá quais recursos são suportados.

Existem quatro técnicas básicas para detectar se um navegador oferece suporte a um recurso específico.
Do mais simples ao mais complexo:

1. Verifique se existe determinada propriedade em um objeto global (como janela ou navegador).

Para obter um exemplo de teste de suporte de geolocalização, consulte “Geolocalização” na página


24.

2. Crie um elemento e verifique se existe uma determinada propriedade nesse elemento.

Para obter um exemplo de teste de suporte ao canvas, consulte “Canvas” na página 16.
3. Crie um elemento, verifique se existe um determinado método naquele elemento, depois chame o
método e verifique o valor que ele retorna.

15

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Para obter um exemplo de teste de quais formatos de vídeo são suportados, consulte “Formatos
de vídeo” na página 19.
4. Crie um elemento, defina uma propriedade com um determinado valor e verifique se a propriedade
manteve seu valor.

Para obter um exemplo de teste de quais tipos de <input> são suportados, consulte “Tipos de
entrada” na página 25.

Modernizr: uma biblioteca de detecção HTML5


Modernizar é uma biblioteca JavaScript de código aberto licenciada pelo MIT que detecta suporte para
muitos recursos HTML5 e CSS3. No momento em que este artigo foi escrito, a versão mais recente era
1.1. Você deve sempre usar a versão mais recente. Para fazer isso, inclua o seguinte elemento <script>
no topo da sua página:
<!DOCTYPE
html>
<html>
<head> <meta
charset="utf-8"> <title>Mergulhe no
HTML5</title> <script src="modernizr.min.js"></
script>
</head > <corpo>
...
</body>
</html>

O Modernizr é executado automaticamente. Não há função modernizr_init() para chamar. Quando


executado, ele cria um objeto global chamado Modernizr que contém um conjunto de propriedades
booleanas para cada recurso que pode detectar. Por exemplo, se o seu navegador suportar a API
canvas (veja o Capítulo 4), a propriedade Modernizr.canvas será verdadeira. Se o seu navegador não
suportar a API canvas, a propriedade Modernizr.canvas será falsa:
if (Modernizr.canvas) {
// vamos desenhar algumas
formas! }
else { // não há suporte nativo para canvas
disponível :( }

Tela
HTML5 define o elemento <canvas> como “uma tela de bitmap dependente de resolução que pode ser
usada para renderizar gráficos, gráficos de jogos ou outras imagens visuais em tempo real”. Uma tela é
um retângulo em sua página dentro do qual você pode usar JavaScript para desenhar o que quiser.
HTML5 define um conjunto de funções (“API canvas”) para desenhar formas, definir caminhos, criar
gradientes e aplicar transformações.

A verificação do suporte da API canvas usa a técnica de detecção nº 2 (consulte “Técnicas de detecção”
na página 15). Se o seu navegador suportar a API canvas, o objeto DOM que ele cria

16 | Capítulo 2: Detectando recursos HTML5

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

para representar um elemento <canvas> terá um método getContext() (veja “Formas Simples” na página 58). Se o
seu navegador não suportar a API canvas, o objeto DOM criado para um elemento <canvas> terá apenas o conjunto
de propriedades comuns, e não qualquer coisa específica do canvas. Você pode verificar o suporte ao canvas
usando esta função:

função support_canvas() { return !!


document.createElement('canvas').getContext; }

Esta função começa criando um elemento <canvas> fictício: return !!

document.createElement('canvas').getContext;

Este elemento nunca é anexado à sua página, portanto ninguém o verá. Está apenas flutuando na memória, indo a
lugar nenhum e sem fazer nada, como uma canoa em um rio lento.

Assim que você cria o elemento fictício <canvas>, você testa a presença de um método getContext(). Este método
só existirá se o seu navegador suportar a API canvas:

return !!document.createElement('canvas').getContext;

Finalmente, você usa o truque da dupla negativa para forçar o resultado a um valor booleano (verdadeiro ou falso):

return !!document.createElement('canvas').getContext;

Esta função detectará suporte para a maior parte da API canvas, incluindo formas (consulte “Formas simples” na
página 58), caminhos (consulte “Caminhos” na página 61), gradientes (consulte “Gradientes” na página 67) e
padrões . Ele não detectará a biblioteca explorercanvas de terceiros (consulte “E quanto ao IE?” na página 73) que
implementa a API canvas no Microsoft Internet Explorer.

Em vez de escrever essa função você mesmo, você pode usar o Modernizr (introduzido na seção anterior) para
detectar suporte para a API canvas:

if (Modernizr.canvas) {
// vamos desenhar algumas
formas! }
else { // não há suporte nativo para canvas
disponível :( }

Há um teste separado para a API de texto de tela, que demonstrarei a seguir.

Texto em tela

Mesmo que o seu navegador suporte a API canvas, ele pode não oferecer suporte à API canvas text.
A API canvas cresceu com o tempo e as funções de texto foram adicionadas mais tarde no jogo.
Alguns navegadores foram fornecidos com suporte a canvas antes da conclusão da API de texto.

A verificação do suporte da API de texto de tela novamente usa a técnica de detecção nº 2 (consulte “Técnicas de
detecção” na página 15). Se o seu navegador suportar a API canvas, o objeto DOM criado para representar um
elemento <canvas> terá o método getContext() (veja “Simples

Texto em tela | 17

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Formas” na página 58). Se o seu navegador não suportar a API canvas, o objeto DOM criado para um
elemento <canvas> terá apenas o conjunto de propriedades comuns, e não qualquer coisa específica
do canvas. Você pode verificar o suporte ao texto da tela usando esta função:
função support_canvas_text() { if (!
supports_canvas()) { return false; } var
dummy_canvas = document.createElement('canvas'); var
contexto = dummy_canvas.getContext('2d'); return
typeof context.fillText == 'função'; }

A função começa verificando o suporte do canvas, usando a função support_canvas() apresentada na


seção anterior:
if (!supports_canvas()) { return falso; }

Se o seu navegador não suporta a API canvas, certamente não suportará a API canvas text!

Em seguida, você cria um elemento <canvas> fictício e obtém seu contexto de desenho. É garantido
que isso funcione, porque a função support_canvas() já verificou se o método getContext() existe em
todos os objetos canvas:
var dummy_canvas = document.createElement('canvas');
var contexto = dummy_canvas.getContext('2d');

Finalmente, você verifica se o contexto do desenho possui uma função fillText(). Se isso acontecer, a
API de texto da tela estará disponível:

return typeof context.fillText == 'função';

Em vez de escrever esta função você mesmo, você pode usar o Modernizr (veja “Modernizr: Um
Biblioteca de detecção HTML5” na página 16) para detectar suporte para a API de texto de tela:
if (Modernizr.canvastext) { //
vamos desenhar um
texto! }
else { // nenhum suporte de texto de tela nativo
disponível :( }

Vídeo

HTML5 define um novo elemento chamado <video> para incorporar vídeo em suas páginas da web.
Incorporar vídeo costumava ser impossível sem plug-ins de terceiros, como Apple QuickTime ou Adobe
Flash.

18 | Capítulo 2: Detectando recursos HTML5

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

O elemento <video> foi projetado para ser usado sem nenhum script de detecção. Você pode
especificar vários arquivos de vídeo, e os navegadores que suportam vídeo HTML5 escolherão um
com base nos formatos de vídeo que suportam.*

Os navegadores que não suportam vídeo HTML5 ignorarão o elemento <video> completamente,
mas você pode usar isso a seu favor e peça para eles reproduzirem o vídeo por meio de um plug-in
de terceiros. Kroc Camen projetou uma solução chamada Video for Everybody! que usa vídeo HTML5
quando disponível, mas recorre ao QuickTime ou Flash em navegadores mais antigos. Esta solução
não usa nenhum JavaScript e funciona em praticamente todos os navegadores, incluindo navegadores
móveis.

Se quiser fazer mais com o vídeo do que colocá-lo em sua página e reproduzi-lo, você precisará usar
JavaScript. A verificação de suporte de vídeo usa a técnica de detecção nº 2 (consulte “Técnicas de
detecção” na página 15). Se o seu navegador suportar vídeo HTML5, o objeto DOM criado para
representar um elemento <video> terá um método canPlayType(). Se o seu navegador não suportar
vídeo HTML5, o objeto DOM criado para um elemento <video> terá apenas o conjunto de
propriedades comuns a todos os elementos. Você pode verificar o suporte de vídeo usando esta
função: function support_video()
{ return !!
document.createElement('video').canPlayType; }

Em vez de escrever esta função você mesmo, você pode usar o Modernizr (veja “Modernizr: Um
Biblioteca de detecção de HTML5” na página 16) para detectar suporte para vídeo HTML5:
if (Modernizr.video) { //
vamos reproduzir um
vídeo! }
else { // nenhum suporte de vídeo nativo
disponível :( // talvez verifique se há QuickTime ou
Flash }

Existe um teste separado para detectar quais formatos de vídeo seu navegador pode reproduzir, que
demonstrarei a seguir.

Formatos de vídeo

Os formatos de vídeo são como linguagens escritas. Um jornal inglês pode transmitir a mesma
informação que um jornal espanhol, mas se você só consegue ler em inglês, apenas um deles lhe
será útil! Para reproduzir um vídeo, seu navegador precisa entender o “idioma” em que o vídeo foi
escrito.

* Consulte “Uma introdução suave à codificação de vídeo, parte 1: formatos de contêiner” e “parte 2: codecs de vídeo com perdas” para
aprender sobre os diferentes formatos de vídeo.

Formatos de vídeo | 19

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

A “linguagem” de um vídeo é chamada de “codec” – este é o algoritmo usado para codificar o vídeo
em um fluxo de bits. Existem dezenas de codecs em uso em todo o mundo. Qual você deve usar?
A triste realidade do vídeo HTML5 é que os navegadores não conseguem chegar a um acordo sobre
um único codec. No entanto, eles parecem ter reduzido para dois. Um codec custa dinheiro (devido
ao licenciamento de patentes), mas funciona no Safari e no iPhone. (Este também funciona em
Adobe Flash, se você usar uma solução como Video for Everybody!.) O outro codec é gratuito e
funciona em navegadores de código aberto como Chromium e Mozilla Firefox.

A verificação do suporte ao formato de vídeo utiliza a técnica de detecção nº 3 (consulte “Técnicas


de detecção” na página 15). Se o seu navegador suportar vídeo HTML5, o objeto DOM criado para
representar um elemento <video> terá um método canPlayType(). Este método informará se o
navegador suporta um formato de vídeo específico.

Esta função verifica o formato com patente suportada por Macs e iPhones:

função support_h264_baseline_video() { if (!
supports_video()) { return false; } var v =
document.createElement("vídeo"); retornar
v.canPlayType('vídeo/mp4; codecs="avc1.42E01E, mp4a.40.2"'); }

A função começa verificando o suporte a vídeo HTML5, usando a função support_video() da seção
anterior:
if (!supports_video()) { return falso; }

Se o seu navegador não suporta vídeo HTML5, certamente não suportará nenhum formato de vídeo!

Em seguida, a função cria um elemento <video> fictício (mas não o anexa à página, portanto não
ficará visível) e chama o método canPlayType(). É garantido que este método esteja lá, porque a
função support_video() acabou de verificar:
var v = document.createElement("vídeo");
retornar v.canPlayType('vídeo/mp4; codecs="avc1.42E01E, mp4a.40.2"');

Um “formato de vídeo” é na verdade uma combinação de várias coisas diferentes. Em termos


técnicos, você está perguntando ao navegador se ele pode reproduzir vídeo H.264 Baseline e áudio
AAC LC em um contêiner MPEG-4.†

A função canPlayType() não retorna verdadeiro ou falso. Reconhecendo a complexidade dos


formatos de vídeo, a função retorna uma string:

"provavelmente"

Se o navegador estiver bastante confiante de que pode reproduzir este formato

† Explicarei o que tudo isso significa no Capítulo 5. Você também pode estar interessado em ler “Uma introdução suave à
codificação de vídeo”.

20 | Capítulo 2: Detectando recursos HTML5

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

"talvez"
Se o navegador achar que pode reproduzir este formato "" (uma string vazia)

Se o navegador tiver certeza de que não consegue reproduzir este formato

Esta segunda função verifica o formato de vídeo aberto suportado pelo Mozilla Firefox e outros navegadores de
código aberto. O processo é exatamente o mesmo; a única diferença é a string que você passa para a função
canPlayType(). Em termos técnicos, você está perguntando ao navegador se ele pode reproduzir vídeo Theora e
áudio Vorbis em um contêiner Ogg:

função support_ogg_theora_video() {
if (!supports_video()) { return falso; } var v =
document.createElement("vídeo"); return
v.canPlayType('video/ogg; codecs="theora, vorbis"'); }

Finalmente, WebM é um codec de vídeo de código aberto (e sem patente) que será incluído na próxima versão dos
principais navegadores, incluindo Chrome, Firefox e Opera. Você pode usar a mesma técnica para detectar suporte
para vídeo WebM aberto:

função support_webm_video() { if (!
supports_video()) { return false; } var v =
document.createElement("vídeo"); retornar
v.canPlayType('video/webm; codecs="vp8, vorbis"'); }

Em vez de escrever esta função sozinho, você pode usar o Modernizr para detectar suporte para vários formatos
de vídeo HTML5 diferentes (observe que o Modernizr ainda não tem suporte para detectar suporte para o formato
de vídeo WebM aberto): if (Modernizr.video) { // vamos reproduza algum

vídeo! mas que tipo? if


(Modernizr.video.ogg) { //tente Ogg Theora + Vorbis
em um contêiner Ogg } else if
(Modernizr.video.h264){

// experimente vídeo H.264 + áudio AAC em um contêiner

MP4 } }

Armazenamento local

O armazenamento HTML5 fornece uma maneira para os sites armazenarem informações em seu computador e
recuperá-las posteriormente. O conceito é semelhante ao dos cookies, mas foi concebido para grandes quantidades
de informação. Os cookies têm tamanho limitado e seu navegador os envia de volta ao servidor da web sempre
que solicita uma nova página (o que exige mais tempo e largura de banda preciosa). O armazenamento HTML5
permanece no seu computador e os sites podem acessá-lo com JavaScript após o carregamento da página.

Armazenamento local | 21

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Pergunte ao professor Markup

P: O armazenamento local é realmente parte do HTML5? Por que está em uma especificação separada?

R: A resposta curta é sim, o armazenamento local faz parte do HTML5. A resposta um pouco mais longa é que o
armazenamento local costumava fazer parte da especificação principal do HTML5, mas foi dividido em uma
especificação separada porque algumas pessoas do Grupo de Trabalho do HTML5 reclamaram que o HTML5 era
muito grande. Se isso soa como cortar uma torta em mais pedaços para reduzir o número total de calorias... bem,
bem-vindo ao mundo maluco dos padrões.

A verificação do suporte ao armazenamento HTML5 usa a técnica de detecção nº 1 (consulte “Técnicas de detecção” na
página 15). Se o seu navegador suportar armazenamento HTML5, haverá uma propriedade localStorage no objeto de janela
global. Se o seu navegador não suportar armazenamento HTML5, a propriedade localStorage será indefinida. Você pode
verificar o suporte de armazenamento local usando esta função:

função support_local_storage() { return


('localStorage' na janela) && window['localStorage'] !== null; }

Em vez de escrever esta função você mesmo, você pode usar o Modernizr (veja “Modernizr: Um
Biblioteca de detecção HTML5” na página 16) para detectar suporte para armazenamento local HTML5:

if (Modernizr.localstorage) { //
window.localStorage está disponível! } else { //
sem
suporte nativo para armazenamento local :( // talvez tente
o Gears ou outra solução de terceiros }

Observe que o JavaScript diferencia maiúsculas de minúsculas. O atributo Modernizr é chamado localstorage (tudo em letras
minúsculas), mas a propriedade DOM é chamada window.localStorage (maiúsculas e minúsculas).

Pergunte ao professor Markup

P: Quão seguro é meu banco de dados de armazenamento HTML5? Alguém pode ler?

R: Qualquer pessoa que tenha acesso físico ao seu computador provavelmente poderá consultar (ou até mesmo
alterar) seu banco de dados de armazenamento HTML5. No seu navegador, qualquer site pode ler e modificar seus
próprios valores, mas os sites não podem acessar valores armazenados por outros sites. Isso é chamado de restrição
de mesma origem.

22 | Capítulo 2: Detectando recursos HTML5

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Trabalhadores da Web

Web workers fornecem uma maneira padrão para os navegadores executarem JavaScript em segundo plano.
Com web workers, você pode gerar vários “threads” que são executados ao mesmo tempo, mais ou menos. (Pense
em como seu computador pode executar vários aplicativos ao mesmo tempo, e você estará quase lá.) Esses “threads
de segundo plano” podem fazer cálculos matemáticos complexos, fazer solicitações de rede ou acessar armazenamento
local enquanto a página principal da web responde à rolagem, clique ou digitação do usuário.

A verificação de web workers usa a técnica de detecção nº 1 (consulte “Técnicas de detecção” na página 15). Se o
seu navegador suportar a API Web Worker, haverá uma propriedade Worker no objeto de janela global. Se o seu
navegador não suportar a API Web Worker, a propriedade Worker será indefinida. Esta função verifica o suporte do
web trabalhador:

função support_web_workers()
{ return !!window.Worker; }

Em vez de escrever esta função você mesmo, você pode usar o Modernizr (veja “Modernizr: Um
Biblioteca de detecção HTML5” na página 16) para detectar suporte para web workers:

if (Modernizr.webworkers) {
// window.Worker está

disponível! } else { // sem suporte nativo


para web workers :( // talvez tente o Gears ou outra
solução de terceiros }

Observe que o JavaScript diferencia maiúsculas de minúsculas. O atributo Modernizr é chamado de webworkers (tudo
em letras minúsculas), mas o objeto DOM é chamado de window.Worker (com “W” maiúsculo em “Worker”).

Aplicativos da Web off-line

Ler páginas da web estáticas off-line é fácil: conecte-se à Internet, carregue uma página da web, desconecte-se da
Internet, dirija até uma cabana isolada e leia a página da web quando quiser. (Para economizar tempo, você pode
pular a etapa da cabine.) Mas que tal usar aplicativos da web como Gmail ou Google Docs quando estiver off-line?
Graças ao HTML5, qualquer pessoa (não apenas o Google!) pode construir uma aplicação web que funcione offline.

Os aplicativos da web offline começam como aplicativos da web online. Na primeira vez que você visita um site
habilitado para off-line, o servidor da web informa ao seu navegador quais arquivos ele precisa para funcionar off-line.
Esses arquivos podem ser qualquer coisa: HTML, JavaScript, imagens e até vídeos (consulte “Vídeo” na página 18).
Depois que seu navegador baixar todos os arquivos necessários, você poderá revisitar o site mesmo se não estiver
conectado à Internet. Seu navegador notará que você está offline e usará os arquivos já baixados. Quando você voltar
a ficar on-line, todas as alterações feitas poderão ser carregadas no servidor web remoto.

Aplicativos da Web off-line | 23

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

A verificação de suporte off-line usa a técnica de detecção nº 1 (consulte “Técnicas de detecção” na página 15). Se o
seu navegador suportar aplicativos da web offline, haverá uma propriedade applicationCache no objeto de janela global.
Se o seu navegador não suportar aplicativos da Web offline, a propriedade applicationCache será indefinida. Você pode
verificar o suporte offline com a seguinte função:

função support_offline() {
retornar !!window.applicationCache; }

Em vez de escrever esta função você mesmo, você pode usar o Modernizr (veja “Modernizr: Um
Biblioteca de detecção HTML5” na página 16) para detectar suporte para aplicativos da web offline:

if (Modernizr.applicationcache) { //
window.applicationCache está disponível! } else { //
sem
suporte nativo para off-line :( // talvez tente o
Gears ou outra solução de terceiros }

Observe que o JavaScript diferencia maiúsculas de minúsculas. O atributo Modernizr é chamado applicationc ache
(tudo em letras minúsculas), mas o objeto DOM é chamado window.applicationCache (maiúsculas e minúsculas).

Geolocalização

Geolocalização é a arte de descobrir onde você está no mundo e (opcionalmente) compartilhar essa informação com
pessoas em quem você confia. Há muitas maneiras de descobrir onde você está: seu endereço IP, sua conexão de
rede sem fio, com qual torre de celular seu telefone está se comunicando ou hardware GPS dedicado que recebe
informações de latitude e longitude de satélites no céu.

Pergunte ao professor Markup

P: A geolocalização faz parte do HTML5? Por que você está falando sobre isso?

R: O suporte à geolocalização está sendo adicionado aos navegadores agora, junto com o suporte para novos
recursos do HTML5. A rigor, a geolocalização está sendo padronizada pelo Grupo de Trabalho de
Geolocalização, que é separado do Grupo de Trabalho HTML5. Mas vou falar sobre geolocalização neste livro
de qualquer maneira, porque faz parte da evolução da Web que está acontecendo agora.

A verificação do suporte de geolocalização utiliza a técnica de detecção nº 1 (consulte “Técnicas de detecção” na


página 15). Se o seu navegador suportar a API de geolocalização, haverá uma propriedade de geolocalização no objeto
navegador global. Se o seu navegador não suportar a API de geolocalização, a propriedade de geolocalização será
indefinida. Veja como verificar o suporte de geolocalização:

24 | Capítulo 2: Detectando recursos HTML5

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

função support_geolocation() { return !!


navigator.geolocation; }

Em vez de escrever esta função você mesmo, você pode usar o Modernizr (veja “Modernizr: Um
Biblioteca de detecção HTML5” na página 16) para detectar suporte para a API de geolocalização:
if (Modernizr.geolocalização) {
// vamos descobrir onde você está! }
else { //
nenhum suporte nativo de geolocalização disponível :
( // talvez tente o Gears ou outra solução de terceiros }

Se o seu navegador não oferece suporte nativo à API de geolocalização, ainda há esperança.
Gears é um plug-in de navegador de código aberto do Google que funciona em Windows, Mac, Linux,
Windows Mobile e Android. Ele fornece vários recursos para navegadores mais antigos que não suportam
todas as novidades sofisticadas que discutimos neste capítulo.
Um dos recursos que o Gears oferece é uma API de geolocalização. Não é o mesmo que a API
navigator.geolocation, mas tem o mesmo propósito.

Existem também APIs de geolocalização específicas de dispositivos em diversas plataformas de telefonia


móvel, incluindo BlackBerry, Nokia, Palm e OMTP BONDI.

O Capítulo 6 entrará em detalhes excruciantes sobre como usar todas essas APIs diferentes.

Tipos de entrada

Você sabe tudo sobre formulários web, certo? Faça um <form>, adicione alguns elementos <input type="text">
e talvez um <input type="password">, e finalize com um botão <input type="submit">.

Você não sabe nem metade disso. HTML5 define mais de uma dúzia de novos tipos de entrada que você
pode usar em seus formulários:

<input type="search">
Consulte http://bit.ly/9mQt5C para caixas de

pesquisa <input
type="number"> Consulte http://bit.ly/aPZHjD para caixas giratórias

<input type="range">
Consulte http://bit.ly/dmLiRr para controles

deslizantes <input
type="color"> Consulte http://bit.ly/bwRcMO para

seletores de cores <input


type="tel"> Consulte http://bit.ly/amkWLq para números de

telefone <input
type="url"> Consulte http://bit.ly/cjKb3a para endereços da web

Tipos de entrada | 25

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

<input type="email">
Consulte http://bit.ly/aaDrgS para endereços de e-
mail <input type="date">
Consulte http://bit.ly/c8hL58 para seletores de datas do
calendário <input
type="month" > Consulte http://bit.ly/cDgHRI
para meses <input
type="week"> Consulte http://bit.ly/
bR3r58 para semanas
<input type="time"> Consulte http://bit.ly/ bfMCMn
para carimbos de data e hora
<input type="datetime"> Consulte http://bit.ly/c46zVW para datas/carimbos de data e hora precisos e absolutos
<input type="datetime-local"> Consulte
http://bit.ly/aziNkE para datas e horários locais

A verificação de tipos de entrada HTML5 usa a técnica de detecção nº 4 (consulte “Técnicas de detecção”
na página 15). Primeiro, você cria um elemento <input> fictício na memória:
var i = document.createElement("entrada");

O tipo de entrada padrão para todos os elementos <input> é "texto". Isto provará ser de vital importância.

Em seguida, defina o atributo type no elemento fictício <input> para o tipo de entrada que você deseja
detectar:

i.setAttribute("tipo", "cor");

Se o seu navegador suportar esse tipo de entrada específico, a propriedade type manterá o valor que
você definiu. Se o seu navegador não suportar esse tipo de entrada específico, ele irá ignorar o valor que
você definiu e a propriedade type ainda será "texto":
return i.type !== "texto";

Em vez de escrever você mesmo 13 funções separadas, você pode usar o Modernizr (consulte “Mod
ernizr: uma biblioteca de detecção de HTML5” na página 16) para detectar suporte para todos os novos
tipos de entrada definidos em HTML5. O Modernizr reutiliza um único elemento <input> para detectar
com eficiência o suporte para todos os 13 tipos de entrada. Em seguida, ele cria um hash chamado tipos
Modernizr.input, que contém 13 chaves (os atributos do tipo HTML5) e 13 valores booleanos (verdadeiro
se suportado, falso se não):
if (!Modernizr.inputtypes.date) { // sem
suporte nativo para <input type="date"> :( // talvez você
mesmo construa um com // Dojo //
ou
jQueryUI }

26 | Capítulo 2: Detectando recursos HTML5

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Texto de espaço reservado

Além dos novos tipos de entrada, o HTML5 inclui vários pequenos ajustes nos formulários existentes. Uma
melhoria é a capacidade de definir texto de espaço reservado em um campo de entrada. O texto do espaço
reservado é exibido dentro do campo de entrada enquanto o campo estiver vazio e sem foco. Assim que você
clica (ou tabula) no campo de entrada, o texto do espaço reservado desaparece. “Texto de espaço reservado” na
página 147 contém capturas de tela caso você esteja tendo problemas para visualizá-lo.

A verificação do suporte de espaço reservado utiliza a técnica de detecção nº 2 (consulte “Técnicas de detecção”
na página 15). Se o seu navegador suportar texto de espaço reservado em campos de entrada, o objeto DOM
criado para representar um elemento <input> terá uma propriedade de espaço reservado (mesmo se você não
incluir um atributo de espaço reservado em seu HTML). Se o seu navegador não suportar texto de espaço
reservado, o objeto DOM criado para um elemento <input> não terá uma propriedade de espaço reservado . Veja
como verificar o suporte ao espaço reservado:

função support_input_placeholder() {
var i = document.createElement('input');
retorne 'espaço reservado'
em i; }

Em vez de escrever esta função sozinho, você pode usar o Modernizr (consulte “Modernizr: uma biblioteca de
detecção HTML5” na página 16) para detectar suporte para texto de espaço reservado: if

(Modernizr.input.placeholder) {
// seu texto de espaço reservado já deve estar visível! }
else { //
sem suporte de espaço
reservado :( // volta para uma solução
com script }

Foco automático de formulário

Muitos sites usam JavaScript para focar automaticamente o primeiro campo de entrada de um formulário da web.
Por exemplo, a página inicial do Google.com focará automaticamente a caixa de entrada para que você possa
digitar as palavras-chave de pesquisa sem precisar posicionar o cursor na caixa de pesquisa.
Embora isso seja conveniente para a maioria das pessoas, pode ser irritante para usuários avançados ou pessoas
com necessidades especiais. Se você pressionar a barra de espaço esperando rolar a página, a página não
rolará porque o foco já está em um campo de entrada do formulário. (Em vez disso, você digitará um espaço no
campo.) Se você focar em um campo de entrada diferente enquanto a página ainda está carregando, o script de
foco automático do site pode “útil” mover o foco de volta para o campo de entrada original após a conclusão,
interrompendo seu fluir e fazer com que você digite no lugar errado.

Como o foco automático é feito com JavaScript, pode ser complicado lidar com todos esses casos extremos, e
há poucos recursos para pessoas que não desejam que uma página da Web “roube” o foco.

Foco automático de formulário | 27

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Para resolver esse problema, o HTML5 introduz um atributo autofocus em todos os controles de formulário da web.
O atributo autofocus faz exatamente o que diz na lata: move o foco para um campo de entrada específico. Mas como
se trata apenas de uma marcação em vez de um script, o comportamento será consistente em todos os sites. Além
disso, os fornecedores de navegadores (ou autores de extensões) podem oferecer aos usuários uma maneira de
desativar o comportamento de foco automático.

A verificação do suporte ao foco automático usa a técnica de detecção nº 2 (consulte “Técnicas de detecção” na
página 15). Se o seu navegador suportar controles de formulário da web com foco automático, o objeto DOM criado
para representar um elemento <input> terá uma propriedade autofocus (mesmo se você não incluir o atributo
autofocus em seu HTML). Se o seu navegador não suportar controles de formulário da web com foco automático, o
objeto DOM criado para um elemento <input> não terá uma propriedade autofocus . Você pode detectar suporte para
foco automático com esta função:

função support_input_autofocus() {
var i = document.createElement('input'); retorne
'foco automático' em i; }

Em vez de escrever esta função você mesmo, você pode usar o Modernizr (veja “Modernizr: Um
Biblioteca de detecção HTML5” na página 16) para detectar suporte para campos de formulário com foco automático:

if (Modernizr.input.autofocus) { // o
foco automático
funciona! }
else { // sem suporte para foco
automático :( // volta para uma solução
com script }

Microdados
Microdados é uma forma padronizada de fornecer semântica adicional em suas páginas da web.
Por exemplo, você pode usar microdados para declarar que uma fotografia está disponível sob uma licença Creative
Commons específica. Como você verá no Capítulo 10, você também pode usar microdados para marcar uma página
“Sobre mim”. Navegadores, extensões de navegador e mecanismos de pesquisa podem converter sua marcação de
microdados HTML5 em um vCard, um formato padrão para compartilhar informações de contato. Você também pode
definir seus próprios vocabulários de microdados.

O padrão de microdados HTML5 inclui marcação HTML (principalmente para mecanismos de pesquisa) e um
conjunto de funções DOM (principalmente para navegadores). Não há mal nenhum em incluir marcação de
microdados em suas páginas da web; nada mais é do que alguns atributos bem posicionados, e os mecanismos de
pesquisa que não entendem os atributos de microdados simplesmente os ignorarão. Mas se precisar acessar ou
manipular microdados por meio do DOM, você precisará verificar se o navegador oferece suporte à API DOM de
microdados.

28 | Capítulo 2: Detectando recursos HTML5

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

A verificação do suporte da API de microdados HTML5 usa a técnica de detecção nº 1 (consulte “Técnicas
de detecção” na página 15). Se o seu navegador suportar a API de microdados HTML5, haverá uma função
getItems() no objeto de documento global . Se o seu navegador não suportar microdados, a função
getItems() será indefinida. Você pode verificar o suporte da seguinte maneira:

função support_microdata_api()
{ return !!document.getItems; }

O Modernizr ainda não oferece suporte à verificação da API de microdados, então você precisará usar uma
função como esta.

Leitura adicional
Especificações e padrões:

• O elemento <canvas>

• O elemento <video>

• tipos de <entrada>
• O atributo <espaço reservado de entrada> •

O atributo <input autofocus> •

Armazenamento HTML5
• Trabalhadores da Web

• Aplicativos da web off-line • A

API de geolocalização

Bibliotecas JavaScript:

• Modernização, uma biblioteca de detecção HTML5 •

geo.js, um wrapper de API de geolocalização

Outros artigos e tutoriais:

• Vídeo para todos! • “Uma

introdução suave à codificação de vídeo” • “Parâmetros

de tipo de vídeo” • O Apêndice

deste livro

Leitura adicional | 29

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

CAPÍTULO 3

O que tudo isso significa?

Mergulhando

Este capítulo pegará uma página HTML que não tem absolutamente nada de errado e a melhorará.
Partes dele ficarão mais curtas. As peças ficarão mais longas. Tudo isso se tornará mais semântico.
Vai ser incrível.

Aqui está a página em questão: http://diveintohtml5.org/examples/blog-original.html.


Aprenda. Viva isso. Adoro. Abra-o em uma nova guia e não volte até clicar em “Ver código-fonte” pelo
menos uma vez.

O tipo de documento

Do topo:
<!DOCTYPE
html PUBLIC "-//W3C//DTD XHTML 1.0
Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

Isso é chamado de tipo de documento. Há uma longa história – e uma arte negra – por trás do doctype.
Durante o desenvolvimento do Internet Explorer 5 para Mac, a Microsoft se deparou com um problema
surpreendente. A próxima versão de seu navegador melhorou tanto o suporte aos padrões que as
páginas mais antigas não eram mais renderizadas corretamente. Ou melhor, eles foram renderizados
corretamente (de acordo com as especificações), mas as pessoas esperavam que eles fossem
renderizados de maneira inadequada. As próprias páginas foram criadas com base nas peculiaridades
dos navegadores dominantes da época, principalmente Netscape 4 e Internet Explorer 4. O IE5/Mac
era tão avançado que realmente quebrou a Web.

A Microsoft apresentou uma solução inovadora. Antes de renderizar uma página, o IE5/Mac olhou para o
“doctype”, que normalmente é a primeira linha do código-fonte HTML (mesmo antes do elemento <html>).
Páginas mais antigas (que dependiam das peculiaridades de renderização de navegadores mais antigos)
geralmente não tinham nenhum tipo de documento. O IE5/Mac renderizou essas páginas como os
navegadores mais antigos. Para “ativar” o suporte aos novos padrões, os autores das páginas web tiveram
que optar por fornecer o tipo de documento correto antes do elemento <html>.

31

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Essa ideia se espalhou rapidamente e logo todos os principais navegadores tinham dois modos: “modo peculiaridades”
e “modo padrão”. É claro que, sendo esta a Web, as coisas rapidamente saíram do controle. Quando a Mozilla
tentou lançar a versão 1.1 de seu navegador, descobriu que havia páginas sendo renderizadas no modo padrão
que, na verdade, dependiam de uma peculiaridade específica. A Mozilla tinha acabado de consertar seu mecanismo
de renderização para eliminar essa peculiaridade e milhares de páginas quebraram de uma só vez. Assim foi criado
– e não estou inventando isso – o “ modo quase padrão”.

Em seu trabalho seminal, “Ativando Modos de Navegador com Doctype”, Henri Sivonen resume os diferentes
modos:

Modo Quirks No
modo Quirks, os navegadores violam as especificações contemporâneas de formato da Web para evitar
“quebrar” páginas criadas de acordo com práticas que eram predominantes no final da década de 1990.

Modo Padrões No

modo Padrões, os navegadores tentam dar aos documentos em conformidade o tratamento correto em termos
de especificação, na medida em que são implementados em um navegador específico.
O HTML5 chama esse modo de “modo sem peculiaridades”.
Modo quase padrão

Firefox, Safari, Chrome, Opera (desde 7.5) e IE8 também possuem um modo conhecido como “modo Quase
Padrões”, que implementa o dimensionamento vertical das células da tabela de forma tradicional e não
rigorosa de acordo com a especificação CSS2. O HTML5 chama esse modo de “modo de peculiaridades
limitadas”.

Você deveria ler o resto do artigo de Henri, porque estou simplificando imensamente
aqui. Mesmo no IE5/Mac, havia alguns tipos de documentos mais antigos que não
contavam para a opção de suporte a padrões. Com o tempo, a lista de peculiaridades
cresceu, assim como a lista de doctypes que acionaram o modo quirks.
A última vez que tentei contar, havia 5 doctypes que acionavam o modo quase padrão
e 73 que acionavam o modo quirks. Mas provavelmente perdi alguns, e nem vou falar
sobre as coisas que o Internet Explorer 8 faz para alternar entre seus quatro – quatro!
– modos de renderização diferentes. Há um fluxograma em http:// hsivonen.iki.fi/ doctype/
ie8-mode .png. Mate isso. Matá-lo com fogo.

Agora, então. Onde nós estávamos? Ah sim, o tipo de documento:


<!DOCTYPE
html PUBLIC "-//W3C//DTD XHTML 1.0
Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

Este é um dos 15 doctypes que acionam o modo padrão em todos os navegadores modernos. Não há nada de
errado com isso. Se você gostar, pode ficar com ele. Ou você pode alterá-lo para o tipo de documento HTML5, que
é mais curto e mais agradável e também aciona o modo padrão em todos os navegadores modernos.

32 | Capítulo 3: O que tudo isso significa?

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Este é o tipo de documento HTML5:


<!DOCTYPEhtml>

É isso. Apenas 15 caracteres. É tão fácil que você pode digitar à mão e não estragar tudo.

Professor Markup diz que seu

tipo de documento precisa estar na primeira linha do seu arquivo HTML. Se houver mais alguma coisa antes
dela - mesmo que seja uma única linha em branco - certos navegadores tratarão sua página como se ela
não tivesse nenhum tipo de documento. Sem um doctype, o navegador renderizará sua página no modo quirks.
Este pode ser um erro muito difícil de detectar. Espaços em branco extras geralmente não importam em
HTML, então meus olhos tendem a ignorá-los, mas neste caso são muito importantes!

O elemento raiz
Uma página HTML é uma série de elementos aninhados. Toda a estrutura da página é como uma árvore.
Alguns elementos são “irmãos”, como dois galhos que se estendem do mesmo tronco de árvore. Alguns
elementos podem ser “filhos” de outros elementos, como um galho menor que se estende de um galho
maior. (Funciona de outra maneira também; um elemento que contém outros elementos é chamado de nó
“pai” de seus elementos filhos imediatos e de “ancestral” de seus netos.) Elementos que não têm filhos são
chamados de nós “folha”.
O elemento mais externo, que é o ancestral de todos os outros elementos da página, é chamado de
“elemento raiz”. O elemento raiz de uma página HTML é sempre <html>.

Em nossa página de exemplo, o elemento raiz se parece com isto:

<html xmlns="http://www.w3.org/1999/xhtml"
lang="en"
xml:lang="en">

Não há nada de errado com essa marcação. Novamente, se você gostar, você pode mantê-lo. É HTML5
válido. Mas partes dele não são mais necessárias no HTML5, então você pode economizar alguns bytes
removendo-os.

A primeira coisa a discutir é o atributo xmlns . Este é um vestígio do XHTML 1.0. Diz que os elementos
desta página estão no namespace XHTML, http://www.w3.org/1999/xhtml. Mas os elementos no HTML5
estão sempre neste namespace, então você não precisa mais declará-lo explicitamente. Sua página HTML5
funcionará exatamente da mesma forma em todos os navegadores modernos, esteja este atributo presente
ou não.

Eliminar o atributo xmlns nos deixa com este elemento raiz:

<html lang="en" xml:lang="en">

O elemento raiz | 33

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Os dois atributos aqui, lang e xml:lang, definem o idioma desta página HTML. en significa “Inglês”.* Por
que dois atributos para a mesma coisa? Novamente, este é um vestígio de XHTML. Somente o atributo
lang tem efeito no HTML5. Você pode manter o atributo xml:lang se quiser, mas se quiser, você precisa
garantir que ele contenha o mesmo valor que o atributo lang :

Para facilitar a migração de e para XHTML, os autores podem especificar um atributo em nenhum espaço
de nome, sem prefixo e com o nome local literal “xml:lang” em elementos HTML em documentos HTML, mas
tais atributos só devem ser especificados se um atributo lang em nenhum namespace também é especificado
e ambos os atributos devem ter o mesmo valor quando comparados de maneira ASCII sem distinção entre
maiúsculas e minúsculas. O atributo sem namespace, sem prefixo e com o nome local literal “xml:lang” não
tem efeito no processamento da linguagem.

Você está pronto para abandoná-lo? Está tudo bem, apenas deixe para lá. Indo indo Foi! Isso nos deixa
com este elemento raiz:

<html lang="pt">

E isso é tudo que tenho a dizer sobre isso.

O elemento <head>
O primeiro filho do elemento raiz geralmente é o elemento <head> . O elemento <head> contém metadados
– informações sobre a página, em vez do corpo da página em si.
(O corpo da página está, sem surpresa, contido no elemento <body> .) O elemento <head> em si é
bastante chato e não mudou de nenhuma maneira interessante no HTML5. O bom é o que está dentro do
elemento <head> . E para isso, voltamos mais uma vez à nossa página de exemplo:

<cabeça>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />


<title>Meu blog</title> <link
rel="stylesheet" type="text/css" href ="style-original.css" /> <link rel="alternate"
type="application/atom+xml"
title="Feed do meu blog"
href="/feed/" />
<link rel="search" type="application/opensearchdescription+xml"
title="Pesquisa do meu
blog" href="opensearch.xml" /
> <link rel="ícone de atalho" href="/favicon.ico" /> </
head>

Primeiro: o elemento <meta> .

*
Não está escrevendo em inglês? Encontre o código do seu idioma em http:// www.w3.org/ International/ questions/ qa-choosing
-language-tags.

34 | Capítulo 3: O que tudo isso significa?

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Codificação de caracteres

Quando você pensa em “texto”, provavelmente pensa em “caracteres e símbolos que vejo na tela do meu
computador”. Mas os computadores não lidam com caracteres e símbolos; eles lidam com bits e bytes.
Cada pedaço de texto que você já viu na tela de um computador é, na verdade, armazenado em uma
codificação de caracteres específica. Existem muitas codificações de caracteres diferentes, algumas
otimizadas para idiomas específicos, como russo, chinês ou inglês, e outras que podem ser usadas para
vários idiomas. Grosso modo, a codificação de caracteres fornece um mapeamento entre o que você vê
na tela e o que seu computador realmente armazena na memória e no disco.

Na realidade, é mais complicado que isso. Muitos caracteres são comuns a múltiplas codificações, mas
cada codificação pode usar uma sequência diferente de bytes para armazenar esses caracteres na
memória ou no disco. Portanto, você pode pensar na codificação de caracteres como uma espécie de
chave de descriptografia do texto. Sempre que alguém fornece uma sequência de bytes e afirma que é
“texto”, você precisa saber qual codificação de caracteres ele usou para poder decodificar os bytes em
caracteres e exibi-los (ou processá-los, ou qualquer outra coisa).

Então, como seu navegador realmente determina a codificação de caracteres do fluxo de bytes que um
servidor web envia? Estou feliz que você perguntou. Se você estiver familiarizado com cabeçalhos HTTP,
talvez já tenha visto um cabeçalho como este:

Tipo de conteúdo: texto/html; conjunto de caracteres = "utf-8"

Resumidamente, isso indica que o servidor web pensa que está enviando um documento HTML e que o
documento usa a codificação de caracteres UTF-8 . Infelizmente, em toda a magnífica sopa da World
Wide Web, poucos autores realmente têm controle sobre seus servidores HTTP. Pense no Blogger: o
conteúdo é fornecido por indivíduos, mas os servidores são administrados pelo Google. Portanto, o HTML
4 forneceu uma maneira de especificar a codificação de caracteres no próprio documento HTML. Você
provavelmente já viu isso também:

<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

Resumidamente, isso indica que o autor da web pensa ter criado um documento HTML usando a
codificação de caracteres UTF-8 .

Ambas as técnicas ainda funcionam em HTML5. O cabeçalho HTTP é o método preferido e substitui a
tag <meta> , se presente. Mas nem todos podem definir cabeçalhos HTTP, então a tag <meta> ainda
existe. Na verdade, ficou um pouco mais fácil no HTML5. Agora fica assim:

<meta charset="utf-8" />

O elemento <head> | 35

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Isso funciona em todos os navegadores. Como surgiu essa sintaxe abreviada? Aqui está a melhor
explicação que pude encontrar:

A justificativa para a combinação de atributos <meta charset=""> é que os UAs já a implementam, porque
as pessoas tendem a deixar coisas sem aspas, como:

<META HTTP-EQUIV=Tipo de conteúdo CONTENT=text/html; conjunto de caracteres=ISO-8859-1>

Existem até alguns casos de teste <meta charset> , se você não acredita que os navegadores já fazem
isso.

Pergunte ao professor Markup

P: Eu nunca uso personagens engraçados. Ainda preciso declarar minha codificação de caracteres?

R: Sim! Você deve sempre especificar uma codificação de caracteres em cada página HTML que você veicula.
Não especificar uma codificação pode levar a vulnerabilidades de segurança.

Resumindo: a codificação de caracteres é complicada e não foi facilitada por várias décadas de
software mal escrito usado por autores com formação em copiar e colar.
Você deve sempre especificar uma codificação de caracteres em cada documento HTML, ou coisas
ruins acontecerão. Você pode fazer isso com o cabeçalho HTTP Content-Type , a declaração <meta
http equiv> ou a declaração <meta charset> mais curta , mas faça isso. A Web agradece.

Amigos e relacionamentos (links)

Links regulares (<a href>) simplesmente apontam para outra página. As relações de link são uma forma
de explicar por que você está apontando para outra página. Eles terminam a frase “Estou apontando
para esta outra página porque...”

• ...é uma folha de estilo contendo regras CSS que seu navegador deve aplicar a este
documento.

• ...é um feed que contém o mesmo conteúdo desta página, mas em um sub padrão
formato rabiscável.

• ...é uma tradução desta página para outro idioma. • ...é o mesmo
conteúdo desta página, mas em formato PDF. • ...é o próximo capítulo
de um livro online do qual esta página também faz parte.

E assim por diante. HTML5 divide as relações de link em duas categorias:

Duas categorias de links podem ser criadas usando o elemento link. Links para recursos externos são
links para recursos que serão usados para aumentar o documento atual, e links de hiperlink são links para
outros documentos. [...]

O comportamento exato dos links para recursos externos depende do relacionamento exato, conforme
definido para o tipo de link relevante.

36 | Capítulo 3: O que tudo isso significa?

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Dos exemplos que acabei de dar, apenas o primeiro (rel="stylesheet") é um link para um recurso externo. O restante
são hiperlinks para outros documentos. Você pode querer seguir esses links ou não, mas eles não são necessários
para visualizar a página atual.

Na maioria das vezes, as relações de link são vistas em elementos <link> dentro do <head> de uma página.
Algumas relações de link também podem ser usadas em elementos <a> , mas isso é incomum mesmo quando
permitido. HTML5 também permite algumas relações em elementos <area> , mas isso é ainda menos comum.
(HTML 4 não permitia um atributo rel em elementos <area> .) Veja o gráfico completo de relações de link para
verificar onde você pode usar valores rel específicos .

Pergunte ao Professor

Markup P: Posso criar minhas próprias relações de link?

R: Parece haver um suprimento infinito de ideias para novas relações de vínculo. Na


tentativa de evitar que as pessoas simplesmente inventem coisas , o Grupo de Trabalho O
QUE mantém um registro de valores rel propostos e define o processo para que sejam aceitos.

rel = folha de estilo

Vejamos a primeira relação de link em nossa página de exemplo:

<link rel="stylesheet" href="style-original.css" type="text/css" />

Esta é a relação de link usada com mais frequência no mundo (literalmente). <link rel="style sheet"> serve para
apontar para regras CSS que são armazenadas em um arquivo separado. Uma pequena otimização que você pode
fazer no HTML5 é eliminar o atributo type . Existe apenas uma linguagem de folha de estilo para a Web, CSS, então
esse é o valor padrão para o atributo type :

<link rel="stylesheet" href="style-original.css" />

Isso funciona em todos os navegadores. (Suponho que algum dia alguém poderia inventar uma nova linguagem de
folha de estilo, mas se isso acontecer, você pode simplesmente adicionar o atributo type de volta.)

rel = alternativo

Continuando com nossa página de exemplo:

<link rel="alternativo"
type="application/atom+xml"
title="Meu feed do blog"
href="/feed/" />

Essa relação de link também é bastante comum. <link rel="alternate">, combinado com o tipo de mídia RSS ou Atom
no atributo type , permite algo chamado “feed au todiscovery”. Ele permite leitores de feeds distribuídos como o
Google Reader descobrir que um site possui um feed de notícias com os artigos mais recentes. A maioria dos
navegadores também oferece suporte à descoberta automática de feeds, exibindo um ícone especial próximo ao
URL. (Ao contrário de rel="stylesheet", o atributo type é importante aqui. Não o deixe cair!)

O elemento <head> | 37

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

A relação de link rel="alternate" sempre foi um estranho híbrido de casos de uso, mesmo
em HTML 4. No HTML5, sua definição foi esclarecida e ampliada para descrever com mais precisão o
conteúdo da web existente. Como você acabou de ver, usar rel="alternate" em conjunto com
type=application/atom+xml indica um feed Atom para a página atual.
Mas você também pode usar rel="alternate" em conjunto com outros atributos de tipo para indicar o
mesmo conteúdo em outro formato, como PDF.

O HTML5 também acaba com uma confusão de longa data sobre como vincular traduções de documentos.
HTML 4 diz para usar o atributo lang em conjunto com rel="alter
nate" para especificar o idioma do documento vinculado, mas isso está incorreto. O HTML
4 Erratas lista quatro erros completos nas especificações do HTML 4 (junto com vários detalhes editoriais);
um desses erros flagrantes é como especificar o idioma de um documento vinculado a
rel="alternativo". (A maneira correta, descrita no documento HTML 4 Errata e
agora em HTML5, é usar o atributo hreflang .) Infelizmente, essas erratas nunca foram
reintegrado na especificação HTML 4, porque ninguém no Grupo de Trabalho HTML do W3C
estava mais trabalhando em HTML.

Outras relações de link em HTML5

rel="arquivos"
(http:// bit.ly/ clzlyG) “indica que o documento referenciado descreve uma coleção
de registros, documentos ou outros materiais de interesse histórico. A página de índice de um blog
poderia vincular a um índice de postagens anteriores do blog com rel="archives".”

rel="autor"
é usado para vincular informações sobre o autor da página. Este pode ser um mailto:
endereço, embora não precise ser. Poderia simplesmente vincular a um formulário de contato ou
página “sobre o autor”.

rel="externo"
(http:// bit.ly/ dBVO09) “indica que o link leva a um documento que não é
parte do site do qual o documento atual faz parte.” acredito que foi o primeiro
popularizado pelo WordPress, que o utiliza em links deixados por comentaristas.

rel="iniciar", rel="anterior" e rel="próximo"


(http:// www.w3.org/ TR/ html401/ types.html#type-links) definir relações entre páginas que fazem
parte de uma série (como capítulos de um livro, ou mesmo postagens em um
blog). O único que foi usado corretamente foi rel="next". Pessoas usaram
rel="anterior" em vez de rel="anterior"; eles usaram rel="begin" e rel="first" em vez de rel="start";
eles usaram rel="end" em vez de rel="last". Ah, e - tudo por
eles próprios - eles criaram rel="up" para apontar para uma página “pai”.
HTML5 inclui rel="first", que era a variação mais comum das diferentes maneiras de dizer “primeira
página de uma série”. (rel="start" é um sinônimo não conforme, fornecido para compatibilidade com
versões anteriores.) Também inclui rel="prev" e
rel="next", assim como HTML 4 (e suporta rel="previous", para retrocesso com

38 | Capítulo 3: O que tudo isso significa?

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

compatibilidade), bem como rel="last" (o último de uma série, espelhando rel="first") e rel="up".

A melhor maneira de pensar em rel="up" é observar sua navegação estrutural (ou pelo menos
imaginá-la). Sua página inicial é provavelmente a primeira página na localização atual, e a
página atual está no final. rel="up" aponta para a penúltima página na localização atual.

rel="ícone"
(http:// bit.ly/ diAJUP) é a segunda relação de link mais popular, depois de rel="folha de estilo".
Geralmente é encontrado junto com o atalho, assim:

<link rel="ícone de atalho" href="/favicon.ico">


Todos os principais navegadores suportam esse uso para associar um pequeno ícone à página.
Geralmente é exibido na barra de localização do navegador ao lado do URL, ou na guia do
navegador, ou em ambos.
Outra novidade no HTML5: o atributo tamanhos pode ser usado em conjunto com o
relacionamento do ícone para indicar o tamanho do ícone referenciado.
rel="licença"
(http:// bit.ly/ 9n9Xfv) foi inventado pela comunidade de microformatos. “Indica que o documento
referenciado fornece os termos de licença de direitos autorais sob os quais o documento atual
é fornecido”.
rel="nofollow"
(http:// bit.ly/ cGjSPi) “indica que o link não é endossado pelo autor ou editor original da página,
ou que o link para o documento referenciado foi incluído principalmente devido a uma relação
comercial entre pessoas afiliadas às duas páginas.” Foi inventado pelo Google e padronizado
dentro da comunidade de microformatos. A ideia era que se os links “nofollow” não passassem
no PageRank, os spammers desistiriam de tentar postar comentários de spam em blogs. Isso
não aconteceu, mas rel="nofollow" persiste. Muitos sistemas de blog populares adicionam
rel="nofollow" aos links adicionados pelos comentaristas.

rel="noreferrer" (http://
bit.ly/ cQMSJg) “indica que nenhuma informação de referência será vazada ao seguir o link.”
Nenhum navegador de remessa atualmente oferece suporte para isso, mas o suporte foi
adicionado recentemente às noites do WebKit, então eventualmente aparecerá no Safari,
Google Chrome e outros navegadores baseados em WebKit. Você pode encontrar um caso de
teste rel="noreferrer" em http:// wearehugh.com/ public/ 2009/04/ rel-
noreferrer.html.
rel="pingback" (http://bit.ly/ cIAGXB) especifica o endereço de um servidor “pingback”. Conforme
explicado na especificação Pingback, “O sistema de pingback é uma forma de um blog ser
notificado automaticamente quando outros sites possuem links para ele. [...] Permite a vinculação
reversa - uma forma de voltar a subir uma cadeia de elos, em vez de apenas aprofundar. Os
sistemas de blog, principalmente o WordPress, implementam o mecanismo de pingback para
notificar os autores de que você criou um link para eles ao criar uma nova postagem no blog.

O elemento <head> | 39

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

rel="pré-busca" (http://
bit.ly/ 9o0nMS) “indica que a busca preventiva e o armazenamento em cache do recurso especificado
provavelmente serão benéficos, pois é altamente provável que o usuário precise desse recurso.” Às vezes,
os mecanismos de pesquisa adicionam <link rel="prefetch" href="<empha sis>URL DO PRINCIPAL
RESULTADO DE PESQUISA</emphasis>"> à página de resultados de pesquisa se acharem que o
resultado principal é muito mais popular do que qualquer outro. Por exemplo: usando Fire fox, pesquise
CNN no Google, visualize o código-fonte da página e pesquise a pré-busca de palavra-chave. Mozilla Firefox
é o único navegador atual que suporta rel="prefetch".

rel="pesquisar"
(http:// bit.ly/ aApkaP) “indica que o documento referenciado fornece uma interface específica para pesquisar
o documento e seus recursos relacionados.” Especificamente, se você quiser que rel="search" faça algo
útil, ele deve apontar para uma pesquisa aberta documento que descreve como um navegador pode
construir uma URL para pesquisar uma determinada palavra-chave no site atual. OpenSearch (e links

rel="search" que apontam para documentos de descrição do OpenSearch) tem suporte no Microsoft Internet
Explorer desde a versão 7 e no Mozilla Firefox desde a versão 2.

rel="barra lateral"
(http:// bit.ly/ azTA9D) “indica que o documento referenciado, se recuperado, tende a ser mostrado em um
contexto de navegação secundário (se possível), em vez de no contexto de navegação atual.” O que isso
significa? No Opera e no Mozilla Firefox, significa “quando clico neste link, solicita ao usuário que crie um
marcador que, quando selecionado no menu Marcadores, abre o documento vinculado na barra lateral do
navegador”. (Na verdade, o Opera o chama de “painel” em vez de “barra lateral”.) Internet Explorer, Safari
e Chrome ignoram rel="sidebar" e tratam-no apenas como um link normal.

Você pode encontrar um caso de teste rel="sidebar" em http:// wearehugh.com/ public/ 2009/04/ rel
-sidebar.html.

rel="tag" (http://
bit.ly/ 9bYlfa) “indica que a tag que o documento referenciado representa se aplica ao documento atual.” A
marcação de “tags” (palavras-chave de categoria) com o atributo rel foi inventada pela Technorati para
ajudar na categorização das postagens do blog. Os primeiros blogs e tutoriais referiam-se a eles como “tags
Technorati”.
(Você leu certo: uma empresa comercial convenceu o mundo inteiro a adicionar metadados que facilitaram
o trabalho da empresa. Bom trabalho, se você conseguir!) A sintaxe foi posteriormente padronizada na
comunidade de microformatos, onde foi simplesmente chamado de rel="tag". A maioria dos sistemas de
blog que permitem associar categorias, palavras-chave ou tags a postagens individuais irá marcá-las com
links rel="tag" .
Os navegadores não fazem nada de especial com eles; eles são realmente projetados para serem usados
pelos mecanismos de pesquisa como um sinal do assunto da página.

40 | Capítulo 3: O que tudo isso significa?

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Novos elementos semânticos em HTML5

O HTML5 não se trata apenas de tornar a marcação existente mais curta (embora faça bastante disso). Também define uma série de novos elementos

semânticos. Os seguintes elementos são definidos pela especificação HTML5:

<section> O elemento de seção representa uma seção genérica de um documento ou aplicativo. Uma seção, neste contexto, é um agrupamento temático

de conteúdo, normalmente com um título. Exemplos de seções seriam os capítulos, as diversas páginas com guias em uma caixa de

diálogo com guias ou as seções numeradas de uma tese. A página inicial de um site pode ser dividida em diferentes seções para

introdução, notícias e informações de contato.

<nenhum> O elemento nav representa uma seção de uma página vinculada a outras páginas ou a partes da página: uma seção com links de

navegação. Nem todos os grupos de links em uma página precisam estar em um elemento nav – somente seções que consistem em

blocos de navegação principais são apropriadas para o elemento nav. Em particular, é comum que os rodapés tenham uma pequena

lista de links para várias páginas de um site, como termos de serviço, página inicial e página de direitos autorais. O elemento footer
sozinho é suficiente para tais casos, sem um elemento nav.

<article> O elemento article representa uma composição independente em um documento, página, aplicativo ou site que se destina a ser distribuído de

forma independente ou reutilizável, por exemplo, em distribuição. Pode ser uma postagem em um fórum, um artigo de revista ou

jornal, uma entrada de blog, um comentário enviado por um usuário, um widget ou gadget interativo ou qualquer outro item de

conteúdo independente.

<à parte> O elemento aparte representa uma seção de uma página que consiste em conteúdo tangencialmente relacionado ao conteúdo ao

redor do elemento aparte e que pode ser considerado separado desse conteúdo. Essas seções são frequentemente representadas

como barras laterais na tipografia impressa. O elemento pode ser usado para efeitos tipográficos, como citações ou barras laterais,

para publicidade, para grupos de elementos de navegação e para outros conteúdos considerados separados do conteúdo principal

da página.

<hgrupo> O elemento hgroup representa o título de uma seção. O elemento é usado para agrupar um conjunto de elementos h1–h6 quando o

título tem vários níveis, como subtítulos, títulos alternativos ou slogans.

<cabeçalho> O elemento header representa um grupo de auxílios introdutórios ou de navegação. Um elemento de cabeçalho geralmente contém

o título da seção (um elemento h1–h6 ou um elemento hgroup), mas isso não é obrigatório.

O elemento header também pode ser usado para agrupar o índice de uma seção, um formulário de pesquisa ou qualquer logotipo relevante.

<rodapé> O elemento footer representa um rodapé para seu conteúdo de seccionamento ancestral mais próximo ou elemento raiz de seccionamento.

Um rodapé normalmente contém informações sobre sua seção, como quem o escreveu, links para documentos relacionados,

dados de direitos autorais e assim por diante. Os rodapés não precisam necessariamente aparecer no final de uma seção, embora

normalmente apareçam. Quando o elemento de rodapé contém seções inteiras, eles representam apêndices, índices, colofões

longos, contratos de licença detalhados e outros conteúdos semelhantes.

<tempo> O elemento de tempo representa uma hora em um relógio de 24 horas ou uma data precisa no calendário gregoriano proléptico,

opcionalmente com uma hora e um deslocamento de fuso horário.

<marca> O elemento mark representa uma sequência de texto em um documento marcado ou destacado para fins de referência.

Sei que você está ansioso para começar a usar esses novos elementos, ou não estaria lendo este capítulo. Mas primeiro precisamos fazer um pequeno desvio.

Novos elementos semânticos em HTML5 | 41

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Uma longa digressão sobre como os navegadores lidam


Elementos desconhecidos

Cada navegador possui uma lista mestra de elementos HTML que suporta. Por exemplo, a lista do
Mozilla Firefox é armazenada em nsElementTable.cpp. Os elementos que não estão nesta lista são
tratados como “elementos desconhecidos”. Existem duas questões fundamentais em relação a
elementos desconhecidos:

Como o elemento deve ser estilizado?


Por padrão, <p> possui espaçamento na parte superior e inferior, <blockquote> é recuado com
uma margem esquerda e <h1> é exibido em uma fonte maior.
Qual deve ser a aparência do DOM do elemento?
O nsElementTable.cpp da Mozilla inclui informações sobre quais tipos de outros elementos
cada elemento pode conter. Se você incluir marcações como <p><p>, o segundo elemento de
parágrafo fechará implicitamente o primeiro, de modo que os elementos acabarão como irmãos,
não como pai e filho. Mas se você escrever <p><span>, o span não fecha o parágrafo, porque
o Firefox sabe que <p> é um elemento de bloco que pode conter o elemento inline <span>.
Portanto, o <span> acaba como filho do <p> no DOM.

Diferentes navegadores respondem a essas perguntas de maneiras diferentes. (Chocante, eu sei.)


Dos principais navegadores, a resposta do Microsoft Internet Explorer a ambas as perguntas é a mais
problemática.

A primeira pergunta deve ser relativamente simples de responder: não dê nenhum estilo especial a
elementos desconhecidos. Apenas deixe-os herdar quaisquer propriedades CSS em vigor onde quer
que apareçam na página e deixe o autor da página especificar todos os estilos com CSS.
Infelizmente, o Internet Explorer (anterior à versão 9) não permite estilização de elementos
desconhecidos. Por exemplo, se você tivesse esta marcação:
<style type="texto/css">
artigo {exibição: bloco; borda: 1px vermelho sólido }
</style>
...
<article>
<h1>Bem-vindo à Initech</
h1> <p>Este é seu <span>primeiro dia.</p>
</article>

O Internet Explorer (até IE 8 inclusive) não colocará uma borda vermelha ao redor do artigo.
Enquanto escrevo isto, o Internet Explorer 9 ainda está na versão beta, mas a Microsoft declarou (e
os desenvolvedores verificaram) que o Internet Explorer 9 não terá esse problema.

O segundo problema é o DOM que os navegadores criam quando encontram elementos desconhecidos.
Novamente, o navegador mais problemático é o Internet Explorer. Se o IE não reconhecer
explicitamente o nome do elemento, ele inserirá o elemento no DOM como um nó vazio sem filhos.
Todos os elementos que você esperaria que fossem filhos diretos do elemento desconhecido serão,
na verdade, inseridos como irmãos.

42 | Capítulo 3: O que tudo isso significa?

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Aqui está alguma arte ASCII para mostrar a diferença. Este é o DOM que o HTML5 dita:

artigo |

+--h1 (filho do artigo) | | +--nó


|
de texto "Bem-vindo à Initech" | +--p (filho do

artigo, irmão de h1)


"
| +--text node "Este é o seu | +--

span | | |
+--
text node "primeiro dia" | +--text

node "."

Mas este é o DOM que o Internet Explorer realmente cria:


artigo (sem filhos) h1
(irmão do artigo) | +--nó de

texto "Bem-vindo ao Initech" p (irmão de


h1) | +--text node
"
"Este é o seu | +--span | | | +--text

node

"primeiro dia" | +--text node "."

Existe uma solução maravilhosa para esse problema. Se você criar um <article> fictício elemento
com JavaScript antes de usá-lo em sua página, o Internet Explorer reconhecerá magicamente o
elemento <article> e permitirá que você o estilize com CSS. Não há necessidade de inserir o
elemento fictício no DOM. Simplesmente criar o elemento uma vez (por página) é suficiente para
ensinar o IE a estilizar o elemento que ele não reconhece. Por exemplo:
<html>
<cabeça>
<estilo>
artigo {display: bloco; borda: 1px vermelho sólido } </style>

<script>document.createElement("article");</script> </head>
<body>
<article>
<h1>Bem-
vindo ao Initech</h1> <p>Este é
seu <span>primeiro dia.</p> </article> </body> </html>

Uma longa digressão sobre como os navegadores lidam com elementos desconhecidos | 43

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Isso funciona em todas as versões do Internet Explorer, desde o IE 6! Podemos estender essa
técnica para criar cópias fictícias de todos os novos elementos HTML5 de uma só vez - novamente,
eles nunca são inseridos no DOM, então você nunca verá esses elementos fictícios - e então
começar a usá-los sem se preocupar também muito sobre navegadores não compatíveis com
HTML5.

Remy Sharp fez exatamente isso, com seu apropriadamente chamado “script de ativação HTML5”.
O script passou por diversas revisões, mas esta é a ideia básica:
<!--[if lt IE 9]>
<script>
var e = ("abbr,article,aside,audio,canvas,datalist,details," +
"figure,footer,header,hgroup,mark,menu,meter, nav,saída,"
+ "progresso,seção,tempo,vídeo").split(',');
for (var i = 0; i < e.length; i++)
{ document.createElement(e[i]); }

</script>
<![endif]-->
Os bits <!--[if lt IE 9]> e <![endif]--> são comentários condicionais. O Internet Explorer os interpreta
como uma instrução if : “se o navegador atual for uma versão do Internet Explorer inferior à versão
9, execute este bloco”. Todos os outros navegadores tratarão o bloco inteiro como um comentário
HTML. O resultado líquido é que o Internet Explorer (até a versão 8 inclusive) executará esse script,
mas outros navegadores o ignorarão completamente. Isso faz com que sua página carregue mais
rápido em navegadores que não precisam desse hack.

O código JavaScript em si é relativamente simples. A variável e termina como um array de strings


como "abbr", "article", "aside" e assim por diante. Em seguida, percorremos esse array e criamos
cada um dos elementos nomeados chamando document.createElement(). Mas como ignoramos
o valor de retorno, os elementos nunca são inseridos no DOM. Ainda assim, isso é suficiente
para fazer com que o Internet Explorer trate esses elementos da maneira que desejamos que
sejam tratados quando realmente os usarmos posteriormente na página.

Essa parte “mais tarde” é importante. Este script precisa estar no topo da sua página – de
preferência no elemento <head> – e não na parte inferior. Dessa forma, o Internet Explorer
executará o script antes de analisar suas tags e atributos. Se você colocar esse script no final da
sua página, será tarde demais. O Internet Explorer já terá interpretado mal sua marcação e
construído o DOM errado, e não irá voltar atrás e ajustá-lo apenas por causa deste script.

Remy Sharp “minificou” este script e o hospedou no Google Project Hosting. (Caso você esteja se
perguntando, o script em si é de código aberto e licenciado pelo MIT, então você pode usá-lo em
qualquer projeto.) Se desejar, você pode até fazer um “hotlink” do script apontando diretamente
para a versão hospedada, como este :

<head> <meta
charset="utf-8" />
<title>Meu blog</
title> <!--[if lt IE 9]> <script src="http://html5shiv.googlecode.com/svn /trunk/html5.js"></script>

44 | Capítulo 3: O que tudo isso significa?

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

<![endif]--> </
head>

Agora estamos prontos para começar a usar os novos elementos semânticos no HTML5.

Cabeçalhos

Vamos voltar à nossa página de exemplo. Especificamente, vejamos os cabeçalhos:


<div id="cabeçalho">
<h1>Meu blog</h1>
<p class="tagline">Muito esforço foi feito para tornar isso fácil.</p> </div>

...

<div class="entrada">
<h2>Dia de viagem</
h2> </div>

...

<div class="entry">
<h2>Vou para Praga!</h2> </div>

Não há nada de errado com essa marcação. Se você gostar, pode ficar com ele. É HTML5 válido. Mas o
HTML5 fornece alguns elementos semânticos adicionais para cabeçalhos e seções.

Primeiro, vamos nos livrar disso <div id="header">. Este é um padrão muito comum, mas não significa nada.
O elemento div não possui semântica definida e o atributo id não possui semântica definida. (Os agentes do
usuário não têm permissão para inferir qualquer significado do valor do atributo id .) Você poderia mudar
isso para <div id="shazbot"> e teria o mesmo valor semântico, ou seja, nada.

HTML5 define um elemento <header> para essa finalidade. A especificação HTML5 tem vários exemplos
do mundo real de usar o elemento <header> . Aqui está como ficaria em nossa página de exemplo:

<cabeçalho>

<h1>Meu blog</h1>
<p class="tagline">Muito esforço foi feito para tornar isso fácil.</p>
...
</header>

Isso é bom. Diz a quem quiser saber que se trata de um cabeçalho. Mas e quanto a esse slogan? Outro
padrão comum, que até agora não tinha marcação padrão.
É uma coisa difícil de marcar. Um slogan é como um subtítulo, mas está “anexado” ao título principal. Ou
seja, é um subtítulo que não cria seção própria.

Cabeçalhos | 45

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Elementos de cabeçalho como <h1> e <h2> fornecem a estrutura da sua página. Juntos, eles criam
um esboço que você pode usar para visualizar (ou navegar) em sua página. Os leitores de tela usam
contornos de documentos para ajudar usuários cegos a navegar pela sua página. Existem
ferramentas online e extensões de navegador que pode ajudá-lo a visualizar o esboço do seu documento.

No HTML 4, os elementos <h1>–<h6> eram a única maneira de criar um esboço de documento. O


esboço na página de exemplo é assim: Meu
Weblog (h1) |

+--Dia de viagem

(h2) | +--Estou indo para Praga! (h2)

Tudo bem, mas significa que não há como marcar o slogan “Muito esforço foi feito para tornar isso
fácil”. Se tentássemos marcá-lo como <h2>, adicionaríamos um nó fantasma ao esboço do
documento:

Meu blog (h1) |

+--Muito esforço foi feito para tornar isso fácil. (h2) | +--Dia de viagem

(h2) | +--Estou indo

para Praga! (h2)

Mas essa não é a estrutura do documento. O slogan não representa uma seção; é apenas um
subtítulo.

Talvez pudéssemos marcar o slogan como <h2> e marcar cada título de artigo como <h3>? Não,
isso é ainda pior: Meu Weblog
(h1) | +--Muito

esforço foi feito para tornar isso fácil. (h2)

| +--Dia de viagem

(h3) | +--Estou indo para Praga! (h3)

Agora ainda temos um nó fantasma em nosso esboço do documento, mas ele “roubou” os filhos que
pertencem por direito ao nó raiz. E é aqui que reside o problema: o HTML 4 não fornece uma maneira
de marcar um subtítulo sem adicioná-lo ao esboço do documento. Não importa o quanto tentemos
mudar as coisas, “muito esforço foi feito para tornar isso fácil” vai acabar naquele gráfico. E é por
isso que acabamos com uma marcação semanticamente sem sentido como <p class="tagline">.

HTML5 fornece uma solução para isso: o elemento <hgroup> . O elemento <hgroup> atua como um
wrapper para dois ou mais elementos de cabeçalho relacionados . O que significa “relacionado”?
Isso significa que, em conjunto, eles criam um único nó no esboço do documento.

Dada esta marcação:

46 | Capítulo 3: O que tudo isso significa?

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

<header>
<hgroup>
<h1>Meu blog</h1>
<h2> Muito esforço foi feito para tornar isso fácil.</h2> </hgroup>

...
</header>

...

<div class="entrada">
<h2>Dia de viagem</
h2> </div>

...

<div class="entry">
<h2>Vou para Praga!</h2> </div>

Este é o esboço do documento criado:

Meu Weblog (h1 do seu hgroup)

| +--Dia de viagem

(h2) | +--Estou indo para Praga! (h2)

Você pode testar suas próprias páginas no HTML5 Outliner para garantir que você está usando os
elementos de título corretamente.

Artigos
Continuando com nossa página de exemplo, vamos ver o que podemos fazer sobre essa marcação:

<div class="entrada">
<p class="post-date">22 de outubro de 2009</p>
<h2>
<a href="#"
rel="bookmark"
title="link para esta postagem">
Dia de viagem
</a>
</h2>
...
</div>

Novamente, este é HTML5 válido. Mas o HTML5 fornece um elemento mais específico para o caso comum
de marcação de um artigo em uma página – o elemento <article> apropriadamente chamado:
<article>
<p class="post-date">22 de outubro de 2009</
p>
<h2> <a
href="#" rel="bookmark"

Artigos | 47

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

title="link para esta postagem">


Dia de viagem
</a>
</h2>
...
</artigo>

Ah, mas não é tão simples assim. Há mais uma mudança que você deve fazer. Vou mostrar para você
primeiro e depois explicar:
<article>
<header>
<p class="post-date">22 de outubro de 2009</p>

<h1> <a
href="#"
rel="bookmark" title="link para esta postagem">
Dia de

viagem
</a> </h1> </header>
...
</artigo>

Você percebeu isso? Mudei o elemento <h2> para um <h1> e coloquei-o dentro de um elemento
<header> . Você já viu o elemento <header> em ação. Sua finalidade é agrupar todos os elementos
que formam o cabeçalho do artigo (neste caso, a data de publicação e o título do artigo).
Mas...mas...mas...você não deveria ter apenas um <h1> por documento? Isso não vai estragar o
esboço do documento? Não, mas para entender por que não, precisamos recuar um passo.

No HTML 4, a única maneira de criar um esboço de documento era com os elementos <h1>–<h6> .
Se você quisesse apenas um nó raiz em seu esboço, teria que se limitar a um <h1> em sua marcação.
Mas a especificação HTML5 define um algoritmo para gerar um esboço de documento que incorpora
os novos elementos semânticos do HTML5. O algoritmo HTML5 diz que um elemento <article> cria
uma nova seção, ou seja, um novo nó no esboço do documento. E no HTML5, cada seção pode ter
seu próprio elemento <h1> .

Esta é uma mudança drástica em relação ao HTML 4 e é por isso que é uma coisa boa. Muitas páginas
da web são realmente geradas por modelos. Um pouco do conteúdo é retirado de uma fonte e inserido
na página aqui em cima; um pouco do conteúdo é retirado de outra fonte e inserido na página ali
embaixo. Muitos tutoriais são estruturados da mesma maneira. “Aqui estão algumas marcações HTML.
Basta copiá-lo e colá-lo em sua página.” Isso é bom para pequenos pedaços de conteúdo, mas e se a
marcação que você está colando for uma seção inteira? Nesse caso, o tutorial será mais ou menos
assim: “Aqui estão algumas marcações HTML. Basta copiá-lo, colá-lo em um editor de texto e corrigir
as tags de título para que correspondam ao nível de aninhamento das tags de título correspondentes
na página em que você está colando.”

Deixe-me explicar de outra forma. HTML 4 não possui elemento de título genérico . Possui seis
elementos de título estritamente numerados, <h1>–<h6>, que devem ser aninhados exatamente nessa ordem.

48 | Capítulo 3: O que tudo isso significa?

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Isso é uma droga, especialmente se sua página for “montada” em vez de “de autoria”. E este é o
problema que o HTML5 resolve com os novos elementos de seccionamento e as novas regras para
os elementos de título existentes. Se você estiver usando os novos elementos de seccionamento,
posso fornecer esta marcação:
<article>
<header>
<h1>Uma postagem distribuída</
h1> </
header> <p>Lorem ipsum blá blá...</
p> </article>

e você pode copiá-lo e colá-lo em qualquer lugar da sua página sem modificação. O fato de conter
um elemento <h1> não é um problema, porque tudo está contido em um <article>. O elemento
<article> define um nó independente no esboço do documento, o elemento <h1> fornece o título
para esse nó do esboço e todos os outros elementos de seccionamento na página permanecerão
em qualquer nível de aninhamento em que estavam antes.

O Professor Markup Diz Como

acontece com todas as coisas na Web, a realidade é um pouco mais complicada do que estou deixando transparecer.

Os novos elementos de seccionamento “explícitos” (como <h1> agrupados em <article>)


podem interagir de maneiras inesperadas com os antigos elementos de seccionamento
“implícitos” (<h1>–<h6> por si só). Sua vida será mais simples se você usar um ou outro, mas
não ambos. Se você precisar usar ambos na mesma página, verifique o resultado no HTML5
Outliner e verifique se o esboço do seu documento faz sentido.

Datas e horários
Isso é emocionante, certo? Quero dizer, não é emocionante “esquiar nu no Monte Everest enquanto
recita o Star Spangled Banner de trás para frente”, mas é muito emocionante no que diz respeito à
marcação semântica. Vamos continuar com nossa página de exemplo. A próxima linha que quero
destacar é esta:

<div class="entrada">
<p class="post-date">22 de outubro de 2009</
p> <h2>Dia da viagem</
h2> </div>

A mesma velha história, certo? Um padrão comum – designando a data de publicação de um artigo
– que não possui marcação semântica para apoiá-lo, então os autores recorrem à marcação genérica
com atributos de classe personalizados . Novamente, este é HTML5 válido. Você não é obrigado a
alterá-lo. Mas o HTML5 fornece uma solução específica para este caso – o elemento <time> :
<time datetime="2009-10-22" pubdate>22 de outubro de 2009</time>

Existem três partes em um elemento <time> :

Datas e horários | 49

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

• Um carimbo de data/hora legível por


máquina • Conteúdo de texto legível por humanos

• Um sinalizador de publicação opcional

Neste exemplo, o atributo datetime especifica apenas uma data, não uma hora. O formato é um ano de quatro dígitos, um mês
de dois dígitos e um dia de dois dígitos, separados por travessões: <time datetime="2009-10-22" pubdate>22

de outubro de 2009</time>

Se você quiser incluir uma hora também, adicione a letra T após a data, depois a hora no formato de 24 horas e,
em seguida, um deslocamento de fuso horário:

<hora datetime="2009-10-22T13:59:47-04:00" publicação>


22 de outubro de 2009, 13h59 EDT </
time>

O formato de data/hora é bastante flexível. A especificação HTML5 contém vários exemplos de strings de data/
hora válidas.

Observe que alterei o conteúdo do texto — o que está entre <time> e </time> — para corresponder ao carimbo de
data/hora legível por máquina. Na verdade, isso não é necessário. O conteúdo do texto pode ser o que você
quiser, desde que você forneça uma data/carimbo de data/hora legível por máquina no atributo datetime . Portanto,
este é HTML5 válido:

<time datetime="2009-10-22"> quinta-feira passada</time>

E isso também é HTML5 válido:

<hora datetime="2009-10-22"></hora>

A peça final do quebra-cabeça aqui é o atributo pubdate . É um atributo booleano, então basta adicioná-lo se
precisar, assim:

<time datetime="2009-10-22" pubdate>22 de outubro de 2009</time>

Se você não gosta de atributos “nus”, isso também é equivalente:

<time datetime="2009-10-22" pubdate="pubdate"> 22 de outubro de 2009</time>

O que significa o atributo pubdate ? Significa uma de duas coisas. Se o elemento <time> estiver em um elemento
<article> , significa que este carimbo de data/hora é a data de publicação do artigo. Se o elemento <time> não
estiver em um elemento <article> , significa que este carimbo de data/hora é a data de publicação de todo o
documento.

Aqui está o artigo completo, reformulado para aproveitar ao máximo o HTML5:

<artigo>
<cabeçalho>
<hora datetime="2009-10-22" pubdate>
22 de outubro de 2009
</time>
<h1>
<a href="#"
rel="favorito"
title="link para esta postagem">
Dia de viagem

50 | Capítulo 3: O que tudo isso significa?

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

</
a> </
h1> </
header> <p>A dor em si é importante...</
p> </article>

Navegação
Uma das partes mais importantes de qualquer site é a barra de navegação. CNN.com tem “guias” na parte
superior de cada página com links para diferentes seções de notícias – “Tecnologia”,
“Saúde”, “Esportes” etc. As páginas de resultados de pesquisa do Google têm uma faixa semelhante na
parte superior da página, permitindo que você tente sua pesquisa em diferentes serviços do Google - “Imagens”,
“Vídeo”, “Mapas” etc. E nossa página de exemplo tem uma barra de navegação no cabeçalho que inclui
links para diferentes seções de nosso site hipotético – “página inicial”, “blog”, “galeria” e “sobre”.

É assim que a barra de navegação foi originalmente marcada:


<div id="nav">
<ul>
<li><a href="#">página inicial</
a></li> <li><a href="#">blog</
a></li > <li><a href="#">galeria</
a></li> <li><a href="#">sobre</
a></
li> </ul> </div>

Novamente, este é HTML5 válido. Mas embora esteja marcada como uma lista de quatro itens, não há nada
na lista que diga que ela faz parte da navegação do site. Visualmente, você pode adivinhar isso pelo fato de
fazer parte do cabeçalho da página e pela leitura do texto dos links. Mas semanticamente, não há nada que
distinga esta lista de links de qualquer outra.

Quem se importa com a semântica da navegação no site? Por um lado, pessoas com deficiência.
Por que é que? Considere este cenário: seu movimento é limitado e usar o mouse é difícil ou impossível.
Para compensar, você pode usar um complemento do navegador que permite pular para (ou pular) os
principais links de navegação. Ou considere o seguinte: sua visão é limitada e você usa um programa
dedicado chamado “leitor de tela”, que usa conversão de texto em fala para falar e resumir páginas da web.
Depois de passar pelo título da página, as próximas informações importantes sobre uma página são os
principais links de navegação. Se quiser navegar rapidamente, você dirá ao leitor de tela para ir até a barra
de navegação e começar a ler. Se quiser navegar rapidamente, você pode dizer ao seu leitor de tela para
pular a barra de navegação e começar a ler o conteúdo principal. De qualquer forma, é importante ser capaz
de determinar links de navegação programaticamente.

Portanto, embora não haja nada de errado em usar <div id="nav"> para marcar a navegação do seu site,
também não há nada particularmente certo nisso. É abaixo do ideal de uma forma que afeta pessoas reais.
HTML5 fornece uma maneira semântica de marcar seções de navegação — o elemento <nav> :

Navegação | 51

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

<nav>
<ul>
<li><a href="#">página inicial</a></
li> <li><a href="#">blog</a></li>
<li>< uma href="#">galeria</a></li>
<li><a href="#">sobre</a></li> </ul>
</
nav>

Pergunte ao Professor

Markup P: Os links são ignorados? compatível com o elemento <nav> ? Ainda preciso pular links em HTML5?

R: Links para pular permitem que os leitores pulem as seções de navegação. Eles são úteis para
usuários com deficiência que usam software de terceiros para ler uma página da web em voz alta e
navegar nela sem o mouse. Saiba como e por que fornecer links para pular em http:// www.webaim.org/
techniques/ skipnav .

Depois que os leitores de tela forem atualizados para reconhecer o elemento <nav> , os links para
pular se tornarão obsoletos, uma vez que o software leitor de tela será capaz de oferecer
automaticamente para pular uma seção de navegação marcada com o elemento <nav> . No entanto,
levará um tempo até que todos os usuários deficientes na Web atualizem para um software leitor de
tela compatível com HTML5, portanto, você deve continuar a fornecer seus próprios links de pular para
pular as seções <nav> .

Rodapés
Finalmente chegamos ao final da nossa página de exemplo. A última coisa que quero falar é a última
coisa da página: o rodapé. O rodapé foi originalmente marcado assim:

<div id="footer">
<p>&#167;</p>
<p>&#169; 2001&#8211;9 <a href="#">Marco Peregrino</a></p> </
div>

Este é HTML5 válido. Se você gostar, pode ficar com ele. Mas o HTML5 fornece um elemento mais
específico para isso — o elemento <footer> :
<footer>
<p>&#167;</p>
<p>&#169; 2001&#8211;9 <a href="#">Mark Pilgrim</a></p> </
footer>

O que é apropriado colocar em um elemento <footer> ? Provavelmente o que você está colocando
em um <div id="footer"> agora. OK, essa é uma resposta circular. Mas realmente, é isso. A
especificação HTML5 diz: “Um rodapé normalmente contém informações sobre sua seção, como
quem o escreveu, links para documentos relacionados, dados de direitos autorais e assim por
diante”. Isso é o que está no rodapé desta página de exemplo: uma breve declaração de direitos
autorais e um link para uma página sobre o autor. Olhando em alguns sites populares, vejo muito potencial no rodapé:

52 | Capítulo 3: O que tudo isso significa?

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

• CNN tem um rodapé que contém uma declaração de direitos autorais, links para traduções e links para
termos de serviço, privacidade, páginas “sobre nós”, “entre em contato” e “ajuda”. Todo material
<footer> totalmente apropriado. • Google tem

uma página inicial notoriamente esparsa, mas na parte inferior dela há links para “Programas de
publicidade”, “Soluções empresariais” e “Sobre o Google”; uma declaração de direitos autorais; e um
link para a política de privacidade do Google. Tudo isso poderia ser agrupado em um <footer>.

• Meu blog tem um rodapé com links para meus outros sites, além de uma declaração de direitos autorais.
Definitivamente apropriado para um elemento <footer> . (Observe que os links em si não devem ser
agrupados em um elemento <nav> , porque não são links de navegação de site; são apenas uma
coleção de links para meus outros projetos em outros sites.)

Rodapés gordos estão na moda hoje em dia. Dê uma olhada no rodapé do site W3C. Ele contém três
colunas, denominadas “Navegação”, “Entre em contato com o W3C” e “Atualizações do W3C”.
A marcação fica assim, mais ou menos:
<div id="w3c_footer">
<div class="w3c_footer-nav">
<h3>Navegação</h3>
<ul>
<li><a href="/">Página inicial</
a></li> <li><a href="/standards/">Padrões</a></
li> <li><a href=" /participate/">Participar</a></li> <li><a
href="/Consortium/membership">Associação</a></li> <li><a
href="/Consortium/"> Sobre o W3C</a></li> </ul>
</
div>
<div class="w3c_footer-nav">
<h3>Entre em contato
com
o W3C</h3> <ul> <li><a href="/Consortium /
contact">Contato</a></li> <li><a href="/
Help/">Ajuda e perguntas frequentes</a></li>
<li><a href="/Consortium/sup" >Doe</a></li> <li><a href="/

Consortium/siteindex">Mapa
do site</a></li> </ul>
</
div> <div class="w3c_footer-nav "> <h3>Atualizações do
W3C</h3> <ul> <li><a href="http://twitter.com/W3C">Twitter</
a></
li>
<li><a href=" http://identi.ca/w3c">Identi.ca</a></
li> </ul> </div> <p class="copyright">Copyright © 2009 W3C</p> </div>

Para converter isso para HTML5 semântico, eu faria as seguintes alterações:

• Converta o <div id="w3c_footer"> externo em um elemento <footer> . • Converter

as duas primeiras instâncias de <div class="w3c_footer-nav"> em elementos <nav> ,


e a terceira instância para um elemento <section> .

Rodapés | 53

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

• Converta os cabeçalhos <h3> em <h1>, já que cada um estará agora dentro de um elemento de seccionamento. O
elemento <nav> cria uma seção no esboço do documento, assim como o elemento <article> (veja “Artigos” na
página 47).

A marcação final pode ser mais ou menos assim:


<rodapé>
<nenhum>

<h1>Navegação</h1>
<ul>
<li><a href="/">Página inicial</a></li>
<li><a href="/standards/">Padrões</a>< /li> <li><a href="/
participate/">Participar</a></li> <li><a href="/Consortium/
membership">Associação</a></li> <li ><a href="/Consortium/">Sobre o
W3C</a></li> </ul> </nav> <nav> <h1>Entre em contato
com o
W3C</
h1>
<ul> <li><a href ="/

Consortium/contact">Contato</a></li> <li><a href="/Help/">Ajuda e


perguntas frequentes</a></li> <li><a href="/ Consortium/
sup">Doar</a></li> <li><a href="/Consortium/siteindex">Mapa
do site</a></li> </ul> </nav> <section>

<h1>Atualizações W3C</
h1> <ul>
<li><a href="http://twitter.com/W3C">Twitter</a></li> <li><a href="http://
identi.ca/w3c">Identi.ca </a></li> </ul> </section> <p

class="copyright">Direitos autorais © 2009 W3C</p> </


footer>

Leitura adicional

Páginas de exemplo usadas ao longo deste capítulo:

• Original (HTML 4) • Modificado

(HTML5)

Na codificação de caracteres:

• “O mínimo absoluto que todo desenvolvedor de software deve saber absolutamente e positivamente sobre Unicode
e conjuntos de caracteres (sem desculpas!)”, por Joel Spolsky • “Sobre os benefícios do Unicode”,

“Sobre cadeias de caracteres” e “Caracteres vs.


Bytes”, de Tim Bray

Ao ativar o novo HTML5 no Internet Explorer:

54 | Capítulo 3: O que tudo isso significa?

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

• “Como estilizar elementos desconhecidos no IE”, por Sjoerd Visscher • Ferramenta

HTML5, por John Resig • Script de

ativação de HTML5, por Remy Sharp

Nos modos padrões e detecção de tipo de documento:

• “Ativando modos de navegador com Doctype”, por Henri Sivonen. Este é o único artigo que você deve ler sobre o
assunto. Existem muitos outros artigos, mas estão desatualizados, incompletos ou errados.

Validador compatível com HTML5:

• Validador Validator.nu (X)HTML5

Leitura adicional | 55

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

CAPÍTULO 4

Vamos chamar isso de superfície de desenho

Mergulhando

HTML5 define o elemento <canvas> como “uma tela de bitmap dependente de resolução que
pode ser usado para renderizar gráficos, gráficos de jogos ou outras imagens visuais em tempo real.” A
canvas é um retângulo em sua página no qual você pode usar JavaScript para desenhar qualquer coisa
você quer. A tabela a seguir mostra quais navegadores oferecem suporte básico a canvas no
momento desta redação:

IEa Raposa de fogo Safári cromada Ópera Iphone Android

7,0+ 3,0+ 3,0+ 3,0+ 10,0+ 1,0+ 1,0+

um suporte para Internet Explorer requer o explorercanvas de terceiros biblioteca.

Então, como é uma tela? Nada realmente. Um elemento <canvas> não tem conteúdo
e nenhuma fronteira própria. A marcação fica assim:

<canvas width="300" height="225"></canvas>

A Figura 4-1 mostra a tela com uma borda pontilhada para que possamos ver com o que estamos lidando.

Você pode ter vários elementos <canvas> na mesma página. Cada tela aparecerá
no DOM, e cada canvas mantém seu próprio estado. Se você der um ID para cada tela
atributo, você pode acessá-los como faria com qualquer outro elemento.

Vamos expandir essa marcação para incluir um atributo id :

<canvas id="a" width="300" height="225"></canvas>

Agora podemos encontrar facilmente esse elemento <canvas> no DOM:

var a_canvas = document.getElementById("a");

57

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Figura 4-1. Tela com borda

Formas Simples

IEa Raposa de fogo Safári cromada Ópera Iphone Android

7,0+ 3,0+ 3,0+ 3,0+ 10,0+ 1,0+ 1,0+

um suporte para Internet Explorer requer o explorercanvas de terceiros biblioteca.

Cada tela começa em branco. Isto é chato! Vamos desenhar algo. Você pode usar o
manipulador onclick para chamar uma função que desenha um retângulo (veja http:// diveintohtml5.org/
tela.html para um exemplo interativo):

função desenhar_b() {
var b_canvas = document.getElementById("b");
var b_context = b_canvas.getContext("2d");
b_context.fillRect(50, 25, 150, 100);
}

A primeira linha da função não tem nada de especial; apenas encontra o elemento <canvas> no
DOM. A segunda linha é onde fica mais interessante. Cada tela tem um desenho
contexto, que é onde toda a diversão acontece. Depois de encontrar um elemento <canvas>
no DOM (usando document.getElementById() ou qualquer outro método de sua preferência), você
pode chamar seu método getContext() . Você deve passar a string "2d" para getContext()
método:

função desenhar_b() {
var b_canvas = document.getElementById("b");
var b_context = b_canvas.getContext("2d");
b_context.fillRect(50, 25, 150, 100);
}

58 | Capítulo 4: Vamos chamar isso de superfície desenhada

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Pergunte ao professor Markup

P: Existe uma tela 3D?

R: Ainda não. Fornecedores individuais experimentaram suas próprias APIs de tela tridimensionais,
mas nenhuma foi padronizada. A especificação HTML5 observa: “Uma versão futura desta
especificação provavelmente definirá um contexto 3D”.

Então, você tem um elemento <canvas> e seu contexto de desenho. O contexto do desenho é
onde todos os métodos e propriedades do desenho são definidos. Há todo um grupo de
propriedades e métodos dedicados ao desenho de retângulos:

• A propriedade fillStyle pode ser uma cor CSS, um padrão ou um gradiente. (Mais sobre
gradientes em breve.) O fillStyle padrão é preto sólido, mas você pode configurá-lo como
quiser. Cada contexto de desenho lembra suas próprias propriedades enquanto a página
estiver aberta, a menos que você faça algo para redefini-la.
• fillRect(x, y, width, height) desenha um retângulo preenchido com o estilo de preenchimento
atual. • A propriedade strokeStyle é como fillStyle — pode ser uma cor CSS, um padrão ou um
gradiente.
• strokeRect(x, y, width, height) desenha um retângulo com o estilo de traço atual. strokeRect
não preenche o meio; apenas desenha as bordas.
• clearRect(x, y, width, height) limpa os pixels no retângulo especificado.

Pergunte ao professor Markup

P: Posso “redefinir” uma tela?

R: Sim. Definir a largura ou altura de um elemento <canvas> apagará seu conteúdo e redefinirá
todas as propriedades de seu contexto de desenho para seus valores padrão. Você nem precisa
alterar a largura; você pode simplesmente configurá-lo para seu valor atual, assim:

var b_canvas = document.getElementById("b");


b_canvas.largura = b_canvas.largura;

Voltando ao código do exemplo anterior: var


b_canvas = document.getElementById("b");
var b_context = b_canvas.getContext("2d");
b_context.fillRect(50, 25, 150, 100);
Chamar o método fillRect() desenha o retângulo e o preenche com o estilo de preenchimento
atual, que fica preto até que você o altere. O retângulo é delimitado pelo canto superior esquerdo
(50, 25), largura (150) e altura (100). Para ter uma ideia melhor de como isso funciona, vamos
dar uma olhada no sistema de coordenadas da tela.

Formas Simples | 59

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Coordenadas da tela
A tela é uma grade bidimensional. A coordenada (0, 0) está no canto superior esquerdo da tela. Ao
longo do eixo x, os valores aumentam em direção à borda direita da tela.
Ao longo do eixo y, os valores aumentam em direção à borda inferior da tela.

O diagrama de coordenadas na Figura 4-2 foi desenhado com um elemento <canvas> . Compreende:
• Um conjunto de linhas verticais esbranquiçadas

• Um conjunto de linhas horizontais esbranquiçadas

• Duas linhas horizontais pretas

• Duas pequenas linhas diagonais pretas que formam uma seta


• Duas linhas verticais pretas

• Duas pequenas linhas diagonais pretas que formam outra seta • A


letra “x”

• A letra “y” • O
texto “(0, 0)” próximo ao canto superior esquerdo • O
texto “(500, 375)” próximo ao canto inferior direito • Um ponto
no canto superior esquerdo e outro no canto inferior direito

Figura 4-2. Diagrama de coordenadas da tela

60 | Capítulo 4: Vamos chamar isso de superfície desenhada

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Nas seções a seguir, exploraremos como criar o efeito mostrado nesta figura.
Primeiro, precisamos definir o próprio elemento <canvas> . O elemento <canvas> define o
largura e altura do retângulo, e o id para que possamos encontrá-lo mais tarde:

<canvas id="c" width="500" height="375"></canvas>

Então precisamos de um script para encontrar o elemento <canvas> no DOM e obter seu desenho
contexto:

var c_canvas = document.getElementById("c");


var contexto = c_canvas.getContext("2d");

Agora podemos começar a desenhar linhas.

Caminhos

IEa Raposa de fogo Safári cromada Ópera Iphone Android

7,0+ 3,0+ 3,0+ 3,0+ 10,0+ 1,0+ 1,0+

um suporte para Internet Explorer requer o explorercanvas de terceiros biblioteca.

Imagine que você está desenhando uma imagem com tinta. Você não quer simplesmente mergulhar e
começar a desenhar, porque pode cometer um erro. Em vez disso, você esboça as linhas e curvas com
um lápis e, quando estiver satisfeito com ele, você traça seu esboço com tinta.

Cada tela tem um caminho. Definir o caminho é como desenhar com um lápis. Você pode desenhar
o que você quiser, mas não fará parte do produto final até que você pegue o
pena e trace seu caminho com tinta.

Para desenhar linhas retas a lápis, você usa os dois métodos a seguir:

• moveTo(x, y) move o lápis para o ponto inicial especificado.

• lineTo(x, y) desenha uma linha até o ponto final especificado.

Quanto mais você chama moveTo() e lineTo(), maior fica o caminho. Estes são “lápis”
métodos - você pode chamá-los quantas vezes quiser, mas não verá nada no
canvas até você chamar um dos métodos “ink”.

Vamos começar desenhando a grade esbranquiçada:

para (var x = 0,5; x < 500; x += 10) {


contexto.moveTo(x, 0);
contexto.lineTo(x,
375); }
para (var y = 0,5; y < 375; y += 10) {
contexto.moveTo(0, y);
context.lineTo(500, y); }

Caminhos | 61

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Todos esses eram métodos de “lápis”. Na verdade, nada foi desenhado na tela ainda.
Precisamos de um método de “tinta” para torná-lo permanente:

context.strokeStyle = "#eee";
contexto.stroke();

acidente vascular cerebral() é um dos métodos de “tinta”. Ele pega o caminho complexo que você definiu
com todas as chamadas moveTo() e lineTo() e realmente o desenha na tela. O strokeStyle controla a cor
das linhas. A Figura 4-3 mostra o resultado.

Figura 4-3. Uma grade desenhada em uma tela

Pergunte ao professor Markup

P : Por que você começou xey em 0,5 ? Por que não 0?

R: Imagine cada pixel como um grande quadrado. As coordenadas de números inteiros (0, 1, 2...) são as
arestas dos quadrados. Se você desenhar uma linha de uma unidade de largura entre coordenadas de
números inteiros, ela se sobreporá aos lados opostos do quadrado de pixels e a linha resultante será
desenhada com dois pixels de largura. Para desenhar uma linha com apenas um pixel de largura, você
precisa deslocar as coordenadas em 0,5 perpendicularmente à direção da linha.

62 | Capítulo 4: Vamos chamar isso de superfície desenhada

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Agora vamos desenhar a seta horizontal. Todas as linhas e curvas em um caminho são desenhadas
a mesma cor (ou gradiente – sim, falaremos disso em breve). Queremos desenhar a seta
em uma tinta de cor diferente – preta em vez de esbranquiçada – então precisamos iniciar um novo caminho:

context.beginPath();
contexto.moveTo(0, 40);
contexto.lineTo(240, 40);
contexto.moveTo(260, 40);
contexto.lineTo(500, 40);
contexto.moveTo(495, 35);
contexto.lineTo(500, 40);
contexto.lineTo(495, 45);
A seta vertical parece praticamente a mesma. Como a seta vertical é da mesma cor que
seta horizontal, não precisamos iniciar outro novo caminho. As duas setas irão
fazer parte do mesmo caminho:

contexto.moveTo(60, 0);
contexto.lineTo(60, 153);
contexto.moveTo(60, 173);
contexto.lineTo(60, 375);
contexto.moveTo(65, 370);
contexto.lineTo(60, 375);
contexto.lineTo(55, 370);

Eu disse que essas setas seriam pretas, mas o strokeStyle ainda está esbranquiçado. (O
fillStyle e strokeStyle não são redefinidos quando você inicia um novo caminho.) Tudo bem,
porque acabamos de executar uma série de métodos “lápis”. Mas antes de desenhá-lo de verdade, em
“ink”, precisamos definir o strokeStyle como preto. Caso contrário, essas duas setas ficarão esbranquiçadas e
dificilmente conseguiremos vê-las! As linhas a seguir mudam a cor para
preto e desenhe as linhas na tela:

context.strokeStyle = "#000";
contexto.stroke();

A Figura 4-4 mostra o resultado.

Texto

IEa Firefoxb Safári cromada Ópera Iphone Android

7,0+ 3,0+ 3,0+ 3,0+ 10,0+ 1,0+ 1,0+

um suporte para Internet Explorer requer o explorercanvas de terceiros biblioteca.

b O suporte do Mozilla Firefox 3.0 requer uma correção de compatibilidade.

Além de desenhar linhas em uma tela, você também pode desenhar texto em uma tela. Diferente
texto na página da web ao redor, não há modelo de caixa. Isso significa que nenhum dos
técnicas familiares de layout CSS estão disponíveis: sem pontos flutuantes, sem margens, sem preenchimento, sem
quebra de palavras. (Talvez você ache que isso é uma coisa boa!) Você pode definir alguns atributos de fonte e,
em seguida, escolher um ponto na tela e desenhar seu texto ali.

Texto | 63

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Figura 4-4. Eixos não rotulados desenhados em uma tela

Os seguintes atributos de fonte estão disponíveis no contexto do desenho (veja “Simples


Formas” na página 58):

• fonte pode ser qualquer coisa que você colocaria em uma regra de fonte CSS . Isso inclui estilo de fonte,
variante da fonte, espessura da fonte, tamanho da fonte, altura da linha e família da fonte.

• textAlign controla o alinhamento do texto. É semelhante (mas não idêntico) a uma regra de
alinhamento de texto CSS . Os valores possíveis são início, fim, esquerda, direita
e centro. • textBaseline controla onde o texto é desenhado em relação ao ponto inicial. Os
valores possíveis são superior, suspenso, intermediário, alfabético, ideográfico e inferior.

textBaseline é complicado, porque o texto é complicado. (Bem, o texto em inglês não é complicado, mas você pode
desenhar qualquer caractere Unicode que desejar em uma tela, e o Unicode é complicado.) A especificação HTML5
explica as diferentes linhas de base do texto:*

A parte superior do quadrado em está aproximadamente no topo dos glifos em uma fonte, a linha de base suspensa é onde alguns
glifos como estão ancorados, o meio está a meio caminho entre o topo do quadrado em e a parte inferior do quadrado em, a linha de
base alfabética é onde caracteres como Á, ÿ, f e ÿ estão ancorados, a linha de base ideográfica é onde glifos como ÿ e ÿ estão
ancorados, e a parte inferior do quadrado em está aproximadamente na parte inferior dos glifos em uma fonte. A parte superior e
inferior da caixa delimitadora podem estar distantes dessas linhas de base, devido aos glifos que se estendem muito além do
quadrado em (veja a Figura 4-5 ).

* http:// bit.ly/ aHCdDO

64 | Capítulo 4: Vamos chamar isso de superfície desenhada

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Figura 4-5. Linhas de base de texto

Para alfabetos simples como o inglês, você pode usar com segurança o topo, o meio ou o fundo para
a propriedade textBaseline .

Vamos desenhar um texto! O texto desenhado dentro da tela herda o tamanho e o estilo da fonte
o próprio elemento <canvas> , mas você pode substituir isso definindo a propriedade font como
o contexto do desenho:
context.font = "negrito 12px sem
serifa"; context.fillText("x", 248, 43);
context.fillText("o", 58, 165);

O método fillText() desenha o texto real:


context.font = "negrito 12px sem serifa";
context.fillText("x", 248, 43);
context.fillText("y", 58, 165);

Pergunte ao professor Markup

P: Posso usar tamanhos de fonte relativos para desenhar texto em uma tela?

R: Sim. Como qualquer outro elemento HTML da sua página, o próprio elemento <canvas> possui
um tamanho de fonte calculado com base nas regras CSS da sua página. Se você definir a propriedade context.font
para um tamanho de fonte relativo como 1,5em ou 150%, seu navegador multiplicará isso pelo tamanho de fonte
calculado do próprio elemento <canvas> .

Para o texto no canto superior esquerdo, digamos que queremos que o topo do texto esteja em y=5. Mas
somos preguiçosos – não queremos medir a altura do texto e calcular a linha de base.
Em vez disso, podemos definir textBaseline como top e passar a coordenada superior esquerda do
caixa delimitadora do texto:
context.textBaseline = "topo";
context.fillText("(0 0)", 8,, 5);

Texto | 65

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Agora, para o texto no canto inferior direito. Digamos que queremos o canto inferior direito
do texto esteja nas coordenadas (492.370) - a apenas alguns pixels do canto inferior direito da tela -
mas, novamente, não queremos medir a largura ou a altura
do texto. Podemos definir textAlign como right e textBaseline como bottom e então chamar
fillText() pelas coordenadas inferiores direitas da caixa delimitadora do texto:

context.textAlign = "direita";
context.textBaseline = "inferior";
, 492, 370);
context.fillText("(500 375)",

A Figura 4-6 mostra o resultado.

Figura 4-6. Eixos rotulados em uma tela

Ops! Esquecemos os pontos nos cantos. Veremos como desenhar círculos um pouco mais tarde; para
agora vamos trapacear um pouco e desenhá-los como retângulos (veja “Formas Simples” na página 58):

contexto.fillRect(0, 0, 3, 3);
contexto.fillRect(497, 372, 3, 3);

E foi tudo o que ela escreveu! A Figura 4-7 mostra o produto final.

66 | Capítulo 4: Vamos chamar isso de superfície desenhada

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Figura 4-7. Um diagrama de coordenadas de tela em uma tela

Gradientes

IEa Raposa de fogo Safári cromada Ópera Iphone Android

Gradientes lineares 7,0+ 3,0+ 3,0+ 3,0+ 10,0+ 1,0+ 1,0+

· 3,0+ 3,0+ 3,0+ 10,0+ 1,0+ 1,0+


Gradientes radiais

um suporte para Internet Explorer requer o explorercanvas de terceiros biblioteca.

Anteriormente neste capítulo, você aprendeu como desenhar um retângulo preenchido com uma cor sólida (veja
“Formas Simples” na página 58), depois uma linha traçada com uma cor sólida (consulte
“Caminhos” na página 61). Mas as formas e linhas não se limitam às cores sólidas. Você pode fazer tudo
tipos de magia com gradientes. A Figura 4-8 mostra um exemplo.

A marcação é igual a qualquer outra tela:

<canvas id="d" width="300" height="225"></canvas>

Primeiro, precisamos encontrar o elemento <canvas> e seu contexto de desenho:

var d_canvas = document.getElementById("d");


var contexto = d_canvas.getContext("2d");

Gradientes | 67

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Figura 4-8. Um gradiente linear da esquerda para a direita

Assim que tivermos o contexto do desenho, podemos começar a definir um gradiente. Um


gradiente é uma transição suave entre duas ou mais cores. O contexto de desenho da tela
suporta dois tipos de

gradientes: • createLinearGradient(x0, y0, x1, y1) pinta ao longo de uma linha de (x0, y0) até
(x1, y1).
• createRadialGradient(x0, y0, r0, x1, y1, r1) pinta ao longo de um cone entre dois círculos.
Os três primeiros parâmetros representam o círculo inicial, com origem (x0, y0) e raio
r0. Os últimos três parâmetros representam o círculo final, com origem (x1, y1) e raio
r1.

Vamos fazer um gradiente linear. Os gradientes podem ter qualquer tamanho, mas faremos esse gradiente com
300 pixels de largura, como a tela:

var meu_gradiente = context.createLinearGradient(0, 0, 300, 0);

Como os valores de y (o segundo e o quarto parâmetros) são ambos 0, esse gradiente será sombreado
uniformemente da esquerda para a direita.

Assim que tivermos um objeto gradiente, podemos definir as cores do gradiente. Um gradiente tem duas ou
mais interrupções de cor. As paradas de cor podem estar em qualquer lugar ao longo do gradiente. Para
adicionar uma parada de cor, você precisa especificar sua posição ao longo do gradiente. As posições do
gradiente podem estar em qualquer lugar entre 0 e 1.

Vamos definir um gradiente que vai do preto ao branco:

my_gradient.addColorStop(0, "preto");
my_gradient.addColorStop(1, "branco");

Definir um gradiente não desenha nada na tela. É apenas um objeto guardado em algum lugar na memória.
Para desenhar um gradiente, você define fillStyle como gradiente e desenha uma forma, como um retângulo ou
uma linha:

context.fillStyle = meu_gradiente;
contexto.fillRect(0, 0, 300, 225);

68 | Capítulo 4: Vamos chamar isso de superfície desenhada

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

A Figura 4-9 mostra o resultado.

Figura 4-9. Um gradiente linear da esquerda para a direita

Suponha que você queira um gradiente que sombreie de cima para baixo. Ao criar o objeto
gradiente, mantenha os valores x (o primeiro e o terceiro parâmetros) constantes e faça os valores
y (o segundo e o quarto parâmetros) variarem de 0 até a altura da tela:
var meu_gradiente = context.createLinearGradient(0, 0, 0, 225);
my_gradient.addColorStop(0, "preto");
my_gradient.addColorStop(1, "branco");
context.fillStyle = meu_gradiente;
contexto.fillRect(0, 0, 300, 225);

A Figura 4-10 mostra o resultado.

Figura 4-10. Um gradiente linear de cima para baixo

Gradientes | 69

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Você também pode criar gradientes ao longo de uma diagonal. Por exemplo:

var meu_gradiente = context.createLinearGradient(0, 0, 300, 225);


my_gradient.addColorStop(0, "preto");
my_gradient.addColorStop(1, "branco");
context.fillStyle = meu_gradiente;
contexto.fillRect(0, 0, 300, 225);

A Figura 4-11 mostra o resultado.

Figura 4-11. Um gradiente linear diagonal

Imagens

IEa Raposa de fogo Safári cromada Ópera Iphone Android

7,0+ 3,0+ 3,0+ 3,0+ 10,0+ 1,0+ 1,0+

um suporte para Internet Explorer requer o explorercanvas de terceiros biblioteca.

A Figura 4-12 mostra a imagem de um gato exibido com o elemento <img> .

Figura 4-12. Gato com um elemento <img>

A Figura 4-13 mostra o mesmo gato desenhado em uma tela.

70 | Capítulo 4: Vamos chamar isso de superfície desenhada

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Figura 4-13. Gato com um elemento <canvas>

O contexto de desenho da tela define vários métodos para desenhar uma imagem em uma tela: •

drawImage(image, dx, dy) pega uma imagem e a desenha na tela. As coordenadas fornecidas (dx,
dy) serão o canto superior esquerdo da imagem. As coordenadas (0, 0) desenhariam a imagem
no canto superior esquerdo da tela.
• drawImage(image, dx, dy, dw, dh) pega uma imagem, dimensiona-a para uma largura de dw e um
altura de dh e desenha-o na tela nas coordenadas (dx, dy).
• drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh) pega uma imagem, recorta-a no retângulo (sx,
sy, sw, sh), dimensiona-a para dimensões (dw, dh), e desenha na tela nas coordenadas (dx, dy).

A especificação HTML5 explica os parâmetros drawImage() :

O retângulo de origem é o retângulo [dentro da imagem de origem] cujos cantos são


os quatro pontos (sx, sy), (sx+sw, sy), (sx+sw, sy+sh), (sx, sy+sh).
O retângulo de destino é o retângulo [dentro da tela] cujos cantos são os quatro pontos
(dx, dy), (dx+dw, dy), (dx+dw, dy+dh), (dx, dy+dh).
A Figura 4-14 fornece uma representação visual desses parâmetros.

Para desenhar uma imagem em uma tela, você precisa de uma imagem. A imagem pode ser um
elemento <img> existente ou você pode criar um objeto Image com JavaScript. De qualquer forma,
você precisa garantir que a imagem esteja totalmente carregada antes de desenhá-la na tela.

Se estiver usando um elemento <img> existente , você pode desenhá-lo com segurança na tela
durante o evento window.onload :

<img id="cat" src="images/cat.png" alt="gato dormindo" width="177" height="113">


<canvas id="e" width="177" height="113" </canvas>
<script>
window.onload = function()
{ var canvas = document.getElementById("e");
var contexto = canvas.getContext("2d");
var gato = document.getElementById("gato");
context.drawImage(gato, 0,

0); }; </script>

Imagens | 71

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Figura 4-14. Como drawImage() mapeia uma imagem para uma tela

Se você estiver criando o objeto de imagem inteiramente em JavaScript, poderá desenhar a imagem
com segurança na tela durante o evento Image.onload :
<canvas id="e" width="177" height="113"></canvas>
<script>
var canvas = document.getElementById("e");
var contexto = canvas.getContext("2d");
var gato = nova
imagem(); cat.src = "imagens/
cat.png"; cat.onload =
function() { context.drawImage(cat,

0, 0); }; </script>

O terceiro e quarto parâmetros opcionais do método drawImage() controlam o dimensionamento da


imagem. A Figura 4-15 mostra a mesma imagem de um gato, dimensionada para metade de sua
largura e altura e desenhada repetidamente em diferentes coordenadas dentro de

uma única tela: Aqui está o script que produz o efeito “multicat”:
cat.onload = function() { for
(var x = 0, y = 0; x <
500 && y < 375; x
+= 50, y += 37)
{ context.drawImage(cat, x, y, 88 , 56);

72 | Capítulo 4: Vamos chamar isso de superfície desenhada

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

} };

Todo esse esforço levanta uma questão legítima: por que você iria querer desenhar uma imagem
em uma tela? O que a complexidade extra traz para você em relação a um elemento <img> e
algumas regras CSS? Até mesmo o efeito “multicat” poderia ser replicado com 10 elementos
<img> sobrepostos .

A resposta simples é que você faria isso pelo mesmo motivo pelo qual deseja desenhar texto
em uma tela (consulte “Texto” na página 63). Nosso diagrama de coordenadas da tela (consulte
“Coordenadas da tela” na página 60) incluía texto, linhas e formas; o elemento texto em tela era
apenas uma parte de um trabalho maior. Um diagrama mais complexo poderia facilmente usar
drawImage() para incluir ícones, sprites ou outros gráficos.

Figura 4-15. Multigato!

E quanto ao IE?
O Microsoft Internet Explorer (até a versão 8 inclusive, a versão atual no momento em que este
artigo foi escrito) não oferece suporte à API canvas. No entanto, o Internet Explorer suporta uma
tecnologia proprietária da Microsoft chamada VML, que pode fazer muitas das mesmas coisas
que o elemento <canvas> . E assim nasceu o excanvas.js .

E quanto ao IE? | 73

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

ExplorerCanvas — excanvas.js — é uma biblioteca JavaScript de código aberto licenciada pelo Apache
que implementa a API canvas no Internet Explorer. Para usá-lo, inclua o seguinte elemento <script>
no topo da sua página:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Mergulhe no HTML 5</title>
<!--[if IE]>
<script src="excanvas.js"></script> <!
[endif]- -> </
head>
<body>
...
</body>
</html>

Os bits <!--[if IE]> e <![endif]--> são comentários condicionais. O Internet Explorer os interpreta como
uma instrução if : “se o navegador atual for qualquer versão do Internet Explorer, execute este bloco”.
Todos os outros navegadores tratarão o bloco inteiro como um comentário HTML. O resultado líquido
é que o Internet Explorer baixará o script excan vas.js e o executará, mas outros navegadores irão
ignorar o script completamente (não baixá-lo, não executá-lo, nada). Isso faz com que sua página
carregue mais rápido em navegadores que implementam a API canvas nativamente.

Depois de incluir o script excanvas.js no <head> da sua página, você não precisa fazer mais nada
para acomodar o Internet Explorer. Você pode simplesmente adicionar elementos <canvas> à sua
marcação ou criá-los dinamicamente com JavaScript. Siga as instruções deste capítulo para obter o
contexto de desenho de um elemento <canvas> e você poderá desenhar formas, texto e padrões.

Bem... não exatamente. Existem algumas limitações:

• Gradientes (consulte “Gradientes” na página 67) só podem ser lineares. Gradientes radiais não são
suportado. •
Os padrões devem se repetir em ambas as direções. •
Regiões de recorte não são suportados. •
Escala não uniforme não dimensiona corretamente os traços. • É
lento. Isso não deveria ser um grande choque para ninguém, já que o analisador de JavaScript do
Internet Explorer é mais lento do que o de outros navegadores, para começar. Quando você
começa a desenhar formas complexas por meio de uma biblioteca JavaScript que traduz
comandos para uma tecnologia completamente diferente, as coisas ficam paralisadas. Você não
notará a degradação do desempenho em exemplos simples, como desenhar algumas linhas e
transformar uma imagem, mas verá isso imediatamente quando começar a fazer animações
baseadas em tela e outras coisas malucas.

74 | Capítulo 4: Vamos chamar isso de superfície desenhada

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Há mais uma ressalva sobre o uso do excanvas.js, e é um problema que encontrei ao criar os exemplos
neste capítulo. ExplorerCanvas inicializa sua própria interface de tela falsa automaticamente sempre que
você inclui o script excanvas.js em sua página HTML. Mas isso não significa que o Internet Explorer esteja
pronto para usá-lo imediatamente.
Em certas situações, você pode entrar em uma condição de corrida em que a interface de tela falsa está
quase, mas não totalmente, pronta para uso. O principal sintoma desse estado é que o Internet Explorer
reclamará que “o objeto não suporta esta propriedade ou método” sempre que você tentar fazer qualquer
coisa com um elemento <canvas> , como obter seu contexto de desenho.

A solução mais fácil para isso é adiar toda a manipulação relacionada ao canvas até que o evento onload
seja acionado. Isso pode demorar um pouco – se sua página tiver muitas imagens ou vídeos, eles atrasarão
o evento onload – mas dará ao ExplorerCanvas tempo para fazer sua mágica.

Um exemplo completo Halma é um

jogo de tabuleiro centenário. Existem muitas variações. Neste exemplo, criei uma versão solitária do Halma
com nove peças em um tabuleiro 9 × 9. No início do jogo, as peças formam um quadrado 3 × 3 no canto
inferior esquerdo do tabuleiro. O objetivo do jogo é mover todas as peças de forma que formem um quadrado
3 × 3 no canto superior direito do tabuleiro, no menor número possível de movimentos.

Existem dois tipos de movimentos legais no Halma:

• Pegue uma peça e mova-a para qualquer quadrado vazio adjacente. Um quadrado “vazio” é aquele que
atualmente não contém nenhuma peça. Um quadrado “adjacente” está imediatamente ao norte, sul,
leste, oeste, noroeste, nordeste, sudoeste ou sudeste da posição atual da peça. (O tabuleiro não gira
de um lado para o outro. Se uma peça estiver na coluna mais à esquerda, ela não poderá se mover
para oeste, noroeste ou sudoeste. Se uma peça estiver na linha inferior, ela não poderá se mover para
sul, sudeste ou sudoeste. sudoeste.)

• Pegue uma peça e pule sobre uma peça adjacente e, possivelmente, repita. Ou seja, se você pular uma
peça adjacente e depois pular outra peça adjacente à sua nova posição, isso contará como um único
movimento. Na verdade, qualquer número de saltos ainda conta como um único movimento. (Como o
objetivo é minimizar o número total de movimentos, ter um bom desempenho no Halma envolve construir
e depois usar longas cadeias de peças escalonadas para que outras peças possam pular sobre elas
em longas sequências.)

A Figura 4-16 é uma captura de tela do jogo em si; você também pode jogar online se você quiser mexer
nisso com as ferramentas de desenvolvedor do seu navegador.

Então, como isso funciona? Estou tão feliz que você perguntou. Não mostrarei todo o código aqui (você pode
vê-lo em http:// diveintohtml5.org/ examples/ halma.js). Irei pular a maior parte do código do jogo em si, mas
quero destacar algumas partes do código que tratam do desenho na tela e da resposta aos cliques do mouse
no elemento <canvas> .

Um exemplo completo | 75

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Figura 4-16. Posição inicial de um jogo Halma

Durante o carregamento da página, inicializamos o jogo definindo as dimensões do próprio <canvas> e


armazenando uma referência ao seu contexto de desenho:

gCanvasElement.width = kPixelWidth;
gCanvasElement.height = kPixelHeight;
gDrawingContext = gCanvasElement.getContext("2d");

Em seguida, fazemos algo que você ainda não viu: adicionamos um ouvinte de evento ao elemento
<canvas> para escutar eventos de clique:

CanvasElement.addEventListener("clique", halmaOnClick, falso);

A função halmaOnClick() é chamada quando o usuário clica em qualquer lugar da tela. Seu argumento
é um objeto MouseEvent que contém informações sobre onde o usuário clicou:

função halmaOnClick(e)
{ var célula = getCursorPosition(e);

// o resto é apenas lógica de jogo for (var i =


0; i < gNumPieces; i++) {

76 | Capítulo 4: Vamos chamar isso de superfície desenhada

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

if ((gPieces[i].row == cell.row) &&


(gPieces[i].column == cell.column))
{ clickOnPiece(i);
retornar;
}

} clickOnEmptyCell(célula);
}

A próxima etapa é pegar o objeto MouseEvent e calcular qual quadrado do quadro Halma acabou de
ser clicado. O quadro Halma ocupa toda a tela, então cada clique ocorre em algum lugar do quadro. Só
precisamos descobrir onde. Isso é complicado porque os eventos do mouse são implementados de
maneira diferente em praticamente todos os navegadores:
function getCursorPosition(e) { var
x;
variar;
if (e.páginaX || e.páginaY)
{x=
e.páginaX; y

=
e.páginaY; } else { x = e.clientX +
document.body.scrollLeft +
document.documentElement.scrollLeft; y =
e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
}

Neste ponto, temos coordenadas xey relativas ao documento (ou seja, a página HTML inteira). Mas
queremos coordenadas relativas à tela. Podemos obtê-los da seguinte forma:

x -= gCanvasElement.offsetLeft; y
-= gCanvasElement.offsetTop;

Agora temos coordenadas x e y relativas à tela (consulte “Coordenadas da tela” na página 60). Ou
seja, se x for 0 e y for 0 neste ponto, sabemos que o usuário acabou de clicar no pixel superior esquerdo
da tela.

A partir daqui, podemos calcular em qual quadrado Halma o usuário clicou e agir de acordo:

var célula = new Cell(Math.floor(y/kPieceWidth),


Math.floor(x/kPieceHeight));
célula de retorno;
}

Uau! Eventos de mouse são difíceis. Mas você pode usar a mesma lógica (na verdade, esse código
exato) em todos os seus próprios aplicativos baseados em canvas. Lembre-se: clique do
mouseÿcoordenadas relativas do documentoÿcoordenadas relativas à telaÿcódigo específico do aplicativo.

OK, vamos dar uma olhada na rotina principal de desenho. Como os gráficos são tão simples, optei por
limpar e redesenhar o tabuleiro por completo sempre que alguma coisa mudar no jogo. Isto não é
estritamente necessário. O contexto de desenho da tela manterá tudo o que

Um exemplo completo | 77

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

você já desenhou nela, mesmo que o usuário role a tela para fora da visualização ou mude para outra
guia e volte mais tarde. Se estiver desenvolvendo um aplicativo baseado em tela com gráficos mais
complicados (como um jogo de arcade), você poderá otimizar o desempenho rastreando quais regiões
da tela estão “sujas” e redesenhando apenas as regiões sujas. Mas isso está fora do escopo deste livro.
Aqui está o código de compensação do quadro:
gDrawingContext.clearRect(0, 0, kPixelWidth, kPixelHeight);

A rotina de desenho do quadro deve parecer familiar. É muito semelhante ao modo como desenhamos
o diagrama de coordenadas do canvas (veja “Coordenadas do Canvas” na página
60): gDrawingContext.beginPath();

/* linhas verticais */
for (var x = 0; x <= kPixelWidth; x += kPieceWidth)
{ gDrawingContext.moveTo(0.5 + x,
0); gDrawingContext.lineTo(0,5 + x, kPixelHeight);
}

/* linhas horizontais */
for (var y = 0; y <= kPixelHeight; y += kPieceHeight)
{ gDrawingContext.moveTo(0, 0.5 +
y); gDrawingContext.lineTo(kPixelWidth, 0,5 + y);
}

/* desenhe
isso! */ gDrawingContext.strokeStyle =
"#ccc"; gDrawingContext.stroke();

A verdadeira diversão começa quando vamos desenhar cada uma das peças individuais. Uma peça é
um círculo, algo que não desenhamos antes. Além disso, se o usuário selecionar uma peça antes de
movê-la, desejaremos desenhar essa peça como um círculo preenchido. Aqui, o argumento p representa
uma peça, que possui propriedades de linha e coluna que indicam a localização atual da peça no
tabuleiro. Usamos algumas constantes do jogo para traduzir (coluna, linha) em coordenadas relativas à
tela (x, y) , depois desenhamos um círculo e (se a peça estiver selecionada) preenchemos
no círculo com uma cor sólida:
função drawPiece (p, selecionado)
{ var coluna = p.coluna;
var linha = p.linha;
var x = (coluna * kPieceWidth) + (kPieceWidth/2); var
y = (linha * kPieceHeight) + (kPieceHeight/2); var raio
= (kPieceWidth/2) - (kPieceWidth/10);

Esse é o fim da lógica específica do jogo. Agora temos coordenadas (x, y) , relativas à tela, para o centro
do círculo que queremos desenhar. Não existe um método circle() na API canvas, mas existe um método
arc() . E realmente, o que é um círculo senão um arco que percorre toda a volta? Você se lembra da sua
geometria básica? O método arc() usa um ponto central (x, y), um raio, um ângulo inicial e final (em
radianos) e um sinalizador de direção (falso para sentido horário, verdadeiro para sentido anti-horário).
Podemos usar o módulo Math integrado ao JavaScript para calcular radianos:

78 | Capítulo 4: Vamos chamar isso de superfície desenhada

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

gDrawingContext.beginPath();
gDrawingContext.arc(x, y, raio, 0, Math.PI * 2, falso);
gDrawingContext.closePath();

Mas espere! Nada foi desenhado ainda. Assim como moveTo() e lineTo(), o método arc() é um
método “lápis” (consulte “Caminhos” na página 61). Para realmente desenhar o círculo, precisamos
definir o StrokeStyle e chamar Stroke() para traçá-lo em “ink”:
gDrawingContext.strokeStyle = "#000";
gDrawingContext.stroke();

E se a peça for selecionada? Podemos reutilizar o mesmo caminho que criamos para desenhar o
contorno da peça e preencher o círculo com uma cor sólida:
if (selecionado)
{ gDrawingContext.fillStyle = "#000";
gDrawingContext.fill();
}

E isso é... bem, é basicamente isso. O resto do programa é uma lógica específica do jogo – distinguir
entre movimentos válidos e inválidos, acompanhar o número de movimentos, detectar se o jogo
acabou. Com nove círculos, algumas linhas retas e um manipulador onclick , criamos um jogo inteiro
em <canvas>. Huzah!

Leitura adicional
• Tutorial de tela no Mozilla Developer Center • “HTML5
canvas – o básico”, por Mihai Sucan • Demonstrações
de telas: demonstrações, ferramentas e tutoriais para o elemento HTML <canvas> • “O
elemento canvas ” no rascunho do padrão HTML5

Leitura adicional | 79

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

CAPÍTULO 5

Vídeo na Web

Mergulhando
Qualquer pessoa que tenha visitado o YouTube.com nos últimos quatro anos sabe que é possível incorporar
vídeo em uma página da web. Mas antes do HTML5, não havia uma maneira baseada em padrões de fazer isso.
Praticamente todos os vídeos que você já assistiu “na Web” foram canalizados
um plug-in de terceiros – talvez QuickTime, talvez RealPlayer, talvez Flash. (YouTube
usa Flash.) Esses plug-ins se integram ao seu navegador bem o suficiente para que você não
até mesmo esteja ciente de que você os está usando - até tentar assistir a um vídeo em uma plataforma
isso não suporta esse plug-in, claro.

HTML5 define uma forma padrão de incorporar vídeo em uma página web, usando um elemento <video> .
O suporte para o elemento <video> ainda está evoluindo, o que é uma forma educada de dizer que não.
ainda funciona (pelo menos não funciona em todos os lugares). Mas não se desespere! Existem alternativas
e substitutos e opções em abundância. A Tabela 5-1 mostra quais navegadores suportam o
Elemento <video> no momento da escrita.

Tabela 5-1. suporte ao elemento <video>

IE9 IE8 IE7 Raposa de fogo Raposa de fogo Safári 4 Safári 3 cromada Ópera
3.5 3,0

ÿ · · ÿ · ÿ ÿ ÿ ÿ

O suporte para o elemento <video> em si é apenas uma pequena parte da história. Antes de nós
Para falar sobre vídeo HTML5, primeiro você precisa entender um pouco sobre o vídeo em si.
(Se você já conhece o vídeo, pode pular para “O que funciona no
Web” na página 88.)

Contêineres de vídeo

Você pode pensar nos arquivos de vídeo como “arquivos AVI” ou “arquivos MP4”. Na realidade, “AVI” e “MP4”
são apenas formatos de contêiner. Assim como um arquivo ZIP pode conter qualquer tipo de arquivo, o vídeo

81

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

os formatos de contêiner definem apenas como armazenar coisas dentro deles, não que tipo de dados
são armazenados. (É um pouco mais complicado do que isso, porque nem todos os streams de vídeo
são compatíveis com todos os formatos de contêiner, mas não importa por enquanto.)

Um arquivo de vídeo geralmente contém múltiplas trilhas: uma trilha de vídeo (sem áudio), mais uma ou
mais trilhas de áudio (sem vídeo). As faixas geralmente estão inter-relacionadas. Uma trilha de áudio
contém marcadores para ajudar a sincronizar o áudio com o vídeo. Trilhas individuais podem ter
metadados, como a proporção de uma trilha de vídeo ou o idioma de uma trilha de áudio. Os contêineres
também podem ter metadados, como o título do vídeo em si, a capa do vídeo, os números dos episódios
(para programas de televisão) e assim por diante.

Existem muitos formatos de contêiner de vídeo. Alguns dos mais populares incluem:

MPEG-4
Geralmente com extensão .mp4 ou .m4v . O contêiner MPEG-4 é baseado no contêiner QuickTime
mais antigo da Apple (.mov). Trailers de filmes no site da Apple ainda usa o contêiner QuickTime
mais antigo, mas os filmes que você aluga no iTunes são entregues em um contêiner MPEG-4.

Vídeo instantâneo

Geralmente com uma extensão .flv . Flash Video é, sem surpresa, usado pelo Adobe Flash.
Antes do Flash 9.0.60.184 (também conhecido como Flash Player 9 Update 3), esse era o único
formato de contêiner compatível com o Flash. Versões mais recentes do Flash também suportam
o contêiner MPEG-4.

Ogg
Geralmente com extensão .ogv . Ogg é um padrão aberto, compatível com código aberto e livre de
quaisquer patentes conhecidas. Firefox 3.5, Chrome 4 e Opera 10.5 oferecem suporte nativo, sem
plug-ins específicos de plataforma, para o formato contêiner Ogg, vídeo Ogg (chamado “Theora”)
e áudio Ogg (chamado “Vorbis”).
No desktop, o Ogg é compatível com todas as principais distribuições Linux, e você pode usá-lo
no Mac e no Windows instalando os componentes do QuickTime . ou filtros DirectShow,
respectivamente. Também é jogável com o excelente VLC em todas as plataformas.

WebM
Com uma extensão .webm . WebM é um novo formato de contêiner tecnicamente muito semelhante
a outro formato chamado Matroska. WebM foi anunciado no Google I/O 2010. Ele foi projetado
para ser usado exclusivamente com o codec de vídeo VP8 e o codec de áudio Vorbis. (Mais sobre
isso em um minuto.) Ele terá suporte nativo, sem plug-ins específicos de plataforma, nas próximas
versões do Chromium, Google Chrome, Mozilla Firefox e Opera. A Adobe também anunciou que a
próxima versão do Flash suportará vídeo WebM.

Intercalação de áudio e
vídeo Geralmente com uma extensão .avi . O formato contêiner AVI foi inventado pela Micro soft
em uma época mais simples, quando o fato de os computadores poderem reproduzir vídeo era
considerado incrível. Ele não suporta oficialmente muitos dos recursos do

82 | Capítulo 5: Vídeo na Web

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

formatos de contêiner mais recentes. Não oferece suporte oficial a nenhum tipo de metadado de
vídeo. Ele nem sequer oferece suporte oficial à maioria dos codecs modernos de vídeo e áudio em
uso atualmente. Com o tempo, várias empresas tentaram estendê-lo de maneiras geralmente
incompatíveis para suportar isto ou aquilo, e ainda é o formato de contêiner padrão para codificadores
populares como o MEncoder.

Codecs de vídeo
Quando você fala em “assistir a um vídeo”, provavelmente está falando sobre uma combinação de um
fluxo de vídeo e um fluxo de áudio. Mas você não tem dois arquivos diferentes; você só tem “o vídeo”.
Talvez seja um arquivo AVI ou MP4. Conforme descrito na seção anterior, esses são apenas formatos
de contêiner, como um arquivo ZIP que contém vários tipos de arquivos. O formato contêiner define como
armazenar os fluxos de vídeo e áudio em um único arquivo.

Quando você “assiste a um vídeo”, seu player de vídeo faz várias coisas ao mesmo tempo:

• Interpretar o formato do contêiner para descobrir quais faixas de vídeo e áudio estão disponíveis e
como elas são armazenadas no arquivo para que ele possa encontrar os dados necessários para
decodificar em seguida

• Decodificar o fluxo de vídeo e exibir uma série de imagens na tela • Decodificar o fluxo de
áudio e enviar o som para seus alto-falantes

Um codec de vídeo é um algoritmo pelo qual um fluxo de vídeo é codificado. Ou seja, especifica como
fazer o item 2 acima. (A palavra “codec” é uma mala de viagem, uma combinação das palavras
“codificador” e “decodificador”.) Seu reprodutor de vídeo decodifica o fluxo de vídeo de acordo com o
codec de vídeo e, em seguida, exibe uma série de imagens, ou “quadros”, na tela. A maioria dos codecs
de vídeo modernos usa todos os tipos de truques para minimizar a quantidade de informações necessárias
para exibir um quadro após o outro. Por exemplo, em vez de armazenar cada quadro individual (como
capturas de tela), eles armazenam apenas as diferenças entre os quadros. A maioria dos vídeos não
muda muito de um quadro para outro, então isso permite altas taxas de compactação, o que resulta em
tamanhos de arquivo menores.

Existem codecs de vídeo com e sem perdas . O vídeo sem perdas é grande demais para ser útil na Web,
então vou me concentrar nos codecs com perdas. Com um codec de vídeo com perdas, as informações
são irremediavelmente perdidas durante a codificação. Assim como copiar uma fita cassete de áudio,
toda vez que você codifica, você perde informações sobre o vídeo de origem e degrada a qualidade.
Em vez do “silvo” de uma fita cassete, um vídeo re-recodificado pode parecer bloqueado, especialmente
durante cenas com muito movimento. (Na verdade, isso pode acontecer mesmo se você codificar
diretamente da fonte original, se você escolher um codec de vídeo ruim ou passar o conjunto errado de
parâmetros.) Pelo lado positivo, os codecs de vídeo com perdas podem oferecer taxas de compactação
incríveis e muitos oferecem maneiras para “trapacear” e suavizar esse bloqueio durante a reprodução
para tornar a perda menos perceptível ao olho humano.

Codecs de vídeo | 83

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Existem muitos codecs de vídeo. Os três codecs mais relevantes são H.264, Theora e VP8.

H.264
H.264 também é conhecido como “MPEG-4 parte 10”, também conhecido como “MPEG-4 AVC”, também
conhecido como “MPEG-4 Advanced Video Coding”. H.264 foi desenvolvido pelo grupo MPEG e
padronizado em 2003. Tem como objetivo fornecer um codec único para dispositivos de baixa largura de
banda e baixa CPU (telefones celulares); dispositivos de alta largura de banda e alta CPU (computadores
desktop modernos); e tudo mais. Para conseguir isso, o padrão H.264 é dividido em “perfis”, cada um
definindo um conjunto de recursos opcionais que trocam complexidade por tamanho de arquivo. Perfis
mais altos usam mais recursos opcionais, oferecem melhor qualidade visual em arquivos menores,
demoram mais para codificar e exigem mais potência da CPU para decodificar em tempo real.

Para lhe dar uma ideia aproximada da variedade de perfis, o iPhone da Apple suporta o perfil Baseline, o
decodificador AppleTV suporta os perfis Baseline e Main, e o Adobe Flash em um PC desktop oferece
suporte aos perfis Baseline, Main e High. O YouTube (de propriedade do Google, meu empregador)
agora usa H.264 para codificar vídeos de alta definição jogável através do Adobe Flash; O YouTube
também fornece vídeo codificado em H.264 para dispositivos móveis, incluindo o iPhone da Apple e
telefones que executam o sistema operacional móvel Android do Google . Além disso, H.264 é um dos
codecs de vídeo exigidos pela especificação Blu-ray; Os discos Blu-ray que o utilizam geralmente usam
o perfil Alto.

A maioria dos dispositivos não PC que reproduzem vídeo H.264 (incluindo iPhones e reprodutores Blu-
ray independentes) na verdade fazem a decodificação em um chip dedicado, já que suas CPUs principais
não são nem de longe poderosas o suficiente para decodificar o vídeo em tempo real. Muitas placas
gráficas de desktop também suportam decodificação H.264 em hardware. Existem vários codificadores
H.264 concorrentes, incluindo a biblioteca x264 de código aberto. O padrão H.264 está protegido por
patente; o licenciamento é intermediado pelo grupo MPEG LA. O vídeo H.264 pode ser incorporado nos
formatos de contêiner mais populares (consulte “Contêineres de vídeo” na página 81), incluindo MP4
(usado principalmente pela iTunes Store da Apple) e MKV (usado principalmente por entusiastas de
vídeos não comerciais).

Teoria
Teora evoluiu do codec VP3 e foi posteriormente desenvolvido pela Fundação Xiph.org. Theora é um
codec livre de royalties e não está sobrecarregado por nenhuma patente conhecida além das patentes
VP3 originais, que foram licenciadas sem royalties.
Embora o padrão esteja “congelado” desde 2004, o projeto Theora (que inclui um codificador e
decodificador de referência de código aberto) só lançou a versão 1.0 em novembro de 2008. e Versão
1.1 em setembro de 2009.

O vídeo Theora pode ser incorporado em qualquer formato de contêiner, embora seja mais frequentemente
visto em um contêiner Ogg. Todas as principais distribuições Linux suportam Theora imediatamente, e o
Mozilla Firefox 3.5 inclui suporte nativo para vídeo Theora em um contêiner Ogg. Por

84 | Capítulo 5: Vídeo na Web

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

“nativo”, quero dizer, “disponível em todas as plataformas sem plug-ins específicos da plataforma”. Você também
pode reproduzir vídeo Theora no Windows ou no Mac OS X após instalar o software decodificador de código aberto
da Xiph.org.

VP8
VP8 é outro codec de vídeo da On2, a mesma empresa que desenvolveu originalmente o VP3 (mais tarde Theora).
Tecnicamente, é semelhante em qualidade ao H.264 Baseline, com muito potencial para melhorias futuras.

Em 2010, o Google adquiriu a On2 e publicou a especificação do codec de vídeo e um exemplo de codificador e
decodificador como código aberto. Como parte disso, o Google também “abriu” todas as patentes que a On2 havia
registrado no VP8, licenciando-as sem royalties. (Isso é o melhor que você pode esperar com patentes – você não
pode realmente “liberá-las” ou anulá-las depois de terem sido emitidas. Para torná-las compatíveis com o código
aberto, você as licencia sem royalties e então qualquer pessoa pode usá-las. as tecnologias que as patentes
cobrem sem pagar nada ou negociar licenças de patente.) Em 19 de maio de 2010, VP8 é um codec moderno e
isento de royalties e não está onerado por nenhuma patente conhecida, exceto as patentes que On2 (agora
Google) já licenciou sem royalties.

Codecs de áudio
A menos que você se limite a filmes feitos antes de 1927 ou algo assim, você vai querer uma trilha de áudio em
seu vídeo. Assim como os codecs de vídeo, os codecs de áudio são algoritmos de codificação, neste caso usados
para fluxos de áudio. Tal como acontece com os codecs de vídeo, existem codecs de áudio com e sem perdas . E
assim como o vídeo sem perdas, o áudio sem perdas é realmente grande demais para ser colocado na Web, então
vou me concentrar nos codecs de áudio com perdas.

Na verdade, podemos restringir ainda mais o foco, porque existem diferentes categorias de codecs de áudio com
perdas. O áudio é usado em muitos lugares onde o vídeo não é (telefonia, por exemplo), e há toda uma categoria
de codecs de áudio otimizados para codificação de voz. Você não copiaria um CD de música com esses codecs,
porque o resultado soaria como uma criança de quatro anos cantando no viva-voz. Mas você os usaria em um
Asterisk PBX, porque a largura de banda é preciosa e esses codecs podem compactar a fala humana em uma
fração do tamanho dos codecs de uso geral. No entanto, devido à falta de suporte em navegadores nativos e plug-
ins de terceiros, os codecs de áudio otimizados para fala nunca decolaram na Web. Portanto, vou me concentrar
nos codecs de áudio com perdas de uso geral.

Como mencionei em “Codecs de vídeo” na página 83, quando você “assiste a um vídeo”, seu computador está
fazendo várias coisas ao mesmo tempo:

1. Interpretando o formato do contêiner 2.

Decodificando o fluxo de vídeo 3.

Decodificando o fluxo de áudio e enviando o som para seus alto-falantes

Codecs de áudio | 85

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

O codec de áudio especifica como fazer o número 3: decodificar o fluxo de áudio e transformá-lo em
formas de onda digitais que seus alto-falantes transformam em som. Tal como acontece com os codecs
de vídeo, existem vários truques para minimizar a quantidade de informações armazenadas no fluxo de áudio.
E como estamos falando de codecs de áudio com perdas , as informações são perdidas durante o ciclo
de vida de gravaçãoÿcodificaçãoÿdecodificaçãoÿaudição. Diferentes codecs de áudio jogam fora coisas
diferentes, mas todos têm o mesmo propósito: enganar seus ouvidos para que não percebam as partes
que estão faltando.

Um conceito que o áudio tem e o vídeo não é o de canais. Estamos enviando som para seus alto-falantes,
certo? Bem, quantos alto-falantes você tem? Se você estiver sentado em frente ao computador, poderá
ter apenas dois: um à esquerda e outro à direita. Minha área de trabalho tem três: esquerda, direita e
mais uma no chão. O chamado “som surround” os sistemas podem ter seis ou mais alto-falantes,
estrategicamente posicionados pela sala. Cada alto-falante é alimentado por um canal específico da
gravação original. A teoria é que você pode sentar-se no meio dos seis alto-falantes, literalmente cercado
por seis canais separados de som, e seu cérebro os sintetiza e faz você se sentir como se estivesse no
meio da ação.
Funciona? Uma indústria multibilionária parece pensar assim.

A maioria dos codecs de áudio de uso geral pode lidar com dois canais de som. Durante a gravação, o
som é dividido nos canais esquerdo e direito; durante a codificação, ambos os canais são armazenados
no mesmo fluxo de áudio; e durante a decodificação, ambos os canais são decodificados e cada um é
enviado ao alto-falante apropriado. Alguns codecs de áudio podem lidar com mais de dois canais e
controlam qual canal é qual, para que o player possa enviar o som certo para o alto-falante certo.

Existem muitos codecs de áudio. Eu disse que havia muitos codecs de vídeo? Esqueça isso.
Existem muitos codecs de áudio, mas na Web, existem apenas três que você precisa conhecer: MP3,
AAC e Vorbis.

MPEG-1 Camada de Áudio 3

MPEG-1 Camada de Áudio 3 é coloquialmente conhecido como “MP3”. Se você ainda não ouviu falar de
MP3, não sei o que fazer com você. Walmart vende tocadores de música portáteis e os chama de
“leitores de MP3”. Walmart. De qualquer forma...

Os MP3s podem conter até dois canais de som. Eles podem ser codificados em diferentes taxas de bits:
64 kbps, 128 kbps, 192 kbps e uma variedade de outras, de 32 a 320. Taxas de bits mais altas significam
tamanhos de arquivo maiores e áudio de melhor qualidade, embora a relação entre qualidade de áudio e
taxa de bits não seja linear. (128 kbps soa duas vezes melhor que 64 kbps, mas 256 kbps não soa duas
vezes melhor que 128 kbps.) Além disso, o formato MP3 (padronizado em 1991) permite codificação de
taxa de bits variável, o que significa que algumas partes do o fluxo codificado é compactado mais do que
outros. Por exemplo, o silêncio entre as notas pode ser codificado em uma taxa de bits muito baixa e, em
seguida, a taxa de bits pode aumentar um momento depois, quando vários instrumentos começarem a
tocar um acorde complexo. Os MP3s também podem ser codificados com uma taxa de bits constante,
que, sem surpresa, é chamada de codificação de taxa de bits constante.

86 | Capítulo 5: Vídeo na Web

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

O padrão MP3 não define exatamente como codificar MP3s (embora defina exatamente como decodificá-
los); diferentes codificadores usam diferentes modelos psicoacústicos que produzem resultados totalmente
diferentes, mas são todos decodificáveis pelos mesmos jogadores. O projeto LAME de código aberto é o
melhor codificador gratuito e, sem dúvida, o melhor codificador, ponto final, para todas as taxas de bits,
exceto as mais baixas.

O formato MP3 é protegido por patente, o que explica por que o Linux não consegue reproduzir arquivos
MP3 imediatamente. Praticamente todos os reprodutores de música portáteis suportam arquivos MP3
independentes, e os fluxos de áudio MP3 podem ser incorporados em qualquer contêiner de vídeo. O
Adobe Flash pode reproduzir arquivos MP3 independentes e fluxos de áudio MP3 em um contêiner de vídeo MP4.

Codificação de áudio avançada

Codificação de áudio avançada é carinhosamente conhecido como “AAC”. Padronizado em 1997, ganhou
destaque quando a Apple o escolheu como formato padrão para a iTunes Store.
Originalmente, todos os arquivos AAC “comprados” na iTunes Store eram criptografados com o esquema
DRM proprietário da Apple, chamado FairPlay. Muitas músicas na iTunes Store agora estão disponíveis
como arquivos AAC desprotegidos, que a Apple chama de “iTunes Plus” porque soa muito melhor do que
chamar todo o resto de “iTunes Minus”. O formato AAC está protegido por patente; as taxas de
licenciamento estão disponíveis online.

O AAC foi projetado para fornecer melhor qualidade de som do que o MP3 na mesma taxa de bits e pode
codificar áudio em qualquer taxa de bits. (O MP3 é limitado a um número fixo de taxas de bits, com um
limite superior de 320 kbps.) O AAC pode codificar até 48 canais de som, embora na prática ninguém faça
isso. O formato AAC também difere do MP3 na definição de múltiplos perfis, da mesma forma que o H.264,
e pelas mesmas razões. O perfil de “baixa complexidade” foi projetado para ser reproduzido em tempo
real em dispositivos com potência de CPU limitada, enquanto perfis mais altos oferecem melhor qualidade
de som na mesma taxa de bits, às custas de codificação e decodificação mais lentas.

Todos os produtos atuais da Apple, incluindo iPods, AppleTV e QuickTime, suportam determinados perfis
de AAC em arquivos de áudio independentes e em fluxos de áudio em um contêiner de vídeo MP4. Adobe
Flash suporta todos os perfis de AAC em MP4, assim como os reprodutores de vídeo MPlayer e VLC de
código aberto. Para codificação, a biblioteca FAAC é a opção de código aberto; o suporte para isso é uma
opção de tempo de compilação no mencoder e ffmpeg.

Vorbis
Vorbis é frequentemente chamado de “Ogg Vorbis”, embora isso seja tecnicamente incorreto – “Ogg” é
apenas um formato de contêiner (consulte “Contêineres de vídeo” na página 81), e os fluxos de áudio
Vorbis podem ser incorporados em outros contêineres. Vorbis não está sobrecarregado por nenhuma
patente conhecida e, portanto, é suportado imediatamente por todas as principais distribuições Linux e
por dispositivos portáteis que executam o Rockbox de código aberto. firmware. Mozilla Firefox 3.5 suporta
arquivos de áudio Vorbis em um contêiner Ogg ou vídeos Ogg com uma trilha de áudio Vorbis. Um andróide
telefones celulares também podem reproduzir arquivos de áudio Vorbis independentes. Fluxos de áudio Vorbis

Codecs de áudio | 87

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

geralmente são incorporados em um contêiner Ogg ou WebM, mas também podem ser incorporados em um MP4
ou MKV container, ou, com algum hacking, em AVI. Vorbis suporta um número arbitrário de canais de som.

Existem codificadores e decodificadores Vorbis de código aberto, incluindo o codificador OggConvert , o


decodificador ffmpeg , o codificador aoTuV, e o decodificador libvorbis. Existem também componentes QuickTime
para Mac OS X e filtros DirectShow para Windows.

O que funciona na web


Se seus olhos ainda não estão vidrados, você está se saindo melhor do que a maioria. Como você pode ver,
vídeo (e áudio) é um assunto complicado – e esta foi a versão resumida! Tenho certeza que você está se
perguntando como tudo isso se relaciona com o HTML5. Bem, o HTML5 inclui um elemento <video> para
incorporar vídeo em uma página da web. Não há restrições quanto ao codec de vídeo, codec de áudio ou formato
de contêiner que você pode usar para seu vídeo. Um elemento <video> pode vincular vários arquivos de vídeo, e
o navegador escolherá o primeiro arquivo de vídeo que pode realmente reproduzir. Cabe a você saber quais
navegadores suportam quais contêineres e codecs.

No momento em que este livro foi escrito, este é o cenário do vídeo HTML5:

• Mozilla Firefox (3.5 e posterior) suporta vídeo Theora e áudio Vorbis em um


Recipiente Ogg.

• Opera (10.5 e posterior) suporta vídeo Theora e áudio Vorbis em formato Ogg
recipiente.

• Google Chrome (3.0 e posterior) suporta vídeo Theora e áudio Vorbis em um contêiner Ogg. Ele também
suporta vídeo H.264 (todos os perfis) e áudio AAC (todos os perfis) em um contêiner MP4.

• No momento em que este livro foi escrito (9 de junho de 2010), o “canal de desenvolvimento” do Google
Chrome, compilações noturnas do Chromium, compilações noturnas do Mozilla Firefox, e versões
experimentais do Opera todos suportam vídeo VP8 e áudio Vorbis em um contêiner WebM. (Visite webm
project.org para obter informações mais atualizadas e links de download para navegadores compatíveis
com WebM.)

• O Safari em Macs e PCs com Windows (3.0 e posteriores) suportará tudo o que o Quick Time suportar. Em
teoria, você poderia exigir que seus usuários instalassem plug-ins Quick Time de terceiros. Na prática,
poucos usuários farão isso. Então você fica com os formatos que o QuickTime suporta “prontos para usar”.
Esta é uma lista longa, mas não inclui vídeo Theora, áudio Vorbis ou contêiner Ogg. No entanto, QuickTime
suporta vídeo H.264 (perfil principal) e áudio AAC em um contêiner MP4.

• Dispositivos móveis como o iPhone da Apple e os telefones Android do Google suportam vídeo H.264 (perfil
de linha de base) e áudio AAC (perfil de baixa complexidade) em um contêiner MP4.

88 | Capítulo 5: Vídeo na Web

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

• Adobe Flash (9.0.60.184 e posterior) suporta vídeo H.264 (todos os perfis) e AAC

áudio (todos os perfis) em um contêiner MP4.

• O Internet Explorer 9 suportará alguns perfis de vídeo H.264 ainda não especificados
e áudio AAC em um contêiner MP4.

• O Internet Explorer 8 não tem suporte para vídeo HTML5, mas praticamente todos os recursos da Internet

Os usuários do Explorer terão o plug-in Adobe Flash. Mais adiante neste capítulo, mostrarei

você como você pode usar vídeo HTML5, mas voltar ao Flash.

A Tabela 5-2 fornece as informações acima de uma forma mais fácil de digerir.

Tabela 5-2. Suporte a codec de vídeo em navegadores de envio

Codecs/contêiner Ou seja Raposa de fogo Safári cromada Ópera Iphone Android

· 3,5+ · 5,0+ 10,5+ · ·


Theora+Vorbis+Ogg

H.264+AAC+MP4 · · 3,0+ 5,0+ · 3,0+ 2,0+

WebM · · · · · · ·

Daqui a um ano, o cenário parecerá significativamente diferente: o WebM será implementado em vários navegadores, esses navegadores

fornecerão versões não experimentais habilitadas para WebM e os usuários atualizarão para essas novas versões. O codec esperado

o suporte é mostrado na Tabela 5-3.

Tabela 5-3. Suporte a codec de vídeo em navegadores futuros

Codecs/contêiner Ou seja Raposa de fogo Safári cromada Ópera Iphone Android

· 3,5+ · 5,0+ 10,5+ · ·


Theora+Vorbis+Ogg

H.264+AAC+MP4 · · 3,0+ 5,0+ · 3,0+ 2,0+

· · b
WebM 9,0+a 4,0+ 6,0+ 11,0+
a
O Internet Explorer 9 só suportará WebM “quando o usuário tiver instalado um codec VP8”, o que implica que a Microsoft não enviará
o próprio codec.
b
O Google se comprometeu a apoiar o WebM “em uma versão futura” do Android, mas ainda não há um cronograma definido.

E agora o nocaute....

Professor Markup diz

Não existe uma combinação única de contêineres e codecs que funcione em todos os HTML5
navegadores.

Não é provável que isto mude num futuro próximo.

Para tornar seu vídeo assistido em todos esses dispositivos e plataformas, você vai
precisar codificar seu vídeo mais de uma vez.

Para obter compatibilidade máxima, veja como será o fluxo de trabalho do seu vídeo:

O que funciona na Web | 89

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

1. Faça uma versão que use vídeo Theora e áudio Vorbis em um contêiner Ogg.
2. Faça outra versão que utilize WebM (VP8 + Vorbis).

3. Faça outra versão que use vídeo H.264 Baseline e AAC de baixa complexidade
áudio em um contêiner MP4.

4. Vincule todos os três arquivos de vídeo a partir de um único elemento <video> e volte para um player de
vídeo baseado em Flash.

Problemas de licenciamento com vídeo H.264

Antes de continuarmos, preciso ressaltar que há um custo para codificar seus vídeos duas vezes. Ou seja,
além do custo óbvio – que você precisa codificar seus vídeos duas vezes, o que leva mais computadores e
mais tempo do que apenas fazer isso uma vez – há outro custo muito real associado ao vídeo H.264: taxas de
licenciamento.

Lembra quando expliquei pela primeira vez o vídeo H.264 (veja “H.264” na página 84) e mencionei que o
codec de vídeo estava sujeito a patentes e o licenciamento era intermediado pelo consórcio MPEG LA? Isso
acaba sendo importante. Para entender por que isso é importante, direciono você para o Labirinto de
Licenciamento H.264:*

A MPEG LA divide o portfólio de licenças H.264 em duas sublicenças: uma para fabricantes de
codificadores ou decodificadores e outra para distribuidores de conteúdo. [...]

A sublicença no lado da distribuição é dividida em quatro subcategorias principais, duas das quais
(assinatura e compra título por título ou uso pago) estão vinculadas ao fato de o usuário final pagar
diretamente pelos serviços de vídeo, e duas das quais (“ televisão gratuita e transmissão pela
Internet) estão vinculados à remuneração de outras fontes que não o telespectador final. [...]

A taxa de licenciamento para televisão “gratuita” baseia-se numa de duas opções de royalties. O
primeiro é um pagamento único de US$ 2.500 por codificador de transmissão AVC, que cobre um
codificador AVC “usado por ou em nome de um Licenciado na transmissão de vídeo AVC para o
Usuário Final”, que o decodificará e visualizará. Se você está se perguntando se esta é uma
cobrança dupla, a resposta é sim: uma taxa de licença já foi cobrada do fabricante do codificador e
a emissora, por sua vez, pagará uma das duas opções de royalties.

A segunda taxa de licenciamento é uma taxa anual de transmissão. [...] [A] taxa anual de transmissão
é dividida por tamanho de audiência:

• US$ 2.500 por ano civil por mercados de transmissão de 100.000 a 499.999 televisões
famílias

• US$ 5.000 por ano civil por mercado de transmissão de 500.000 a 999.999 televisões
famílias

• US$ 10.000 por ano civil por mercado de transmissão de 1.000.000 ou mais de televisão
famílias

* http:// www.streamingmedia.com/ Articles/ Editorial/ Featured-Articles/ The-H.264-Licensing-Labyrinth-65403


.aspx.

90 | Capítulo 5: Vídeo na Web

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

[...] Com todas as questões em torno da televisão “gratuita”, por que alguém envolvido na distribuição não
transmitida deveria se preocupar? Como mencionei antes, as taxas de participação aplicam-se a qualquer entrega
de conteúdo. Depois de definir que televisão “gratuita” significava mais do que apenas [over-the-air], a MPEG LA
passou a definir taxas de participação para transmissão pela Internet como “vídeo AVC que é entregue através da
Internet mundial a um usuário final para o qual o usuário final não não pagar remuneração pelo direito de receber

ou visualizar.” Em outras palavras, qualquer transmissão pública, seja ela [over-the-air], cabo, satélite ou Internet,
está sujeita a taxas de participação. [...]

As taxas são potencialmente um pouco mais elevadas para transmissões pela Internet, talvez assumindo que a
distribuição pela Internet crescerá muito mais rapidamente do que a OTA ou a televisão “gratuita” via cabo ou satélite.
Adicionando a taxa do mercado de transmissão de “televisão gratuita” juntamente com uma taxa adicional, a MPEG
LA concede uma espécie de indulto durante o primeiro período de licença, que termina em 31 de dezembro de
2010, e observa que “após o primeiro período, o royalty será não mais do que o equivalente económico dos
royalties devidos durante o mesmo período pela televisão gratuita.”

A última parte – sobre a estrutura de taxas para transmissões pela Internet – já foi alterada. A MPEG
LA anunciou recentemente esse streaming gratuito pela Internet seria estendido até 31 de dezembro
de 2015. E depois disso... quem sabe?

Codificando vídeo Ogg com Firefogg


(Nesta seção, usarei “vídeo Ogg” como uma abreviação para “vídeo Theora e áudio Vorbis em um
contêiner Ogg”. Esta é a combinação de codecs + contêiner que funciona nativamente no Mozilla Firefox
e no Google Chrome.)

Firefogg é uma extensão do Firefox de código aberto e licenciada pela GPL para codificação de vídeo
Ogg. Para usá-lo, você precisará instalar o Mozilla Firefox 3.5 ou posterior, visite o site do Firefogg,
mostrado na Figura 5-1.

Clique em “Instalar Firefogg”. O Firefox perguntará se você realmente deseja permitir que o site instale
uma extensão. Clique em “Permitir” para continuar (Figura 5-2).

O Firefox apresentará a janela padrão de instalação do software. Clique em “Instalar agora” para
continuar (Figura 5-3).

Clique em “Reiniciar Firefox” para concluir a instalação (Figura 5-4).

Assim que o Firefox for reiniciado, o site do Firefogg confirmará que o Firefogg foi instalado com
sucesso (Figura 5-5).

Clique em “Make Ogg Video” para iniciar o processo de codificação (Figura 5-6), depois clique em
“Select file” para selecionar o vídeo de origem (Figura 5-7).

Codificando vídeo Ogg com Firefogg | 91

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Figura 5-1. Página inicial do Firefogg

Figura 5-2. Permitir que o Firefogg seja instalado

92 | Capítulo 5: Vídeo na Web

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Figura 5-3. Instale o Firefogg

Figura 5-4. Reinicie o Firefox

Codificando vídeo Ogg com Firefogg | 93

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Figura 5-5. Instalação bem sucedida

Figura 5-6. Vamos fazer um vídeo!

94 | Capítulo 5: Vídeo na Web

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Figura 5-7. Selecione seu arquivo de vídeo

A interface principal do Firefogg possui seis “abas” (mostradas na Figura 5-8):

Predefinições A predefinição padrão é “vídeo da web”, o que é adequado para nossos propósitos.

Faixa de codificação A
codificação de vídeo pode levar muito tempo. Ao começar, você pode querer codificar apenas parte do seu vídeo (digamos,
os primeiros 30 segundos) até encontrar uma combinação de configurações de sua preferência.

Controle básico de qualidade e resolução É aqui que


estão a maioria das opções importantes.

Metadados

Não vou abordar isso aqui, mas você pode adicionar metadados como título e autor ao seu vídeo codificado. Você
provavelmente adicionou metadados à sua coleção de músicas com o iTunes ou algum outro gerenciador de música. Esta é
a mesma ideia.

Controles avançados de codificação de vídeo Não


mexa com eles, a menos que você saiba o que está fazendo. (O Firefogg oferece ajuda interativa na maioria dessas opções.
Clique no símbolo “i” ao lado de cada opção para saber mais sobre ela.)

Controles avançados de codificação de áudio


Novamente, não mexa com isso a menos que saiba o que está fazendo.

Codificando vídeo Ogg com Firefogg | 95

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Figura 5-8. Vamos codificar um vídeo

Veremos apenas a aba “Controle básico de qualidade e resolução” (Figura 5-9), que contém todas as
opções importantes:

Qualidade de
vídeo É medida em uma escala de 0 (qualidade mais baixa) a 10 (qualidade mais alta). Números mais altos
significam tamanhos de arquivo maiores, então você precisará experimentar para determinar a melhor
relação tamanho/qualidade para suas necessidades.

Qualidade de áudio
É medida em uma escala de –1 (qualidade mais baixa) a 10 (qualidade mais alta). Números mais altos significam
tamanhos de arquivo maiores, assim como acontece com a configuração de qualidade de vídeo.
Codec de
vídeo Deve ser sempre “theora”.
Codec de áudio
Deve ser sempre “vorbis”.
Largura e altura do vídeo
O padrão é a largura e altura reais do vídeo de origem. Se quiser redimensionar o vídeo durante a
codificação, você pode alterar a largura ou altura aqui. O Firefogg ajustará automaticamente a
outra dimensão para manter as proporções originais, para que seu vídeo não fique amassado ou
esticado.

Na Figura 5-10, redimensiono o vídeo para metade da largura original. Observe como o Firefogg ajusta
automaticamente a altura para corresponder.

96 | Capítulo 5: Vídeo na Web

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Figura 5-9. Controle básico de qualidade e resolução

Figura 5-10. Ajuste a largura e altura do vídeo

Codificando vídeo Ogg com Firefogg | 97

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Depois de mexer em todos os botões, clique em “Salvar Ogg” para iniciar o processo de codificação real
(Figura 5-11). O Firefogg solicitará um nome de arquivo para o vídeo codificado.

Figura 5-11. Inicie o processo de codificação clicando em “Salvar Ogg”

O Firefogg mostrará uma bela barra de progresso enquanto codifica seu vídeo (Figura 5-12). Tudo que
você precisa fazer é esperar (e esperar e esperar)!

Codificação em lote de vídeo Ogg com ffmpeg2theora


(Como na seção anterior, nesta seção usarei “vídeo Ogg” como abreviação de “vídeo Theora e áudio
Vorbis em um contêiner Ogg”. Esta é a combinação de codecs+contêiner que funciona nativamente no
Mozilla Firefox e Google Chrome.)

Existem vários codificadores offline para vídeo Ogg. Se você está pensando em codificar em lote muitos
arquivos de vídeo e deseja automatizar o processo, você definitivamente deveria dar uma olhada no
ffmpeg2theora. ffmpeg2theora

é um aplicativo de código aberto licenciado pela GPL para codificação de vídeo Ogg.
Binários pré-construídos estão disponíveis para Mac OS X, Windows e distribuições Linux modernas . Ele
pode receber praticamente qualquer arquivo de vídeo como entrada, incluindo o vídeo DV produzido por
muitas filmadoras de consumo.

Para usar o ffmpeg2theora, você precisa chamá-lo na linha de comando. (No Windows, vá para Menu
IniciarÿProgramasÿAcessóriosÿPrompt de Comando. No Mac OS X, abra AplicativosÿUtilitáriosÿTerminal.)

98 | Capítulo 5: Vídeo na Web

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Figura 5-12. Codificação em andamento

ffmpeg2theora pode receber um grande número de sinalizadores de linha de comando. (Digite


ffmpeg2theora -- ajude a ler sobre todos eles.) Vou me concentrar

em apenas três deles: • --video-quality Q, onde Q é um


número de 0 a 10. • --audio-quality Q, onde Q é um número
de –2 a 10. • --max_size=LxA, onde L e A são a largura e altura máximas desejadas para o
vídeo. (O x intermediário é na verdade apenas a letra “x”.) O ffmpeg2theora redimensionará
o vídeo proporcionalmente para caber nessas dimensões, de modo que o vídeo codificado
pode ser menor que W×H. Por exemplo, codificar um vídeo de 720 × 480 pixels com --
max_size 320x240 produzirá um vídeo com 320 pixels de largura e 213 pixels de altura.

Portanto, aqui está como você pode codificar um vídeo com as mesmas configurações que
usamos na seção anterior (“Codificando vídeo Ogg com Firefogg” na página 91):
você@localhost$ ffmpeg2theora --videoquality
5 --audioquality
1 --max_size
320x240 pr6.dv

O vídeo codificado será salvo no mesmo diretório do vídeo original, com uma extensão .ogv
adicionada. Você pode especificar um local e/ou nome de arquivo diferente passando um
sinalizador de linha de comando --output=/ path/ to/ encoded/ video para ffmpeg2theora.

Codificação em lote de vídeo Ogg com ffmpeg2theora | 99

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Codificando vídeo H.264 com HandBrake


(Nesta seção, usarei “vídeo H.264” como uma abreviação para “vídeo de perfil de linha de base H.264 e áudio
de perfil de baixa complexidade AAC em um contêiner MPEG-4”. Esta é a combinação de codecs+ contêiner
que funciona nativamente no Safari, no Adobe Flash, no iPhone e em dispositivos Google Android.)

Deixando de lado as questões de licenciamento (consulte “Problemas de licenciamento com vídeo H.264” na
página 90), a maneira mais fácil de codificar vídeo H.264 é usando o HandBrake. HandBrake é um aplicativo
de código aberto licenciado pela GPL para codificação de vídeo H.264. (Ele costumava fazer outros formatos
de vídeo também, mas na versão mais recente os desenvolvedores abandonaram o suporte para a maioria dos
outros formatos e concentraram todos os seus esforços no vídeo H.264.) Binários pré-construídos estão
disponíveis para Windows , Mac OS X e sistemas modernos. Distribuições Linux.

O HandBrake vem em dois sabores: gráfico e linha de comando. Apresentarei primeiro a interface gráfica e
depois veremos como minhas configurações recomendadas se traduzem em
a versão da linha de comando.

Depois de abrir o aplicativo HandBrake, a primeira coisa a fazer é selecionar o vídeo de origem (Figura 5-13).
Clique em “Fonte” e escolha “Arquivo de vídeo” no menu suspenso para selecionar um arquivo. O HandBrake
pode receber praticamente qualquer arquivo de vídeo como entrada, incluindo vídeo DV produzido por muitas
filmadoras de consumo.

Figura 5-13. Selecione seu vídeo de origem

100 | Capítulo 5: Vídeo na Web

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

O HandBrake reclamará que você não definiu um diretório padrão para salvar seus vídeos
codificados (Figura 5-14). Você pode ignorar este aviso com segurança ou pode abrir a janela de
opções (no menu “Ferramentas”) e definir um diretório de saída padrão.

Figura 5-14. Ignore este aviso

No lado direito está uma lista de predefinições. Selecionar a predefinição “iPhone e iPod Touch”,
como na Figura 5-15, definirá a maioria das opções necessárias.

Uma opção importante que está desativada por padrão é a opção “Otimizado para Web”.
Selecionar esta opção, conforme mostrado na Figura 5-16, reordena alguns dos metadados do
vídeo codificado para que você possa assistir ao início do vídeo enquanto o restante é baixado
em segundo plano. Eu recomendo sempre marcar esta opção. Isso não afeta a qualidade ou o
tamanho do arquivo do vídeo codificado, então não há razão para não fazê-lo.

Na aba “Imagem”, você pode definir a largura e altura máximas do vídeo codificado (Figura 5-17).
Você também deve selecionar a opção “Manter proporção de aspecto” para garantir que o
HandBrake não estique ou estique seu vídeo ao redimensioná-lo.

Codificando vídeo H.264 com HandBrake | 101

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Figura 5-15. Selecione a predefinição do iPhone

Figura 5-16. Sempre otimize para a Web

102 | Capítulo 5: Vídeo na Web

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Figura 5-17. Definir largura e altura

Na aba “Vídeo”, mostrada na Figura 5-18, você pode definir diversas opções importantes:

Codec de vídeo
Certifique-se de que seja “H.264 (x264)”.

Codificação de 2
passagens Se esta opção estiver marcada, o HandBrake executará o codificador de vídeo duas vezes.
Na primeira vez, ele apenas analisa o vídeo, procurando coisas como composição de cores, movimento
e quebras de cena. Na segunda vez, ele codifica o vídeo usando as informações que aprendeu durante
a primeira passagem. Como seria de esperar, isso leva cerca de duas vezes mais tempo que a
codificação de passagem única, mas resulta em um vídeo melhor sem aumentar o tamanho do arquivo.
Sempre habilito a codificação de duas passagens para vídeo H.264. A menos que você esteja construindo
o próximo YouTube e codificando vídeos 24 horas por dia, você provavelmente também deverá usar a
codificação em duas passagens.
Turbo First Pass
Quando você habilita a codificação de duas passagens, você pode recuperar um pouco de tempo
habilitando esta opção. Reduz a quantidade de trabalho realizado na primeira passagem (análise do
vídeo), ao mesmo tempo que degrada apenas ligeiramente a qualidade. Normalmente habilito esta
opção, mas se a qualidade é de extrema importância para você, deixe-a desabilitada.

Qualidade
Existem várias maneiras diferentes de especificar a “qualidade” do seu vídeo codificado.
Você pode definir um tamanho de arquivo de destino e o HandBrake fará o possível para garantir que o
vídeo codificado não seja maior do que isso. Você pode definir uma “taxa de bits” média, que é

Codificando vídeo H.264 com HandBrake | 103

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

literalmente, o número de bits necessários para armazenar um segundo de vídeo codificado. (É


chamada de taxa de bits “média” porque alguns segundos exigirão mais bits do que outros.) Ou você
pode especificar uma qualidade constante, em uma escala de 0 a 100 por cento.
Números mais altos resultarão em arquivos de melhor qualidade, mas maiores. Não existe uma resposta
certa para qual configuração de qualidade você deve usar.

Pergunte ao Professor Markup

P: Posso usar codificação de duas passagens em vídeo Ogg também?

R: Sim, mas devido a diferenças fundamentais no funcionamento do codificador, provavelmente não será
necessário. A codificação H.264 de duas passagens quase sempre resulta em vídeo de maior qualidade.
A codificação Ogg de duas passagens de vídeo Ogg só é útil se você estiver tentando fazer com que seu vídeo
codificado tenha um tamanho de arquivo específico. (Talvez isso seja algo em que você esteja interessado, mas
não é o que esses exemplos mostram e provavelmente não vale a pena gastar tempo extra para codificar vídeo da
web.) Para obter a melhor qualidade de vídeo Ogg, use as configurações de qualidade de vídeo e não se preocupe .
sobre codificação de duas passagens.

Figura 5-18. Opções de qualidade de vídeo

104 | Capítulo 5: Vídeo na Web

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Neste exemplo, escolhi uma taxa de bits média de 600 kbps, que é bastante alta para um vídeo codificado em
320×240. Também habilitei a codificação de duas passagens com uma primeira passagem “turbo”.

Na aba “Áudio”, mostrada na Figura 5-19, você provavelmente não precisará alterar nada.
Se o seu vídeo de origem tiver várias trilhas de áudio, talvez seja necessário selecionar qual delas deseja no
vídeo codificado. Se o seu vídeo for principalmente uma pessoa falando (em oposição a música ou sons ambientais
em geral), você provavelmente poderá reduzir a taxa de bits do áudio para 96 kbps ou mais. Fora isso, os padrões
que você herdou da predefinição “iPhone” devem servir.

Figura 5-19. Opções de qualidade de áudio

Em seguida, clique no botão “Browse” e escolha um diretório e nome de arquivo para salvar seu vídeo codificado
(Figura 5-20).

Finalmente, clique em “Iniciar” para iniciar a codificação (Figura 5-21).

O HandBrake exibirá algumas estatísticas de progresso enquanto codifica seu vídeo (Figura 5-22).

Codificando vídeo H.264 com HandBrake | 105

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Figura 5-20. Definir nome do arquivo de destino

Figura 5-21. Vamos fazer um vídeo!

106 | Capítulo 5: Vídeo na Web

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Figura 5-22. Paciência, gafanhoto

Codificação em lote de vídeo H.264 com HandBrake


(Como na seção anterior, nesta seção usarei “vídeo H.264” como uma abreviação para “vídeo de perfil
de linha de base H.264 e áudio de perfil de baixa complexidade AAC em um contêiner MPEG-4”. Isso é a
combinação de codecs+contêiner que funciona nativamente no Safari, no Adobe Flash, no iPhone e em
dispositivos Google Android.)

Como mencionei na seção anterior, o HandBrake também vem em uma edição de linha de comando.
Tal como acontece com a edição gráfica, você deve baixar um instantâneo recente em http:// handbrake.fr/
downloads2.php.

Assim como o ffmpeg2theora (consulte “Codificação em lote de vídeo Ogg com ffmpeg2the ora” na
página 98), a edição de linha de comando do HandBrake oferece uma variedade estonteante de opções.
(Digite HandBrakeCLI --help em uma janela do Terminal ou em um prompt de comando para ler sobre
eles.) Vou me concentrar em apenas alguns:

• --preset "X", onde "X" é o nome de um preset do HandBrake (é importante colocar o nome entre
aspas). A predefinição que você deseja para o vídeo da web H.264 é chamada de “iPhone e iPod
Touch”.

• --width W, onde W é a largura do seu vídeo codificado. O HandBrake ajustará automaticamente a


altura para manter as proporções do vídeo original. • --vb Q, onde Q é a taxa de
bits média (medida em kilobits por segundo). • --two-pass, que permite a codificação em
duas passagens. • --turbo, que permite uma primeira
passagem turbo durante a codificação de duas passagens. • --input F, onde F é o
nome do arquivo do vídeo de origem. • --output E, onde E é o nome do
arquivo de destino para seu vídeo codificado.

Aqui está um exemplo de chamada do HandBrake na linha de comando, com sinalizadores de linha de
comando que correspondem às configurações que escolhemos com a versão gráfica do HandBrake:

você@localhost$ HandBrakeCLI --preset "iPhone e iPod


Touch" --
width
320 --vb
600 --
two-pass --
turbo --input pr6.dv --output pr6.mp4

Codificação em lote de vídeo H.264 com HandBrake | 107

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

De cima para baixo, este comando executa o HandBrake com o “iPhone e iPod Touch”
predefinido, redimensiona o vídeo para 320 × 240, define a taxa de bits média para 600 kbps, habilita a
codificação de duas passagens com uma primeira passagem turbo, lê o arquivo pr6.dv e o codifica como pr6.mp4.
Uau!

Codificando vídeo WebM com ffmpeg


Estou escrevendo isso em 20 de maio de 2010. O formato WebM foi literalmente lançado ontem.
Como tal, não há muitas opções de ferramentas de codificação e muito poucos guias completos.
Estão disponíveis. Tudo isso ficará mais fácil à medida que as ferramentas forem escritas (ou atualizadas) para fornecer
suporte com um clique para WebM. Até então, aqui estão as ferramentas de que você precisará:

• libvp8 e uma versão especial do ffmpeg com patches adicionais (para conectá-lo com
libvp8) que ainda não fazem parte do repositório oficial do ffmpeg :

—Instruções para Linux, que testei pessoalmente no Ubuntu “Lucid” 10.04.

—Instruções para Windows, que eu não testei pessoalmente.


• A versão mais recente do mkclean.

Preparar? OK. Na linha de comando, execute ffmpeg sem parâmetros e verifique se ele
foi compilado com suporte VP8:

você@localhost$ ffmpeg
Versão FFmpeg SVN-r23197, Copyright (c) 2000-2010 os desenvolvedores do FFmpeg
construído em 19 de maio de 2010 22:32:20 com gcc 4.4.3
configuração: --enable-gpl --enable-version3 --enable-nonfree --enable-postproc --enable-pthreads --enable-
libfaac --enable-libfaad --enable-libmp3lame --enable-libopencore-amrnb - -enable-libopencore-
amrwb --enable-libtheora --enable-libx264 --enable-libxvid --enable-x11grab --enable-libvpx-vp8

Se você não vir as palavras mágicas --enable-libvpx-vp8, você não tem a versão correta
do ffmpeg. (Se você jura que compilou corretamente, verifique se você tem dois
versões instaladas. Tudo bem, eles não entrarão em conflito um com o outro - você só precisará
use o caminho completo da versão do ffmpeg habilitada para VP8.)

Vou mostrar como fazer uma codificação em duas passagens (veja “Codificando vídeo H.264 com
HandBrake” na página 100). A primeira passagem apenas examina o arquivo de vídeo de entrada
(-i pr6.dv) e escreve algumas estatísticas em um arquivo de log (que será nomeado automaticamente
pr6.dv-0.log). Você especifica o codec de vídeo com o parâmetro -vcodec :

você @ localhost $ ffmpeg -pass 1 -passlogfile pr6.dv -threads 16 -token_partitions 4 -altref 1 -lag 16
-keyint_min 0 -g 250 -mb_static_threshold 0 -skip_threshold 0 -qmin 1 -qmax
51 -i pr6.dv -vcodec libvpx_vp8 -an -f rawvideo -y NUL

108 | Capítulo 5: Vídeo na Web

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

A maior parte da linha de comando do ffmpeg não tem nada a ver com VP8 ou WebM. libvp8 suporta uma
série de opções específicas do VP8 que você pode passar para o ffmpeg, mas ainda não sei como nenhuma
delas funciona. Assim que encontrar uma boa explicação sobre essas opções, fornecerei um link no site
deste livro.

Para a segunda passagem, o ffmpeg lerá as estatísticas que escreveu durante a primeira passagem e
realmente fará a codificação do vídeo e do áudio. Ele gravará um arquivo MKV, que converteremos
posteriormente em um arquivo WebM. (Eventualmente, o ffmpeg será capaz de gravar arquivos WebM
diretamente, mas essa funcionalidade está atualmente quebrada de maneira sutil e perniciosa.)
Aqui está a linha de comando para a segunda passagem:

você @ localhost $ ffmpeg -pass 2 -passlogfile pr6.dv -threads 16 -token_partitions 4


-altref 1 -lag 16 -keyint_min 0 -g 250 -mb_static_threshold 0
-skip_threshold 0 -qmin 1 -qmax 51 -i pr6.dv -vcodec libvpx_vp8
-b 614400 -s 320x240 -aspecto 4:3 -acodec vorbis -y pr6.mkv

Existem cinco parâmetros importantes aqui:

-vcodec libvpx_vp8
Especifica que estamos codificando com o codec de vídeo VP8. WebM sempre usa vídeo VP8.

-b 614400
Especifica a taxa de bits. Ao contrário de outros formatos, o libvp8 espera a taxa de bits em bits reais,
não em kilobits. Se você quiser um vídeo de 600 kbps, multiplique 600 por 1.024 para obter 614.400.
-s 320x240
Especifica o tamanho do destino, largura por altura.

-aspecto 4:3
Especifica a proporção do vídeo. O vídeo de definição padrão geralmente é 4:3, mas a maioria dos
vídeos de alta definição é 16:9 ou 16:10. Em meus testes, descobri que precisava especificar isso
explicitamente na linha de comando, em vez de confiar no ffmpeg para detectá-lo automaticamente.

-acodec vobis
Especifica que estamos codificando com o codec de áudio Vorbis. WebM sempre usa áudio Vorbis.

Agora temos um arquivo MKV com vídeo VP8 e áudio Vorbis. Isso está muito próximo do que queremos. O
formato de contêiner do WebM é tecnicamente muito semelhante ao MKV. Na verdade, é um subconjunto
adequado. Precisamos apenas mexer alguns bits para criar nosso arquivo de vídeo WebM final, usando o
utilitário mkclean Mencionei anteriormente:

você@localhost$ mkclean --doctype 4 pr6.mkv pr6.webm


E foi tudo o que ela escreveu!

Codificando vídeo WebM com ffmpeg | 109

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Por fim, a marcação


Tenho quase certeza de que este deveria ser um livro HTML. Então, onde está a marcação?

HTML5 oferece duas maneiras de incluir vídeo em sua página da web. Ambos envolvem o elemento
<video> . Se você tiver apenas um arquivo de vídeo, poderá simplesmente vinculá-lo em um atributo
src . Isso é notavelmente semelhante a incluir uma imagem com uma tag <img src="..."> .
<video src="pr6.webm"></video>

Tecnicamente, isso é tudo que você precisa. Mas assim como em uma tag <img> , você deve sempre
incluir atributos de largura e altura em suas tags <video> . Os atributos de largura e altura podem ser
iguais à largura e altura máximas especificadas durante o processo de codificação:

<video src="pr6.webm" width="320" height="240"></video>

Não se preocupe se uma dimensão do vídeo for um pouco menor que isso. Seu navegador
centralizará o vídeo dentro da caixa definida pela tag <video> . Nunca será esmagado ou esticado
fora de proporção.

Por padrão, o elemento <video> não exporá nenhum tipo de controle do player. Você pode criar
seus próprios controles com HTML, CSS e JavaScript simples e antigos. O elemento <video>
possui métodos como play() e pause() e uma propriedade de leitura/gravação chamada hora
atual . Também há volume de leitura/gravação e silenciado propriedades. Então você realmente
tem tudo o que precisa para construir sua própria interface.

Se não quiser criar sua própria interface, você pode instruir o navegador a exibir um conjunto
integrado de controles. Para fazer isso, basta incluir o atributo controles na sua tag <video> :

<video src="pr6.webm" width="320" height="240" controles></video>

Existem dois outros atributos opcionais que quero mencionar antes de prosseguirmos: pré-
carregamento e reprodução automática. Não atire no mensageiro; deixe-me explicar por que eles são úteis.
O atributo preload informa ao navegador que você gostaria que ele iniciasse o download do arquivo
de vídeo assim que a página carregasse. Isso faz sentido se o objetivo da página for visualizar o
vídeo. Por outro lado, se for apenas material suplementar que apenas alguns visitantes assistirão,
você poderá definir o pré-carregamento como nenhum para informar ao navegador para minimizar o
tráfego de rede.

Aqui está um exemplo de vídeo que começará a ser baixado (mas não será reproduzido) assim que
a página carregar:
<video src="pr6.webm" width="320" height="240" preload></video>

E aqui está um exemplo de vídeo que não inicia o download assim que a página carrega:

<video src="pr6.webm" width="320" height="240" preload="none"></video>

110 | Capítulo 5: Vídeo na Web

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

O atributo autoplay faz exatamente o que parece: informa ao navegador que você gostaria que ele
iniciasse o download do arquivo de vídeo assim que a página carregasse e que desejasse que ele
começasse a reproduzir o vídeo automaticamente o mais rápido possível. Algumas pessoas adoram
isso; algumas pessoas odeiam isso. Mas deixe-me explicar por que é importante ter um atributo como
este no HTML5. Algumas pessoas vão querer que seus vídeos sejam reproduzidos automaticamente,
mesmo que isso irrite os visitantes. Se o HTML5 não definisse uma forma padrão de reprodução
automática de vídeos, as pessoas recorreriam a hacks de JavaScript para fazer isso de qualquer
maneira, por exemplo, chamando o método play() do vídeo durante o evento de carregamento da
janela . Isso seria muito mais difícil para os visitantes neutralizarem. Por outro lado, é simples adicionar
uma extensão ao seu navegador (ou escrever uma, se necessário) que permita dizer “ignore o atributo
de reprodução automática , nunca quero que os vídeos sejam reproduzidos automaticamente”.

Aqui está um exemplo de vídeo que começará a ser baixado e reproduzido assim que possível após o
carregamento da página:
<video src="pr6.webm" width="320" height="240" reprodução automática></video>

E aqui está um Greasemonkey script que você pode instalar em sua cópia local do Firefox que impede
a reprodução automática de vídeos HTML5. Ele usa o atributo DOM de reprodução automática definido
pelo HTML5, que é o equivalente JavaScript do atributo de reprodução automática em sua marcação
HTML: // ==UserScript== //
@name //
Desativar a reprodução automática
@namespace // de vídeo http://diveintomark.org/projects/greasemonkey/ Garante que
@description // os elementos de vídeo HTML5 não sejam reproduzidos automaticamente
@include // *
==/UserScript==

var arVideos = document.getElementsByTagName('vídeo'); for (var i


= arVideos.length - 1; i >= 0; i--) { var elmVideo = arVideos[i];
elmVideo.autoplay = falso;

Mas espere um segundo. Se você acompanhou todo este capítulo, sabe que não tem apenas um
arquivo de vídeo; você tem três. Um é um arquivo .ogv que você criou com Firefogg (consulte
“Codificação de vídeo Ogg com Firefogg” na página 91) ou ffmpeg2theora (consulte “Codificação em
lote de vídeo Ogg com ffmpeg2theora” na página 98). O segundo é um arquivo .mp4 que você criou
com HandBrake (consulte “Codificando vídeo H.264 com HandBrake” na página 100). O terceiro é um
arquivo .webm que você criou com ffmpeg (consulte “Codificando vídeo WebM com ffmpeg” na página
108). HTML5 fornece uma maneira de vincular todos os três: o elemento <source> . Cada elemento
<video> pode conter quantos elementos <source> você precisar. Seu navegador percorrerá a lista de
fontes de vídeo, em ordem, e reproduzirá a primeira que for capaz de reproduzir.

Isso levanta outra questão: como o navegador sabe qual vídeo pode reproduzir? Na pior das hipóteses,
ele carrega cada um dos vídeos e tenta reproduzi-los. Isso é um grande

Por fim, a marcação | 111

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

desperdício de largura de banda, no entanto. Você economizará muito tráfego de rede se informar
antecipadamente ao navegador sobre cada vídeo. Você faz isso com o atributo type no elemento <source> .

Aqui está tudo:

<video width="320" height="240" controles>


<source src="pr6.mp4" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'>
<source src="pr6.webm" type='video/webm; codecs="vp8, vorbis"'>
<source src="pr6.ogv" type='video/ogg; codecs="theora, vorbis"'> </
video>

Vamos decompô-lo. O elemento <video> especifica a largura e a altura do vídeo, mas na verdade não
vincula a um arquivo de vídeo. Dentro do elemento <video> estão dois elementos <source> . Cada elemento
<source> vincula-se a um único arquivo de vídeo (com o atributo src ) e fornece informações sobre o
formato do vídeo (no atributo type ).

O atributo type parece complicado – caramba, é complicado. Ele contém três informações: o formato do
contêiner (consulte “Contêineres de vídeo” na página 81), o codec de vídeo (consulte “Codecs de vídeo” na
página 83) e o codec de áudio (consulte “Codecs de áudio” na página 85) . Vamos começar de baixo. Para
o arquivo de vídeo .ogv , o formato do contêiner é Ogg, representado aqui como video/ogg. (Tecnicamente
falando, esse é o tipo MIME para arquivos de vídeo Ogg.) O codec de vídeo é Theora e o codec de áudio é
Vorbis.
Isso é bastante simples, exceto que o formato do valor do atributo é um pouco complicado. O próprio valor
dos codecs deve incluir aspas, o que significa que você precisará usar um tipo diferente de aspas para
delimitar todo o valor do tipo : <source src="pr6.ogv" type='video/ogg;
codecs="theora, vorbis"'>

O elemento <source> para o arquivo WebM é praticamente o mesmo, mas com um tipo MIME diferente
(video/webm em vez de video/ogg) e um codec de vídeo diferente (vp8 em vez de theora) listado no
parâmetro codecs :

<source src="pr6.webm" type='video/webm; codecs="vp8, vorbis"'>

O elemento <source> do arquivo H.264 é ainda mais complicado. Lembra quando eu disse que tanto o
vídeo H.264 (consulte “H.264” na página 84) quanto o áudio AAC (consulte “Codificação de áudio avançada”
na página 87) podem vir em “perfis” diferentes? Codificamos com o perfil H.264 Baseline e o perfil AAC de
baixa complexidade e, em seguida, agrupamos tudo em um contêiner MPEG-4. Todas essas informações
estão incluídas no atributo type :

<source src="pr6.mp4" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'>

A vantagem de enfrentar todo esse problema é que o navegador será capaz de verificar primeiro o atributo
type para ver se pode reproduzir um arquivo de vídeo específico. Se um navegador decidir que não pode
reproduzir um vídeo específico, ele não fará o download do arquivo. Nem mesmo parte do arquivo. Você
economizará largura de banda e seus visitantes verão o vídeo que procuram com mais rapidez.

Se você seguir as instruções deste capítulo para codificar seus vídeos, poderá simplesmente copiar os
valores do atributo type deste exemplo. Caso contrário, você mesmo precisará definir os parâmetros de
tipo .

112 | Capítulo 5: Vídeo na Web

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Professor Markup afirma No

momento em que este artigo foi escrito (20 de maio de 2010), o iPad tinha um bug que o impedia de perceber
qualquer coisa além da primeira fonte de vídeo listada. Infelizmente, isso significa que você precisará listar
primeiro o arquivo MP4, seguido pelos formatos de vídeo gratuitos. Suspirar.

Tipos MIME levantam suas cabeças feias

Há tantas peças no quebra-cabeça do vídeo que hesito até mesmo em mencionar isso. Mas é
importante, porque um servidor web mal configurado pode levar a uma frustração sem fim enquanto
você tenta depurar por que seus vídeos são reproduzidos em seu computador local, mas não são
reproduzidos quando você os implanta em seu site de produção. Se você se deparar com esse
problema, a causa raiz provavelmente são os tipos MIME.

Mencionei os tipos MIME no Capítulo 1 (veja “Tipos MIME” na página 1), mas você provavelmente
não percebeu isso e não percebeu o significado. Então aqui está em letras maiúsculas.

Gritos de marcação do professor


ARQUIVOS DE VÍDEO DEVEM SER SERVIDOS COM O TIPO MIME ADEQUADO!

Qual é o tipo MIME adequado? Você já viu; faz parte do valor do atributo type de um elemento
<source> . Mas definir o atributo type na sua marcação HTML não é suficiente. Você também
precisa garantir que seu servidor web inclua o tipo MIME adequado no cabeçalho HTTP Content-
Type .

Se você estiver usando o servidor web Apache ou algum derivado do Apache, você pode usar
diretivas Add Type no httpd.conf de todo o site ou em um arquivo .htaccess no diretório onde você
armazena seus arquivos de vídeo. (Se você usar algum outro servidor web, consulte a documentação
do seu servidor sobre como definir o cabeçalho HTTP Content-Type para tipos de arquivo específicos.)
As diretivas AddType que você precisará incluir são:
AddType vídeo/ogg .ogv
AddType vídeo/mp4 .mp4
AddType vídeo/webm .webm

A primeira linha é para vídeos em um contêiner Ogg. A segunda linha é para vídeos em um
contêiner MPEG-4. O terceiro é para WebM. Defina-os uma vez e esqueça-os. Caso contrário, seus
vídeos não serão reproduzidos em alguns navegadores, mesmo se você incluir o tipo MIME no
atributo type em sua marcação HTML.

Para obter detalhes ainda mais sangrentos sobre como configurar seu servidor web, direciono sua
atenção para um excelente artigo do Mozilla Developer Center, “Configurando servidores para Ogg
me dia”. (O conselho desse artigo também se aplica a vídeos MP4 e WebM.)

Por fim, a marcação | 113

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

E quanto ao IE?
Enquanto escrevo isto, a Microsoft lançou uma “visualização para desenvolvedores” do Internet
Explorer 9. Ele ainda não oferece suporte ao elemento HTML5 <video> , mas a Microsoft prometeu
publicamente que a versão final do IE 9 suportará vídeo H.264 e áudio AAC em um contêiner
MPEG-4, assim como o Safari em Macs desktop e o Mobile Safari no iOS.

Mas e as versões mais antigas do Internet Explorer? Tipo, você sabe, todas as versões disponíveis
até o IE 8, inclusive? A maioria das pessoas que usa o Internet Explorer também possui o plug-in
Adobe Flash instalado. Versões modernas do Adobe Flash (começando com 9.0.60.184) suportam
vídeo H.264 e áudio AAC em um contêiner MPEG-4. Depois de codificar seu vídeo H.264 para
Safari (consulte “Codificando vídeo H.264 com freio de mão” na página 100), você poderá
reproduzi-lo em um player de vídeo baseado em Flash se detectar que seu visitante não possui um
navegador compatível com HTML5.

FlowPlayer é um reprodutor de vídeo de código aberto, licenciado pela GPL e baseado em Flash.
(Licenças comerciais também estão disponíveis; consulte http:// flowplayer.org/ download/.)
FlowPlayer não sabe nada sobre o elemento <video> . Ele não transformará magicamente uma tag
<video> em um objeto Flash. Mas o HTML5 é bem projetado para lidar com isso, porque você pode
aninhar um elemento <object> dentro de um elemento <video> . Os navegadores que não suportam
vídeo HTML5 ignorarão o elemento <video> e simplesmente renderizarão o <object> aninhado , o
que invocará o plug-in Flash e reproduzirá o filme por meio do FlowPlayer. Os navegadores que
suportam vídeo HTML5 encontrarão uma fonte de vídeo que possam reproduzir e reproduzir, e
ignorarão completamente o elemento <object> aninhado.

Essa última parte é a chave para todo o quebra-cabeça: HTML5 especifica que todos os elementos
(exceto os elementos <source> ) que são filhos de um elemento <video> devem ser ignorados
completamente. Isso permite que você use vídeo HTML5 em navegadores mais recentes e volte
ao Flash normalmente em navegadores mais antigos, sem a necessidade de hacks sofisticados de
JavaScript. Você pode ler mais sobre essa técnica no Vídeo para Todos! site.

Um exemplo completo
Vejamos um exemplo que usa essas técnicas. Estendi o vídeo para todos! código para incluir um
vídeo formatado em WebM. Usando esses comandos, codifiquei o mesmo vídeo de origem em três
formatos:

## Theora/Vorbis/Ogg
you@localhost$ ffmpeg2theora --videobitrate 200 --max_size 320x240 --output pr6.ogv
pr6.dv

## H.264/AAC/
MP4 you@localhost$ HandBrakeCLI --preset "iPhone e iPod Touch" --vb 200 --width 320
--duas passagens --turbo --optimize --input pr6.dv --output pr6.mp4

## VP8/Vorbis/
WebM you@localhost$ ffmpeg -pass 1 -passlogfile pr6.dv -threads 16 -token_partitions
4 -altref 1 -lag 16 -keyint_min 0 -g 250 -mb_static_threshold 0

114 | Capítulo 5: Vídeo na Web

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

-skip_threshold 0 -qmin 1 -qmax 51 -i pr6.dv -vcodec libvpx_vp8 -an -f


rawvideo -y NULffmpeg --videobitrate 200 you@localhost$
ffmpeg -pass 2 -passlogfile pr6.dv -threads 16 -token_partitions 4 -altref 1 -lag 16 -keyint_min 0
-g 250 -mb_static_threshold 0 -skip_threshold 0 -qmin 1 -qmax 51 -i
pr6.dv -vcodec libvpx_vp8 -b 204800 -s 320x240 -aspect 4:3 -acodec vorbis
-ac 2 -y pr6 .mkv
você@localhost$ mkclean --doctype 4 pr6.mkv pr6.webm

A marcação final usa um elemento <video> para vídeo HTML5, com um elemento <object>
aninhado para substituto do Flash:

<video id="movie" width="320" height="240" controles de pré-carregamento>


<source src="pr6.mp4" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"' /> <source
src="pr6.webm" type='video/webm; codecs="vp8, vorbis"' /> <source src="pr6.ogv"
type='video/ogg; codecs="theora, vorbis"' /> <object width="320" height="240"
type="application/x-shockwave-flash" data="flowplayer-3.2.1.swf"> <param name="
filme" value="flowplayer-3.2.1.swf" /
> <param name="allowfullscreen" value="true" /> <param
name="flashvars" value='config={ "clip": {"url" : "http://
wearehugh.com/dih5/good/bbb_480p.mp4",
"autoPlay":false, "autoBuffering":true}}' /> <p>Baixe o vídeo como <a
href="pr6.mp4" >MP4</a>, <a href="pr6.webm">WebM</
a> ou <a href="pr6.ogv">Ogg</a>.</p> </object> </ vídeo>

Com a combinação de HTML5 e Flash, você poderá assistir a este vídeo em praticamente
qualquer navegador e dispositivo.

Leitura adicional
• “O elemento <video> ” na especificação HTML5 • Vídeo
para todos! • “Uma
introdução suave à codificação de vídeo” • “Theora
1.1 foi lançado – o que você precisa saber”, por Christopher Blizzard • “Configurando
servidores para mídia Ogg” • “Codificação
com o codec x264 ” • “Parâmetros de
tipo de vídeo” • Zencoder
Vídeo JS, controles personalizados para vídeo HTML5 • “Tudo
o que você precisa saber sobre áudio e vídeo HTML5”, por Simon Pieters

Leitura adicional | 115

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

CAPÍTULO 6

Você está aqui (e todos os outros também)

Mergulhando

Geolocalização é a arte de descobrir onde você está no mundo e (opcionalmente) compartilhar essa
informação com pessoas em quem você confia. Há muitas maneiras de descobrir onde você está: seu
endereço IP, sua conexão de rede sem fio, com qual torre de celular seu telefone está se comunicando
ou hardware GPS dedicado que recebe informações de latitude e longitude de satélites no céu.

Pergunte ao professor Markup

P: A geolocalização parece assustadora. Posso desligá-lo?

R: A privacidade é uma preocupação óbvia quando se trata de compartilhar sua localização física com um
servidor web remoto. A API de geolocalização afirma explicitamente: “Os User Agents não devem enviar
informações de localização para sites sem a permissão expressa do usuário.” Em outras palavras, se você
não quiser compartilhar sua localização, não é necessário.

A API de geolocalização

A API de geolocalização permite que você compartilhe sua localização com sites confiáveis. A latitude
e a longitude estão disponíveis para JavaScript na página, que por sua vez pode enviar essas
informações de volta ao servidor web remoto e realizar tarefas sofisticadas de reconhecimento de
localização, como encontrar empresas locais ou mostrar sua localização em um mapa.

Como você pode ver na Tabela 6-1, a API de geolocalização é suportada em vários dos principais
navegadores em desktops e dispositivos móveis. Além disso, alguns navegadores e dispositivos mais
antigos podem ser suportados por bibliotecas wrapper, como veremos mais adiante neste capítulo.

117

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Tabela 6-1. Suporte à API de geolocalização

Ou seja Raposa de fogo Safári cromada Ópera Iphone Android

· 3,5+ 5,0+ 5,0+ · 3,0+ 2,0+

Juntamente com o suporte para a API de geolocalização padrão, há uma infinidade de APIs específicas de
dispositivos em outras plataformas móveis. Abordarei tudo isso mais adiante neste capítulo.

Mostre-me o código
A API de geolocalização gira em torno de uma nova propriedade no objeto navegador global :
navegador.geolocalização.
O uso mais simples da API de geolocalização é assim:

função get_location() {
navigator.geolocation.getCurrentPosition(show_map);
}

Não há detecção, tratamento de erros e opções. Seu aplicativo da web deve


provavelmente inclui pelo menos os dois primeiros. Para detectar suporte para geolocalização
API (veja “Geolocalização” na página 24), você pode usar o Modernizr:

função get_location() {
if (Modernizr.geolocation)
{navigator.geolocation.getCurrentPosition(show_map);
} outro {
// sem suporte nativo; talvez tente o Gears?
}
}

O que você faz sem suporte de geolocalização depende de você. Vou explicar o substituto do Gears
opção em um minuto, mas primeiro quero falar sobre o que acontece durante aquela ligação para
getCurrentPosition(). Como mencionei no início deste capítulo, o suporte de geolocalização
é opt-in. Isso significa que seu navegador nunca irá forçá-lo a revelar seu endereço físico atual.
local para um servidor remoto. A experiência do usuário difere de navegador para navegador. Em
Mozilla Firefox, chamar a função getCurrentPosition() da API de geolocalização irá
fazer com que o navegador exiba uma “barra de informações” na parte superior da janela do navegador. A barra de informações
se parece com a Figura 6-1.

Figura 6-1. Barra de informações de geolocalização

118 | Capítulo 6: Você está aqui (e todo mundo também)

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Há muita coisa acontecendo aqui. Como usuário final, você:

• São informados de que um site deseja saber sua localização • São informados

de qual site deseja saber sua localização • Podem clicar na página de ajuda

“Navegação com reconhecimento de localização” da Mozilla, qual ex


explica o que diabos está acontecendo • Pode

optar por compartilhar sua localização • Pode optar

por não compartilhar sua localização • Pode dizer ao seu

navegador para lembrar sua escolha (compartilhar ou não compartilhar) para que você nunca mais veja esta barra de
informações neste site

Além disso, esta barra de informações é:

• Não modal, portanto não impedirá que você mude para outra janela do navegador ou
aba

• Específico da guia, portanto ele desaparecerá se você mudar para outra janela ou guia do navegador e reaparecerá
quando você voltar para a guia original • Incondicional, então não há como um

site ignorá-lo • Bloqueio, então não há nenhuma chance que o site pode determinar sua

localização enquanto
está esperando sua resposta

Você acabou de ver o código JavaScript que faz com que esta barra de informações apareça. É uma única chamada de
função que recebe uma função de retorno de chamada (que chamei de show_map()). A chamada para getCurrent Position()
retornará imediatamente, mas isso não significa que você tenha acesso à localização do usuário. A primeira vez que você
terá informações de localização garantidas será na função de retorno de chamada. A função de retorno de chamada fica
assim:

função show_map (posição)


{ var latitude = posição.coords.latitude;
var longitude = posição.coords.longitude; //
vamos mostrar um mapa ou fazer algo
interessante! }

A função callback será chamada com um único parâmetro, um objeto com duas propriedades: coordenadas e carimbo de
data/hora. O carimbo de data/hora é apenas isso, a data e hora em que o local foi calculado. (Como tudo isso está
acontecendo de forma assíncrona, você não pode realmente saber quando isso acontecerá com antecedência. Pode levar
algum tempo para o usuário ler a barra de informações e concordar em compartilhar sua localização, dispositivos com
hardware GPS dedicado podem levar mais algum tempo para conectar-se a um satélite GPS e assim por diante.) O objeto
coords possui propriedades como latitude e longitude que representam exatamente o que parecem: a localização física do
usuário no mundo. As propriedades do objeto posição estão listadas na Tabela 6-2.

Mostre-me o código | 119

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Tabela 6-2. Propriedades do objeto de posição

Propriedade Tipo Notas

coordenadas.latitude dobro
Graus decimais

coordenadas.longitude dobro
Graus decimais
coordenadas.altitude
double ou null Metros acima do elipsóide de referência

coordenadas.precisão dobro Metros

coords.altitudeAccuracy medidores duplos ou nulos

coordenadas.cabeçalho duplo ou nulo Graus no sentido horário a partir do norte verdadeiro

coordenadas.velocidade duplo ou nulo Metros/segundo

carimbo de data/hora DOMTimeStamp como um objeto Date()

Apenas três das propriedades têm garantia de presença lá (coords.latitude,


coords.longitude e coords.precisão). O resto pode voltar como nulo, dependendo
nas capacidades do seu dispositivo e do servidor de posicionamento backend com o qual ele
comunica. As propriedades de direção e velocidade são calculadas com base nas informações do usuário
posição anterior, se possível.

Tratamento de erros
A geolocalização é complicada. Tantas coisas podem dar errado. Mencionei o “usuário
consentimento” já. Se o seu aplicativo da web deseja a localização do usuário, mas o usuário
não quer dar isso a você, você está ferrado. O usuário sempre ganha. Mas o que faz
isso parece no código? Parece o segundo argumento para getCurrentPosition()
function – uma função de retorno de chamada de tratamento de erros:

navegador.geolocation.getCurrentPosition(
show_map, handle_error)

Se algo der errado, sua função de retorno de chamada de erro será chamada com um
Objeto PositionError . Possui as propriedades listadas na Tabela 6-3.

Tabela 6-3. Propriedades do objeto PositionError

Propriedade Tipo Notas

código curto Um valor enumerado

mensagem DOMString Não destinado a usuários finais

A propriedade do código será uma das seguintes:

• PERMISSION_DENIED (1) se o usuário clicar no botão “Não compartilhar” ou de outra forma


nega a você acesso à localização dele.

• POSITION_UNAVAILABLE (2) se a rede estiver inoperante ou os satélites de posicionamento não puderem


ser contatado.

120 | Capítulo 6: Você está aqui (e todo mundo também)

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

• TIMEOUT (3) se a rede estiver ativa, mas demorar muito para calcular a posição do usuário.
Quanto tempo é “muito longo”? Mostrarei como definir isso na próxima seção.
• UNKNOWN_ERROR (0) se algo der errado.

Por exemplo:
function handle_error(err) { if (err.code
== 1) { // o usuário disse não!

}}

Pergunte ao Professor
Markup P: A API de geolocalização funciona na Estação Espacial Internacional, na Lua
ou em outros planetas?

R: A especificação de geolocalização afirma: “O sistema de referência de coordenadas geográficas


usado pelos atributos nesta interface é o World Geodetic System (2d) [WGS84].
Nenhum outro sistema de referência é suportado.” A Estação Espacial Internacional está orbitando
a Terra, então os astronautas na estação pode descrever sua localização por latitude, longitude e
altitude. No entanto, o Sistema Geodésico Mundial é centrado na Terra, por isso não pode ser
usado para descrever localizações na Lua ou em outros planetas.

Escolhas! Eu exijo escolhas!


Alguns dispositivos móveis populares – como os telefones iPhone e Android – suportam dois
métodos para descobrir onde você está. O primeiro método triangular sua posição com base na
sua proximidade relativa a diferentes torres de celular operadas pela sua operadora de telefonia.
Este método é rápido e não requer nenhum hardware GPS dedicado, mas apenas dá uma ideia
aproximada de onde você está. Dependendo de quantas torres de celular existem em sua área,
essa “ideia aproximada” pode ter precisão de apenas um quarteirão ou até um quilômetro em
todas as direções.

O segundo método, na verdade, usa hardware GPS dedicado em seu dispositivo para se
comunicar com satélites de posicionamento GPS dedicados que estão orbitando a Terra. O GPS
geralmente pode apontar sua localização em poucos metros. A desvantagem é que o chip GPS
dedicado do seu dispositivo consome muita energia, então telefones e outros dispositivos móveis
de uso geral geralmente desligam o chip até que seja necessário. Isso significa que haverá um
atraso na inicialização enquanto o chip inicializa sua conexão com os satélites GPS no céu. Se
você já usou o Google Maps em um iPhone ou outro smartphone, viu os dois métodos em ação.
Primeiro você vê um círculo grande que se aproxima da sua posição (encontrando a torre de
celular mais próxima), depois um círculo menor (triangulando com outras torres de celular) e, em
seguida, um único ponto com uma posição exata (fornecida por satélites GPS).

Mencionei isso porque, dependendo do seu aplicativo da web, você pode não precisar de alta
precisão. Por exemplo, se você estiver procurando listas de filmes próximos, um valor “baixo

Escolhas! Eu exijo escolhas! | 121

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

precisão” provavelmente é boa o suficiente. Não há muitas salas de cinema


por aí, mesmo em cidades densas, e você provavelmente listará vários deles de qualquer maneira. Sobre
por outro lado, se você estiver fornecendo instruções passo a passo em tempo real, você realmente precisa
para saber exatamente onde o usuário está para poder dizer “vire à direita em 20 metros” ou algo assim.

A função getCurrentPosition() recebe um terceiro argumento opcional, um PositionOp


objeto de ções . Existem três propriedades que você pode definir em um objeto PositionOptions (consulte
Tabela 6-4). Todas as propriedades são opcionais; você pode definir qualquer um, todos ou nenhum deles.

Tabela 6-4. Propriedades do objeto PositionOptions

Propriedade Tipo Padrão Notas

enableHighAccuracy booleano falso verdadeiro pode ser mais lento

tempo esgotado
longo (nenhum padrão) Em milissegundos

idade máxima longo 0 Em milissegundos

A propriedade enableHighAccuracy é exatamente o que parece. Se estiver definido como verdadeiro e


o dispositivo pode suportá-lo e o usuário consente em compartilhar sua localização exata, o dispositivo
tentarei fornecê-lo. Tanto iPhones quanto telefones Android têm permissões separadas
para posicionamento de baixa e alta precisão, então é possível que chamar getCurrentPosi
tion() com enableHighAccuracy:true falhará, mas chamá-lo com enableHighAccur
acy:false terá sucesso.

A propriedade timeout especifica o número de milissegundos que seu aplicativo da web fica
disposto a esperar por uma posição. Este cronômetro não inicia a contagem regressiva até depois do
o usuário dá permissão para tentar calcular sua posição. Você não está cronometrando o usuário;
você está cronometrando a rede.

A propriedade MaximumAge permite que o dispositivo responda imediatamente com uma posição em cache. Por
exemplo, digamos que você chame getCurrentPosition() pela primeira vez, o
consentimento do usuário, e sua função de retorno de chamada de sucesso é chamada com uma posição que foi
calculado exatamente às 10h. Então suponha que exatamente um minuto depois, às 10h01
AM, você chama getCurrentPosition() novamente com uma propriedade maximaAge de 75000:

navegador.geolocation.getCurrentPosition(
sucesso_callback, erro_callback, {maximumAge: 75000});

O que você está dizendo é que não precisa necessariamente da localização atual do usuário . Você
ficaria satisfeito em saber onde ele estava há 75 segundos (75.000 milissegundos).
Nesse caso, o dispositivo sabe onde o usuário estava há 60 segundos (60.000 milissegundos),
porque calculou a localização na primeira vez que você chamou getCurrentPosition(). Desde
isso está dentro da janela especificada, o dispositivo não se preocupa em recalcular o usuário
localização atual. Ele apenas retorna exatamente as mesmas informações que retornou da primeira vez:
a mesma latitude e longitude, precisão e carimbo de data/hora (10h).

Antes de solicitar a localização do usuário, você deve pensar na precisão


você precisa e defina enableHighAccuracy adequadamente. Se você precisar encontrar o nome do usuário

122 | Capítulo 6: Você está aqui (e todo mundo também)

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

location mais de uma vez, você deve pensar em quantos anos as informações podem ter e ainda
serem úteis, e definir a idade máxima de acordo. Se você precisa encontrar a localização do usuário
continuamente, getCurrentPosition() não é para você. Você precisa atualizar para watchPosition().

A função watchPosition() tem a mesma estrutura que getCurrentPosition(). São necessárias duas
funções de retorno de chamada – uma obrigatória para sucesso e outra opcional para condições
de erro – e também pode usar um objeto PositionOptions opcional que possui todas as mesmas
propriedades que você acabou de aprender. A diferença é que sua função de retorno de chamada
será chamada sempre que a localização do usuário mudar. Não há necessidade de pesquisar
ativamente a posição. O dispositivo determinará o intervalo de pesquisa ideal e chamará sua
função de retorno de chamada sempre que determinar que a posição do usuário mudou. Você
pode usar isso para atualizar um marcador visível em um mapa, fornecer instruções sobre onde ir
em seguida ou o que quiser. Depende inteiramente de você.

A própria função watchPosition() retorna um número. Você provavelmente deveria armazenar esse
número em algum lugar. Se você quiser parar de observar as mudanças de localização do usuário,
você pode chamar o método clearWatch() e passar esse número para ele, e o dispositivo irá parar
de chamar sua função de retorno de chamada. Se você já usou as funções setInterval() e
clearInterval() em JavaScript, isso funciona da mesma maneira.

E quanto ao IE?
O Internet Explorer não oferece suporte à API de geolocalização W3C que acabei de descrever
(consulte “A API de geolocalização” na página 117). Mas não se desespere! Engrenagens é um
plug-in de navegador de código aberto do Google que funciona nas plataformas Windows, Mac,
Linux, Windows Mobile e Android. Ele fornece vários recursos para navegadores mais antigos,
incluindo uma API de geolocalização. Não é exatamente igual à API de geolocalização do W3C,
mas serve ao mesmo propósito.

Já que estamos falando de plataformas legadas, devo salientar que há uma série de APIs de
geolocalização específicas de dispositivos em plataformas de telefonia móvel. Amora, Nokia,
Palma, e OMTP BONDI todos fornecem suas próprias APIs de geolocalização. Claro, todos eles
funcionam de forma diferente do Gears, que por sua vez funciona de forma diferente da API de
geolocalização W3C. Uau!

geo.js para o resgate


geo.js é uma biblioteca JavaScript de código aberto licenciada pelo MIT que suaviza as diferenças
entre a API de geolocalização W3C, a API Gears e as diversas APIs fornecidas por plataformas
móveis. Para usá-lo, você precisará adicionar dois elementos <script> na parte inferior da sua
página. (Tecnicamente, você poderia colocá-los em qualquer lugar, mas colocar scripts em seu
<head> fará com que sua página carregue mais lentamente. Portanto, não faça isso!)

geo.js para o resgate | 123

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

O primeiro script é gears_init.js, que inicializa o Gears se estiver instalado. O segundo script é geo.js.
Você pode incluí-los em sua página usando um código como este:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Mergulhe no HTML 5</title>
</head>
<body>
...
<script src="gears_init.js"></script> <script
src="geo.js"></script> </body> </
html>

Agora você está pronto para usar qualquer API de geolocalização instalada: if
(geo_position_js.init()) {
geo_position_js.getCurrentPosition(geo_success, geo_error); }

Vamos dar um passo de cada vez. Primeiro, você precisa chamar explicitamente uma função init().
A função init() retorna true se uma API de geolocalização compatível estiver disponível:
if (geo_position_js.init()) {

Chamar a função init() na verdade não encontra a localização do usuário; apenas verifica se é possível
encontrar o local. Para realmente encontrar a localização do usuário, você precisa chamar a função
getCurrentPosition():
geo_position_js.getCurrentPosition(geo_success, geo_error);

A função getCurrentPosition() fará com que o navegador peça permissão para encontrar e compartilhar
a localização do usuário. Se a geolocalização estiver sendo fornecida pelo Gears, será exibida uma caixa
de diálogo perguntando se o usuário confia no site para usar o Gears. Se o navegador suportar
nativamente a API de geolocalização, a caixa de diálogo terá uma aparência diferente. Por exemplo, o
Firefox 3.5 exibirá uma barra de informações no topo da página perguntando se o usuário deseja
compartilhar sua localização com o seu site.

A função getCurrentPosition() aceita duas funções de retorno de chamada como argumentos. Se a


função getCurrentPosition() tiver sucesso em encontrar a localização — ou seja, se o usuário deu
permissão e a API de geolocalização realmente fez sua mágica — ela chamará a função passada como
primeiro argumento. Neste exemplo, a função de retorno de chamada de sucesso é chamada
geo_success:
geo_position_js.getCurrentPosition(geo_success, geo_error);

A função de retorno de chamada de sucesso recebe um único argumento, que contém as informações
de posição:

função geo_sucesso(p) { "


alert("Encontrei você em
" latitude + p.coords.latitude + ",
longitude + p.coords.longitude);
}

124 | Capítulo 6: Você está aqui (e todo mundo também)

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Se a função getCurrentPosition() não conseguir encontrar a localização do usuário — seja porque ele
se recusou a dar permissão ou porque a API de geolocalização falhou por algum motivo — ela chamará
a função passada como segundo argumento. Neste exemplo, a função de retorno de chamada de
falha é chamada geo_error:
geo_position_js.getCurrentPosition(geo_success, geo_error);

A função de retorno de falha não aceita argumentos:


function geo_error()
{ alert("Não foi possível encontrar
você!"); }

geo.js atualmente não suporta a função watchPosition() . Se precisar de informações de localização


contínuas, você mesmo precisará pesquisar ativamente getCurrentPosition() .

Um exemplo completo
Vamos trabalhar com um exemplo de uso de geo.js para tentar obter a localização do usuário e exibir
um mapa do entorno imediato.

Quando a página carregar, será necessário chamar geo_position_js.init() para determinar se a


geolocalização está disponível por meio de qualquer uma das interfaces suportadas por geo.js. Nesse
caso, você pode configurar um link no qual o usuário pode clicar para procurar sua localização. Clicar
nesse link chama a função lookup_location() ,
mostrada aqui: function lookup_location() {
geo_position_js.getCurrentPosition(show_map, show_map_error); }

Se o usuário der consentimento para rastrear sua localização e o serviço de back-end for realmente
capaz de determinar essa localização, geo.js chamará a primeira função de retorno de chamada,
show_map(), com um único argumento, loc. O objeto loc possui uma propriedade coords que contém
informações de latitude, longitude e precisão. (Este exemplo não usa informações de precisão.) O
restante da função show_map() usa a API do Google Maps para configurar um mapa incorporado:

função show_map(loc) { $
("#geo-wrapper").css({'largura':'320px','altura':'350px'}); var mapa = new
GMap2(document.getElementById("geo-wrapper")); var centro = novo
GLatLng(loc.coords.latitude, loc.coords.longitude); map.setCenter(centro, 14);
map.addControl(novo
GSmallMapControl()); map.addControl(novo
GMapTypeControl()); map.addOverlay(new
GMarker(center, {draggable: false, title: "Você está aqui (mais ou
menos)"}));
}

Se geo.js não conseguir determinar a localização, ele chama a segunda função de retorno de chamada,
show_map_error():

Um exemplo completo | 125

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

função show_map_error() {
$("#live-geolocation").html('Não foi possível determinar sua localização.'); }

Leitura adicional
• API de geolocalização W3C •
Engrenagens

• API de geolocalização do BlackBerry •

API de geolocalização da Nokia •

API de geolocalização Palm •

API de geolocalização OMTP BONDI • geo.js,

o script wrapper da API de geolocalização

126 | Capítulo 6: Você está aqui (e todo mundo também)

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

CAPÍTULO 7

O passado, o presente e o futuro do local

Armazenamento para aplicativos da Web

Mergulhando

O armazenamento local persistente é uma das áreas onde os aplicativos clientes nativos têm
tradicionalmente mantido uma vantagem sobre os aplicativos web. Para aplicativos nativos, o sistema
operacional normalmente fornece uma camada de abstração para armazenar e recuperar dados específicos
do aplicativo, como preferências ou estado de tempo de execução. Esses valores podem ser armazenados
no registro, em arquivos INI, em arquivos XML ou em algum outro local, conforme convenção da plataforma.
Se seu aplicativo cliente nativo precisar de armazenamento local além dos pares chave/valor, você poderá
incorporar seu próprio banco de dados, inventar seu próprio formato de arquivo ou implementar inúmeras
outras soluções.

Historicamente, os aplicativos da Web não tiveram nenhum desses luxos. Os cookies foram inventados no
início da história da Web e, na verdade, podem ser usados para armazenamento local persistente de
pequenas quantidades de dados. Mas eles têm várias desvantagens potencialmente prejudiciais:

• Os cookies são incluídos em todas as solicitações HTTP, tornando assim a sua aplicação web mais
lenta ao transmitir desnecessariamente os mesmos dados repetidas vezes.

• Os cookies são incluídos em todas as solicitações HTTP, enviando assim dados não criptografados pela
Internet (a menos que todo o seu aplicativo da Web seja servido por SSL). • Os cookies

são limitados a cerca de 4 KB de dados, o suficiente para tornar seu aplicativo mais lento
(veja acima), mas não o suficiente para ser terrivelmente útil.

O que realmente queremos é:

• Muito espaço de
• armazenamento... no cliente...

• que persiste além da atualização da página... •


e não é transmitido ao servidor.

127

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Houve uma série de tentativas para conseguir isso, todas insatisfatórias de diferentes maneiras.

Uma breve história de hacks de armazenamento local antes do HTML5

No início existia apenas o Internet Explorer. Ou pelo menos era isso que a Microsoft queria que o mundo
pensasse. Para esse fim, durante a primeira das Grandes Guerras dos Navegadores, A Microsoft
inventou muitas coisas e as incluiu em sua guerra de navegadores, o Internet Explorer. Uma dessas
coisas foi chamada de Comportamentos DHTML, e um desses comportamentos foi chamado userData.

userData permite que páginas da web armazenem até 64 KB de dados por domínio, em uma estrutura
hierárquica baseada em XML. (Domínios confiáveis, como sites de intranet, podem armazenar 10 vezes
essa quantidade. E, ei, 640 KB devem ser suficientes para qualquer pessoa!) O IE não apresenta
nenhuma forma de caixa de diálogo de permissões e não há permissão para aumentar a quantidade de
armazenamento disponível.

Em 2002, a Adobe introduziu um recurso no Flash 6 que ganhou o infeliz e equivocado nome de
“cookies Flash”. No ambiente Flash, o recurso é conhecido como Local Shared Objects, ou LSOs.
Resumidamente, permite que objetos Flash armazenem até 100 KB de dados por domínio. Em 2005,
Brad Neuberg desenvolveu um protótipo inicial de uma ponte Flash para JavaScript chamada AJAX
Massive Storage System, ou AMASS, mas foi limitado por algumas peculiaridades de design do Flash.
Em 2006, com o advento do ExternalInterface no Flash 8, acessar LSOs a partir de JavaScript tornou-
se muito mais fácil e rápido. Brad reescreveu o AMASS e integrou-o ao popular Dojo Toolkit sob o
apelido dojox.storage. Com esta solução, cada domínio recebe os habituais 100 KB de armazenamento
“de graça”. Além disso, ele solicita ao usuário cada aumento de ordem de magnitude no armazenamento
de dados (1 MB, 10 MB e assim por diante).

Então, em 2007, o Google lançou o Gears, um plug-in de navegador de código aberto destinado a
fornecer recursos adicionais em navegadores. (Já discutimos anteriormente o Gears no contexto do
fornecimento de uma API de geolocalização no Internet Explorer (consulte “E quanto ao IE?” na página
123). O Gears fornece uma API para um banco de dados SQL incorporado baseado em SQLite. Depois
de obter permissão do usuário uma vez, o Gears pode armazenar quantidades ilimitadas de dados por
domínio em tabelas de banco de dados SQL.

Enquanto isso, Brad Neuberg e outros continuaram a hackear o dojox.storage para fornecer uma
interface unificada para todos esses plug-ins e APIs diferentes. Em 2009, o dojox.storage poderia
detectar automaticamente (e fornecer uma interface unificada sobre) Adobe Flash, Gears, Adobe AIR e
um protótipo inicial de armazenamento HTML5 que só foi implementado em versões mais antigas do
Firefox.

À medida que você examina essas soluções, surge um padrão: todas elas são específicas de um único
navegador ou dependem de um plug-in de terceiros. Apesar dos esforços heróicos para encobrir as
diferenças (no dojox.storage), todos eles expõem interfaces radicalmente diferentes, têm limitações de
armazenamento diferentes e apresentam experiências de usuário diferentes. Então este é o

128 | Capítulo 7: O passado, o presente e o futuro do armazenamento local para aplicativos da Web

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

problema que o HTML5 se propôs a resolver: fornecer uma API padronizada, implementada
de forma nativa e consistente em vários navegadores, sem precisar depender de terceiros
plug-ins.

Apresentando o armazenamento HTML5

O que chamo de “Armazenamento HTML5” é na verdade uma especificação chamada Web Storage.
Isso já fez parte da especificação HTML5 propriamente dita, mas foi dividido em seu
próprias especificações por razões políticas desinteressantes. Certos fornecedores de navegadores também se referem
a ele como “Armazenamento local” ou “Armazenamento DOM”. A situação de nomenclatura torna-se ainda mais
complicado por alguns padrões emergentes relacionados e com nomes semelhantes que discutirei mais tarde
neste capítulo.

Então, o que é armazenamento HTML5? Simplificando, é uma forma de as páginas da web armazenarem chaves nomeadas/
pares de valores localmente, no navegador da web do cliente. Tal como os dados armazenados em cookies, este
os dados persistem mesmo depois que você sai do site, fecha a guia do navegador,
saia do seu navegador ou o que quer que seja. Mas, diferentemente dos cookies, esses dados nunca são transmitidos
para o servidor web remoto (a menos que você faça o possível para enviá-los manualmente).
E ao contrário de todas as tentativas anteriores de fornecer armazenamento local persistente (descritas no
seção anterior), ele é implementado nativamente em navegadores web, portanto está disponível mesmo
quando plug-ins de navegador de terceiros não o são.

Quais navegadores? Como mostra a Tabela 7-1 , o HTML5 é suportado pelas versões mais recentes do
praticamente todos os navegadores...até mesmo o Internet Explorer!

Tabela 7-1. Suporte para armazenamento HTML5

Ou seja Raposa de fogo Safári cromada Ópera Iphone Android

8,0+ 3,5+ 4,0+ 4,0+ 10,5+ 2,0+ 2,0+

A partir do seu código JavaScript, você acessará o armazenamento HTML5 por meio do localStorage
objeto no objeto de janela global . Antes de poder usá-lo, você deve detectar se
o navegador suporta (consulte “Armazenamento local” na página 21):

função support_html5_storage() {
return ('localStorage' na janela) && window['localStorage'] !== null;
}

Ou, em vez de escrever esta função você mesmo, você pode usar o Modernizr (veja “Modernizr:
Uma biblioteca de detecção HTML5” na página 16) para detectar suporte para armazenamento HTML5:

if (Modernizr.localstorage) {
// window.localStorage está disponível!
} outro {
// sem suporte nativo para armazenamento HTML5 :(
// talvez tente dojox.storage ou uma solução de terceiros
}

Apresentando o armazenamento HTML5 | 129

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Usando armazenamento HTML5

O armazenamento HTML5 é baseado em pares chave/valor nomeados. Você armazena dados com
base em uma chave nomeada e pode recuperá-los com a mesma chave:
interface Storage { getter
qualquer getItem (na chave DOMString); criador do
setter void setItem (na chave DOMString, em qualquer dado); };

A chave nomeada é uma string. Os dados podem ser de qualquer tipo suportado por JavaScript,
incluindo strings, booleanos, inteiros ou flutuantes. No entanto, os dados são armazenados como uma
string. Se você estiver armazenando e recuperando algo diferente de strings, precisará usar funções
como parseInt() ou parseFloat() para forçar seus dados recuperados no tipo de dados Java Script
esperado.

Chamar setItem() com uma chave nomeada que já existe substituirá silenciosamente o valor anterior.
Chamar getItem() com uma chave inexistente retornará nulo em vez de lançar uma exceção.

Como outros objetos JavaScript, você pode tratar o objeto localStorage como um array associativo. Em vez de usar os métodos
getItem() e setItem() , você pode simplesmente usar colchetes. Por exemplo, este trecho de código: var foo =
localStorage.getItem("bar"); // ... localStorage.setItem("bar",

foo);

poderia ser reescrito para usar a sintaxe de colchetes:


var foo = localStorage["barra"]; // ...

localStorage["bar"] = foo;

Existem também métodos para remover o valor de uma determinada chave nomeada e limpar toda a
área de armazenamento (ou seja, excluir todas as chaves e valores de uma vez):
interface Armazenamento {
deleter void removeItem (na chave DOMString); vazio
claro(); };

Chamar removeItem() com uma chave inexistente não fará nada.

Finalmente, existe uma propriedade para obter o número total de valores na área de armazenamento
e iterar por todas as chaves por índice (para obter o nome de cada chave):
interface Storage {
atributo readonly de comprimento longo sem sinal; chave
getter DOMString (em índice longo não assinado); };

Se você chamar key() com um índice que não esteja entre 0 e (comprimento –1), a função retornará
nulo.

130 | Capítulo 7: O passado, o presente e o futuro do armazenamento local para aplicativos da Web

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Rastreando alterações na área de armazenamento HTML5

Se quiser acompanhar programaticamente quando a área de armazenamento muda, você pode


interceptar o evento de armazenamento . O evento de armazenamento é disparado no objeto window sempre que
setItem(), removeItem() ou clear() são chamados e realmente mudam alguma coisa. Por exemplo, se você definir um
item com seu valor existente ou chamar clear() quando não houver nenhum nome
chaves, o evento de armazenamento não será acionado porque nada realmente mudou no armazenamento
área.

O evento de armazenamento é suportado em todos os lugares onde o objeto localStorage é suportado,


que inclui o Internet Explorer 8. O IE 8 não suporta o padrão W3C
addEventListener (embora isso seja finalmente adicionado no IE 9). Portanto, para fisgar o
storage evento, você precisará verificar qual mecanismo de evento o navegador suporta. (Se
Se você já fez isso antes com outros eventos, pode pular para o final desta seção.
A captura do evento de armazenamento funciona da mesma maneira que a captura de qualquer outro evento. Se você
prefira usar jQuery ou alguma outra biblioteca JavaScript para registrar seus manipuladores de eventos,
você também pode fazer isso com o evento de armazenamento .) Veja como:

if (window.addEventListener) {
window.addEventListener("armazenamento", handle_storage, false);
} outro {
window.attachEvent("onstorage", handle_storage);
};

A função de retorno de chamada handle_storage() será chamada com um objeto StorageEvent , exceto no Internet
Explorer, onde o objeto de evento é armazenado em window.event:

função handle_storage(e) {
if (!e) { e = janela.event; }
}

Neste ponto, a variável e será um objeto StorageEvent , que possui as propriedades úteis listadas na Tabela 7-2.

Tabela 7-2. Propriedades do objeto StorageEvent

Propriedade Tipo Descrição

Corda A chave nomeada que foi adicionada, removida ou modificada

chave oldValue Qualquer O valor anterior (agora substituído) ou nulo se um novo item foi adicionado

novoValor Qualquer O novo valor ou nulo se um item foi removido

gritar Corda A página que chamou o método que acionou essa alteração
a
A propriedade url foi originalmente chamada de uri. Alguns navegadores foram fornecidos com essa propriedade antes da alteração da especificação. Para máximo

compatibilidade, você deve verificar se a propriedade url existe e, caso contrário, verifique a propriedade uri .

O evento de armazenamento não é cancelável. De dentro da função de retorno de chamada handle_storage() , não
há como impedir que a mudança ocorra. É simplesmente uma forma do navegador
para lhe dizer: “Ei, isso acabou de acontecer. Não há nada que você possa fazer sobre isso agora; Eu acabei de
queria que você soubesse.

Usando armazenamento HTML5 | 131

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Limitações nos navegadores atuais


Ao falar sobre a história dos hacks de armazenamento local usando plug-ins de terceiros (veja “Uma breve história
dos hacks de armazenamento local antes do HTML5” na página 128), fiz questão de mencionar as limitações de cada
técnica, como limites de armazenamento . No entanto, não mencionei nada sobre as limitações do agora padronizado
armazenamento HTML5.

Por padrão, cada origem obtém 5 MB de espaço de armazenamento. Isso é surpreendentemente consistente em
todos os navegadores, embora seja formulado como nada mais do que uma sugestão na especificação de
armazenamento HTML5. Uma coisa a ter em mente é que você está armazenando strings, e não dados em seu
formato original. Se você estiver armazenando muitos inteiros ou números flutuantes, a diferença na representação
pode realmente aumentar: cada dígito nesse número flutuante está sendo armazenado como um caractere, não na
representação usual de um número de ponto flutuante.

Se você exceder sua cota de armazenamento, uma exceção QUOTA_EXCEEDED_ERR será lançada. “Não” é a
resposta à próxima pergunta óbvia: “Posso pedir ao usuário mais espaço de armazenamento?”
No momento em que este artigo foi escrito, nenhum navegador suportava qualquer mecanismo para que os
desenvolvedores da Web solicitassem mais espaço de armazenamento. Alguns navegadores, como o Opera,
permitem que o usuário controle a cota de armazenamento de cada site, mas é puramente uma ação iniciada pelo
usuário, e não algo que você, como desenvolvedor web, possa incorporar em seu aplicativo web.

Armazenamento HTML5 em ação

Vejamos um exemplo de armazenamento HTML5 em ação. Pense no jogo Halma que construímos no Capítulo 4
(veja “Um exemplo completo” na página 75). Há um pequeno problema com o jogo: se você fechar a janela do
navegador no meio do jogo, perderá seu progresso. Mas com o armazenamento HTML5, podemos salvar o progresso
localmente, dentro do próprio navegador. Você pode ver uma demonstração ao vivo em http:// diveintohtml5.org/
examples/ localstor age-halma.html. Faça alguns movimentos, feche a guia do navegador e reabra-a. Se o seu
navegador suportar armazenamento HTML5, a página de demonstração deverá lembrar magicamente sua posição
exata no jogo, incluindo o número de movimentos que você fez, as posições de cada uma das peças no tabuleiro e
até mesmo se uma peça específica está selecionada .

Como funciona? Cada vez que ocorre uma mudança no jogo, chamamos esta função:

function saveGameState()
{ if (!supportsLocalStorage()) { return false; }
localStorage["halma.game.in.progress"] = gGameInProgress;
for (var i = 0; i < kNumPieces; i++) {
localStorage["halma.piece." + i + ".row"] = gPieces[i].row;
localStorage["halma.piece." + i + ".coluna"] = gPieces[i].coluna; }

localStorage["halma.selectedpiece"] = gSelectedPieceIndex;
localStorage["halma.selectedpiecehasmoved"] gSelectedPieceHasMoved;
localStorage["halma.movecount"] = gMoveCount;
retornar verdadeiro;
}

132 | Capítulo 7: O passado, o presente e o futuro do armazenamento local para aplicativos da Web

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Como você pode ver, ele usa o objeto localStorage para salvar se há um jogo em andamento
(gGameInProgress, um booleano). Nesse caso, ele itera pelas peças (gPieces, um array JavaScript ) e
salva o número da linha e da coluna de cada peça. Em seguida, ele salva algum estado adicional do
jogo, incluindo qual peça está selecionada (gSelectedPieceIndex, um número inteiro), se a peça está no
meio de uma série potencialmente longa de saltos (gSelectedPieceHasMoved, um booleano) e o número
total de movimentos feitos até agora (gMoveCount, um número inteiro).

No carregamento da página, em vez de chamar automaticamente uma função newGame() que redefiniria
essas variáveis para valores codificados, chamamos uma função resumeGame() . Usando o
armazenamento HTML5, a função resumeGame() verifica se algum estado sobre um jogo em andamento
está armazenado localmente. Nesse caso, ele restaura esses valores usando o objeto localStorage :
function resumeGame()
{ if (!supportsLocalStorage()) { return false; }
gGameInProgress = (localStorage["halma.game.in.progress"] == "true"); if (!
gGameInProgress) { retornar falso; }
gPieces = new Array(kNumPieces);
for (var i = 0; i < kNumPieces; i++) { var
row = parseInt(localStorage["halma.piece." + i + ".row"]); var coluna
= parseInt(localStorage["halma.piece." + i + ".column"]); gPieces[i] = new
Cell(linha, coluna); } gNumPieces =

kNumPieces;
gSelectedPieceIndex = parseInt(localStorage["halma.selectedpiece"]);
gSelectedPieceHasMoved = localStorage["halma.selectedpiecehasmoved"] == "true";
gMoveCount = parseInt(localStorage["halma.movecount"]);
drawBoard();
retornar verdadeiro;
}

A parte mais importante desta função é a advertência que mencionei anteriormente neste capítulo, que
repetirei aqui: Os dados são armazenados como strings. Se você estiver armazenando algo diferente de
uma string, você mesmo precisará coagi-lo ao recuperá-lo. Por exemplo, o sinalizador para saber se há
um jogo em andamento (gGameInProgress) é um booleano. Na função saveGameState() , apenas
armazenamos e não nos preocupamos com o tipo de dados:

localStorage["halma.game.in.progress"] = gGameInProgress;

Mas na função resumeGame() , precisamos tratar o valor que obtivemos da área de armazenamento
local como uma string e construir manualmente o valor booleano adequado:

gGameInProgress = (localStorage["halma.game.in.progress"] == "true");

Da mesma forma, o número de movimentos é armazenado em gMoveCount como um número inteiro.


Na função saveGameState() , apenas armazenamos:

localStorage["halma.movecount"] = gMoveCount;

Mas na função resumeGame() , precisamos forçar o valor para um número inteiro, usando a função
parseInt() incorporada ao JavaScript: gMoveCount
= parseInt(localStorage["halma.movecount"]);

Armazenamento HTML5 em ação | 133

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Além dos pares chave/valor nomeados: visões concorrentes

Embora o passado esteja repleto de hacks e soluções alternativas (veja “Uma Breve História do Local
Hacks de armazenamento antes do HTML5” na página 128), a condição atual do armazenamento HTML5
é surpreendentemente róseo. Uma nova API foi padronizada e implementada em todos os principais
navegadores, plataformas e dispositivos. Como desenvolvedor web, isso não é algo que você
vejo todos os dias, não é? Mas a vida é mais do que 5 MB de pares chave/valor nomeados, e
o futuro do armazenamento local persistente é... como posso dizer? Bem, há uma série de
visões concorrentes.

Uma visão é um acrônimo que você provavelmente já conhece: SQL. Em 2007, Google
lançou o Gears, um plug-in de código aberto para vários navegadores que incluía uma base de dados incorporada baseada
em SQLite. Este protótipo inicial influenciou mais tarde a criação da Web
Especificação do banco de dados SQL. O Banco de Dados SQL da Web (anteriormente conhecido como “WebDB”) fornece
um wrapper fino em torno de um banco de dados SQL, permitindo que você faça coisas como esta a partir de
JavaScript:

openDatabase('documentos', '1.0', 'Armazenamento local de documentos', 5*1024*1024, function


(db) {
db.changeVersion('', '1.0', função (t) {
t.executeSql('CREATE TABLE docids (id, nome)');
}, erro);
});

Como você pode ver, a maior parte da ação reside na string que você passa para executeSql()
método. Esta string pode ser qualquer instrução SQL suportada, incluindo SELECT, UPDATE,
INSERIR e EXCLUIR. É como programar banco de dados back-end, exceto que você está fazendo
isso em JavaScript! Ah, alegria!

A Tabela 7-3 mostra quais navegadores implementaram o Banco de Dados Web SQL
especificação.

Tabela 7-3. Suporte a banco de dados Web SQL

Ou seja Raposa de fogo Safári cromada Ópera Iphone Android


· · 4,0+ 4,0+ 10,5+ 3,0+ ·

Claro, se você usou mais de um produto de banco de dados em sua vida, você sabe
que “SQL” é mais um termo de marketing do que um padrão rígido e rápido. (Alguns gostariam
diga o mesmo de “HTML5”, mas não importa isso.) Claro, existe um SQL real
especificação - é chamada SQL-92 - mas não há nenhum servidor de banco de dados no mundo que
está em conformidade com essa e somente essa especificação. Existe o SQL da Oracle, o SQL da Microsoft,
SQL do MySQL, SQL do PostgreSQL e SQL do SQLite. E cada um desses produtos acrescenta
novos recursos SQL ao longo do tempo, portanto, mesmo dizer “SQL do SQLite” não é suficiente para fixar
exatamente o que você está falando - você precisa dizer “a versão do SQL que
enviado com SQLite versão XYZ”

134 | Capítulo 7: O passado, o presente e o futuro do armazenamento local para aplicativos da Web

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Tudo isso nos leva à seguinte isenção de responsabilidade, atualmente presente no topo da lista
Especificação do banco de dados SQL da Web:

Esta especificação chegou a um impasse: todos os implementadores interessados usaram o mesmo


backend SQL (Sqlite), mas precisamos de múltiplas implementações independentes para prosseguir
ao longo de um caminho de padronização. Até que outro implementador esteja interessado em
implementar esta especificação, a descrição do dialeto SQL será deixada simplesmente como uma
referência ao Sqlite, o que não é aceitável para um padrão.

É nesse contexto que apresentarei outra visão concorrente para armazenamento local avançado e persistente para aplicações
web: a API de banco de dados indexado, anteriormente conhecido como “WebSimpleDB”, agora carinhosamente conhecido
como “IndexedDB”.

A API do banco de dados indexado expõe o que é chamado de armazenamento de objetos. Um armazenamento de objetos
compartilha muitos conceitos com um banco de dados SQL. Existem “bancos de dados” com “registros” e cada registro possui
um número definido de “campos”. Cada campo possui um tipo de dados específico, que é definido quando o banco de dados é
criado. Você pode selecionar um subconjunto de registros e enumerá-los com um “cursor”. As alterações no armazenamento

de objetos são tratadas em “transações”.

Se você já programou algum banco de dados SQL, esses termos provavelmente lhe parecem familiares.
A principal diferença é que o armazenamento de objetos não possui linguagem de consulta estruturada. Você não constrói uma
instrução como "SELECT * from USERS where ACTIVE = 'Y'". Em vez disso, você usa métodos fornecidos pelo armazenamento

de objetos para abrir um cursor no banco de dados chamado USERS, enumerar os registros, filtrar registros de usuários
inativos e usar métodos de acesso para obter os valores de cada campo nos registros restantes. O primeiro passo a passo do
IndexedDB é um bom tutorial sobre como o IndexedDB funciona, fornecendo comparações lado a lado do IndexedDB e do
banco de dados SQL da Web.

No momento em que este artigo foi escrito, o IndexedDB não foi implementado em nenhum navegador importante. No início de
junho de 2010, a Mozilla disse que “teria algumas compilações de teste nas próximas semanas”, mas ainda não há informações
se ele será lançado no Firefox 4. (Por outro lado, a Mozilla declarou que nunca implementará o banco de dados SQL da Web.)
O Google declarou que está considerando o suporte ao IndexedDB, e até a Microsoft disse que o IndexedDB “é uma ótima
solução para a Web”.

Então, o que você, como desenvolvedor web, pode fazer com o IndexedDB? No momento, absolutamente nada. Daqui a um
ano? Talvez alguma coisa. Verifique a seção “Leitura adicional” para obter links para alguns bons tutoriais para você começar.

Leitura adicional
Armazenamento HTML5:

• Especificação de armazenamento HTML5 •

“Introdução ao armazenamento DOM” no MSDN • “Armazenamento

Web: armazenamento de dados do lado do cliente mais fácil e poderoso”, por Shwetank Dixit

Leitura adicional | 135

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

• “Introdução ao armazenamento DOM” no Mozilla Developer Center. (Nota: a maior parte desta página
é dedicada ao protótipo de implementação do objeto globalStorage no Firefox, um precursor não
padrão do localStorage. A Mozilla adicionou suporte para a interface localStorage padrão no Firefox
3.5.)

• “Desbloqueie o armazenamento local para aplicativos Web móveis com HTML 5”, um tutorial sobre
IBM DeveloperWorks

Os primeiros trabalhos de Brad Neuberg et al. (pré-HTML5):

• “Internet Explorer tem suporte nativo para persistência?!?!”, sobre os dados do usuário
objeto no IE
• Armazenamento Dojo, parte de um tutorial maior sobre a (agora extinta) biblioteca Dojo Offline •
referência da API dojox.storage.manager •

repositório Subversion dojox.storage

Banco de dados SQL da Web:

• Especificação do banco de dados Web


SQL • “Introduzindo bancos de dados Web SQL”, por Remy Sharp
• Demonstração de banco de dados da Web

• persistência.js, um “ORM JavaScript assíncrono” construído sobre base de dados Web SQL e Gears

Banco de dados indexado:

• Especificação da API de banco de dados


indexado • “Além do HTML5: APIs de banco de dados e o caminho para IndexedDB”, por Arun Ranga
Nathan e Shawn Wilsher

• “Firefox 4: um passo a passo inicial do IndexedDB”, por Arun Ranganathan

136 | Capítulo 7: O passado, o presente e o futuro do armazenamento local para aplicativos da Web

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

CAPÍTULO 8

Vamos colocar isso off-line

Mergulhando

O que é um aplicativo da web offline? À primeira vista, parece uma contradição


termos. Páginas da Web são coisas que você baixa e renderiza. Baixar implica uma rede
conexão. Como você pode fazer download quando está offline? Claro, você não pode. Mas você
pode baixar quando você estiver on-line. E é assim que funcionam os aplicativos offline HTML5.

Na sua forma mais simples, uma aplicação web offline é apenas uma lista de URLs apontando para HTML, CSS,
ou arquivos JavaScript, imagens ou quaisquer outros tipos de recursos que possam estar presentes. O
página inicial do aplicativo da web off-line aponta para esta lista, chamada de arquivo de manifesto, que
é apenas um arquivo de texto localizado em outro lugar no servidor web. Um navegador web que implementa
Os aplicativos offline HTML5 lerão a lista de URLs do arquivo de manifesto, farão o download
os recursos, armazená-los em cache localmente e manter automaticamente as cópias locais atualizadas
à medida que eles mudam. Quando você tenta acessar o aplicativo da web sem uma conexão de rede, seu
navegador da web mudará automaticamente para as cópias locais.

A partir daí, a maior parte do trabalho depende de você, como desenvolvedor web. Há uma bandeira no
DOM que lhe dirá se você está online ou offline, e há eventos que disparam
quando seu status muda (um minuto você está off-line e no minuto seguinte você está on-line,
ou vice-versa). Mas é basicamente isso. Se seu aplicativo criar dados ou salvar estado,
cabe a você armazenar esses dados localmente (veja o Capítulo 7) enquanto estiver offline e sincronizá-los
com o servidor remoto quando estiver online novamente. Em outras palavras, HTML5
pode colocar seu aplicativo da web off-line, mas o que você fará quando estiver lá depende de você.
A Tabela 8-1 mostra quais navegadores suportam aplicações web offline.

Tabela 8-1. Suporte off-line

Ou seja Raposa de fogo Safári cromada Ópera Iphone Android


· ÿ ÿ ÿ · ÿ ÿ

137

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

O Manifesto de Cache

Um aplicativo da web offline gira em torno de um arquivo de manifesto de cache. Como já mencionei, o arquivo de
manifesto é uma lista de todos os recursos que seu aplicativo Web pode precisar acessar enquanto estiver
desconectado da rede. Para iniciar o processo de download e armazenamento em cache desses recursos, você
precisa apontar para o arquivo manifesto, usando o atributo manifest no seu elemento <html>:

<!DOCTYPE
HTML> <html manifest="/
cache.manifest"> <body>
...
</body>
</html>

Seu arquivo de manifesto de cache pode estar localizado em qualquer lugar do seu servidor web, mas deve ser
servido com o tipo de conteúdo text/cache-manifest. Se você estiver executando um servidor web baseado em
Apache, provavelmente poderá simplesmente colocar uma diretiva AddType no arquivo .htaccess na raiz do seu
diretório web:

AddType text/cache-manifest .manifest

Em seguida, certifique-se de que o nome do arquivo de manifesto do cache termine com .manifest. Se você usar um
servidor web diferente ou uma configuração diferente do Apache, consulte a documentação do seu servidor sobre
como controlar o cabeçalho Content-Type.

Pergunte ao Professor Markup

P: Minha aplicação web abrange diversas páginas. Preciso de um atributo de manifesto em cada página ou
posso simplesmente colocá-lo na página inicial?

R: Cada página do seu aplicativo da web precisa de um atributo de manifesto que aponte para o manifesto
de cache de todo o aplicativo.

OK, então cada uma de suas páginas HTML aponta para o arquivo de manifesto de cache, e seu arquivo de manifesto
de cache está sendo servido com o cabeçalho Content-Type adequado. Mas o que está no arquivo de manifesto? É
onde as coisas começam a ficar interessantes.

A primeira linha de cada arquivo de manifesto de cache é esta:


MANIFESTO DE CACHE

Depois disso, todos os arquivos de manifesto são divididos em três partes: a seção “explícita”, a seção “substituta” e
a seção “lista de permissões online”. Cada seção possui um cabeçalho, em sua própria linha. Se o arquivo de
manifesto não tiver nenhum cabeçalho de seção, todos os recursos listados estarão implicitamente na seção
“explícita”. Tente não se preocupar com a terminologia, para que sua cabeça não exploda.

138 | Capítulo 8: Vamos colocar isso off-line

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Aqui está um arquivo de manifesto válido. Ele lista três recursos – um arquivo CSS, um arquivo JavaScript e
uma imagem JPEG:
MANIFESTO DE
CACHE /
clock.css /
clock.js /clock-face.jpg

Este arquivo de manifesto de cache não possui cabeçalhos de seção, portanto, todos os recursos listados estão
na seção “explícita” por padrão. Os recursos na seção “explícita” serão baixados e armazenados em cache
localmente e serão usados no lugar de suas contrapartes online sempre que você estiver desconectado da rede.
Assim, ao carregar este arquivo de manifesto de cache, seu navegador baixará clock.css, clock.js e clock-
face.jpg do diretório raiz do seu servidor web. Você pode então desconectar o cabo de rede e atualizar a página,
e todos esses recursos estarão disponíveis offline.

Pergunte ao Professor Markup


P: Preciso listar minhas páginas HTML em meu manifesto de cache?

R: Sim e não. Se todo o seu aplicativo da web estiver contido em uma única página, certifique-se de que
a página aponte para o manifesto do cache usando o atributo manifest. Quando você navega para uma
página HTML com um atributo de manifesto, presume-se que a própria página faça parte do aplicativo
Web, portanto, não é necessário listá-la no próprio arquivo de manifesto. Entretanto, se seu aplicativo
Web abranger diversas páginas, você deverá listar todas as páginas HTML no arquivo de manifesto;
caso contrário, o navegador não saberá que existem outras páginas HTML que precisam ser baixadas e
armazenadas em cache.

Seções de rede

Aqui está um exemplo um pouco mais complicado. Suponha que você queira que seu aplicativo de relógio
rastreie visitantes, usando um script tracking.cgi que é carregado dinamicamente a partir de um atributo <img
src>. Armazenar esse recurso em cache anularia o propósito de rastreamento, portanto, esse recurso nunca
deve ser armazenado em cache e nunca estar disponível off-line. Aqui está como você faz isso:
MANIFESTO DE CACHE
REDE:
/tracking.cgi

CACHE: /
clock.css /
clock.js /clock-face.jpg

Este arquivo de manifesto de cache inclui cabeçalhos de seção. A linha marcada NETWORK: é o início da

seção “lista branca online”. Os recursos nesta seção nunca são armazenados em cache e não estão disponíveis
offline. (Tentar carregá-los off-line resultará em erro.)
A linha marcada CACHE: é o início da seção “explícita”. O restante do arquivo de manifesto do cache é igual ao
exemplo anterior. Cada um dos três recursos listados será armazenado em cache e estará disponível offline.

O Manifesto de Cache | 139

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Seções substitutas

Há mais um tipo de seção em um arquivo de manifesto de cache: uma seção substituta. Em uma seção de
fallback, você pode definir substituições para recursos online que, por qualquer motivo, não podem ser
armazenados em cache ou não foram armazenados em cache com êxito. A especificação HTML5 oferece
este exemplo inteligente de uso de uma seção substituta:
CACHE
MANIFEST
FALLBACK: //
offline.html REDE:
*

O que isso faz? Primeiro, considere um site que contém milhões de páginas, como o Wikipédia. Você não
poderia baixar o site inteiro, nem gostaria de fazer isso. Mas suponha que você pudesse disponibilizar
parte dele off-line. Como você decidiria quais páginas armazenar em cache? Que tal isto: cada página que
você já viu em uma hipotética Wikipédia off-line seria baixada e armazenada em cache. Isso incluiria cada
entrada da enciclopédia que você já visitou, cada página de discussão (onde você pode ter discussões
improvisadas sobre uma entrada específica da enciclopédia) e cada página de edição (onde você pode
realmente fazer alterações naquela entrada específica).

É isso que este manifesto de cache faz. Suponha que todas as páginas HTML da Wikipedia (entrada,
página de discussão, página de edição, página de histórico) apontassem para este arquivo de manifesto
de cache. Quando você visita qualquer página que aponta para um manifesto de cache, seu navegador diz:
“Ei, esta página faz parte de um aplicativo da web offline, eu conheço algum?” Se o seu navegador nunca
tiver baixado esse arquivo de manifesto de cache específico, ele configurará um novo “appcache” offline
(abreviação de “cache de aplicativo”), baixará todos os recursos listados no manifesto de cache e, em
seguida, adicionará a página atual para o appcache. Se o seu navegador souber sobre esse manifesto de
cache, ele simplesmente adicionará a página atual ao appcache existente. De qualquer forma, a página
que você acabou de visitar acaba no appcache. Isso é importante. Isso significa que você pode ter um
aplicativo da web offline que adiciona páginas “preguiçosamente” conforme você as visita. Você não precisa
listar cada uma de suas páginas HTML no manifesto de cache.
Agora olhe para a seção alternativa. A seção de fallback neste manifesto de cache contém apenas uma
linha. A primeira parte da linha (antes do espaço) não é uma URL. É realmente um padrão de URL. O
caractere único (/) corresponderá a qualquer página do seu site, não apenas à página inicial. Quando você
tenta visitar uma página enquanto está offline, seu navegador irá procurá-la no appcache. Se o seu
navegador encontrar a página no appcache (porque você a visitou enquanto estava online e a página foi
adicionada implicitamente ao appcache naquele momento), ele exibirá a cópia em cache da página. Se o
seu navegador não encontrar a página no appc ache, em vez de exibir uma mensagem de erro, ele exibirá
a página /offline.html, conforme especificado na segunda metade da linha na seção de fallback.

Finalmente, vamos examinar a seção de rede. A seção de rede neste manifesto de cache também possui
apenas uma linha, que contém apenas um caractere (*). Este caractere tem um significado especial em
uma seção de rede. É chamado de “sinalizador curinga da lista de permissões online”.
Essa é uma maneira elegante de dizer que qualquer coisa que não esteja no appcache ainda pode ser

140 | Capítulo 8: Vamos colocar isso off-line

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

baixado do endereço da web original, desde que você tenha uma conexão com a Internet.
Isso é importante para um aplicativo da web off-line “aberto”. Continuando com nosso exemplo, isso significa que
enquanto você navega nesta hipotética Wikipédia on-line habilitada para off-line, seu navegador buscará
imagens, vídeos e outros recursos incorporados normalmente, mesmo que estejam em um domínio diferente.
(Isso é muito comum em sites grandes, mesmo que não façam parte de um aplicativo da Web off-line: as páginas
HTML são geradas e veiculadas localmente, enquanto as imagens e os vídeos são veiculados a partir de um
CDN em outro domínio.)
Sem esse sinalizador curinga, nossa hipotética Wikipedia habilitada para off-line se comportaria de maneira
estranha quando você estivesse on-line - especificamente, ela não carregaria nenhuma imagem ou vídeo
hospedado externamente!

Este exemplo está completo? Não. A Wikipédia é mais do que apenas arquivos HTML; ele usa CSS, JavaScript
e imagens comuns em cada página. Cada um desses recursos precisaria ser listado explicitamente na seção
CACHE: do arquivo de manifesto para que as páginas fossem exibidas e se comportassem adequadamente off-
line. Mas o objetivo da seção alternativa é que você pode ter um aplicativo da Web off-line “aberto” que se estende
além dos recursos listados explicitamente no arquivo de manifesto.

O Fluxo de Eventos

Até agora, falei sobre aplicativos web off-line, o manifesto de cache e o cache de aplicativos off-line (“appcache”)
em termos vagos e semimágicos. As coisas são baixadas, os navegadores tomam decisões e tudo “simplesmente
funciona”. Você sabe melhor do que isso, certo? Quero dizer, é de desenvolvimento web que estamos falando.
Nada nunca “simplesmente funciona”.

Primeiro, vamos falar sobre o fluxo de eventos, especificamente eventos DOM. Quando seu navegador visita uma
página que aponta para um manifesto de cache, ele dispara uma série de eventos no objeto
window.applicationCache, conforme descrevo abaixo. Eu sei que isso parece complicado, mas acredite em mim,
esta é a versão mais simples que consegui e que não deixou de fora informações importantes. Aqui está o
processo:

1. Assim que notar um atributo manifesto no elemento <html>, seu navegador dispara um evento de verificação.
(Todos os eventos listados aqui são acionados no objeto de cache window.applicationC.) O evento de
verificação é sempre acionado, independentemente de você ter visitado esta página anteriormente ou
qualquer outra página que aponte para o mesmo manifesto de cache.

2. Se o seu navegador nunca viu esse manifesto de cache antes:

• Ele disparará um evento de download e, em seguida, iniciará o download dos recursos listados no
manifesto do cache.

• Durante o download, seu navegador disparará periodicamente eventos de progresso, que contêm
informações sobre quantos arquivos já foram baixados e quantos arquivos ainda estão na fila para
download.
• Após o download completo de todos os recursos listados no manifesto de cache, o navegador dispara

um evento final, armazenado em cache. Este é o seu sinal de que o offline

O Fluxo de Eventos | 141

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

O aplicativo da web está totalmente armazenado em cache e pronto para ser usado offline. É isso; Você
Terminou.

3. Por outro lado, se você já visitou esta página ou qualquer outra página que aponte para o mesmo manifesto de
cache, seu navegador já conhece esse manifesto de cache e pode já ter alguns recursos no appcache. Na
verdade, ele pode ter todo o aplicativo da web offline funcionando no appcache. Então agora a questão é: o
manifesto do cache mudou desde a última vez que seu navegador o verificou? • Se a resposta for não, o
manifesto do cache não foi alterado. Nesse caso, seu navegador disparará imediatamente um evento

noupdate. É isso; Você Terminou. • Se a resposta for sim, o manifesto do cache foi alterado. Nesse caso, seu
navegador disparará um evento de download e começará a baixar novamente cada recurso

listado no manifesto de cache.

Durante o download, seu navegador disparará periodicamente eventos de progresso, que contêm informações
sobre quantos arquivos já foram baixados e quantos arquivos ainda estão na fila para download.

Depois que todos os recursos listados no manifesto do cache forem baixados novamente com sucesso, o

navegador disparará um evento final, updateready. Este é o seu sinal de que a nova versão do seu aplicativo
da web offline está totalmente armazenada em cache e pronta para ser usada offline. A nova versão ainda não
está em uso. Para fazer “hot-swap” para a nova versão sem forçar o usuário a recarregar a página, você pode
chamar manualmente a função window.applicationC ache.swapCache().

Se, em qualquer ponto deste processo, algo der terrivelmente errado, seu navegador disparará um evento de erro e
parará. Aqui está uma lista irremediavelmente abreviada de coisas que podem dar errado:

• O manifesto do cache retornou um HTTP 404 (Página não encontrada) ou 410 (Permanentemente
Desaparecido) erro.

• O manifesto do cache foi encontrado e não foi alterado, mas a página HTML que apontava para o manifesto não
foi baixada corretamente. • O manifesto do cache foi encontrado e

alterado, mas o navegador não conseguiu baixar um dos recursos listados no manifesto do cache.

A Bela Arte da Depuração, também conhecida como “Kill Me! Me mate agora!"

Quero destacar dois pontos importantes aqui. O primeiro é algo que você acabou de ler, mas provavelmente não
entendeu, então aqui está novamente: se mesmo um único recurso listado em seu arquivo de manifesto de cache
falhar no download corretamente, todo o processo de armazenamento em cache de seu aplicativo da web offline
falhará . Seu navegador disparará o evento de erro, mas não haverá indicação de qual era o problema real. Isso
pode tornar a depuração de aplicativos da Web off-line extremamente frustrante.

142 | Capítulo 8: Vamos colocar isso off-line

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

O segundo ponto importante é algo que não é, tecnicamente falando, um erro, mas parecerá um
bug grave do navegador até você perceber o que está acontecendo. Tem a ver exatamente com a
forma como o seu navegador verifica se um arquivo de manifesto de cache foi alterado.
Este é um processo de três fases. Isso é chato, mas importante, então preste atenção. Aqui está o
procedimento:

1. Através da semântica HTTP normal, seu navegador verificará se o manifesto do cache expirou.
Assim como acontece com qualquer outro arquivo servido por HTTP, seu servidor web
normalmente incluirá metainformações sobre o arquivo nos cabeçalhos de resposta HTTP.
Alguns desses cabeçalhos HTTP (Expires e Cache-Control) informam ao seu navegador como
é permitido armazenar o arquivo em cache sem nunca perguntar ao servidor se ele foi alterado.
Esse tipo de cache não tem nada a ver com aplicativos da web offline. Isso acontece com
praticamente todas as páginas HTML, folhas de estilo, scripts, imagens ou outros recursos no
a teia.

2. Se o manifesto do cache expirou (de acordo com seus cabeçalhos HTTP), seu navegador
perguntará ao servidor se existe uma nova versão e, em caso afirmativo, fará o download dela.
Para fazer isso, seu navegador emite uma solicitação HTTP que inclui a data da última
modificação do arquivo de manifesto de cache, que seu servidor web incluiu nos cabeçalhos
de resposta HTTP na última vez que seu navegador baixou o arquivo. Se o servidor web
determinar que o arquivo de manifesto não foi alterado desde aquela data, ele simplesmente
retornará um código de status 304 (Não Modificado). Novamente, nada disso é específico para
aplicações web off-line. Isso acontece com praticamente todos os recursos da Web.
3. Se o servidor web achar que o arquivo de manifesto foi alterado desde aquela data, ele retornará
um código de status HTTP 200 (OK), seguido pelo conteúdo do novo arquivo junto com os
novos cabeçalhos Cache-Control e uma nova data da última modificação . Isso garante que as
etapas 1 e 2 funcionarão corretamente na próxima vez. (HTTP é legal; os servidores web estão
sempre planejando o futuro. Se o seu servidor web realmente precisa enviar um arquivo para
você, ele faz tudo o que pode para garantir que não precise enviá-lo duas vezes sem motivo.)
Depois de baixado o novo arquivo de manifesto de cache, seu navegador verificará o conteúdo
em relação à cópia baixada da última vez. Se o conteúdo do arquivo de manifesto de cache for
o mesmo da última vez, seu navegador não baixará novamente nenhum dos recursos listados
no manifesto.

Qualquer uma dessas etapas pode atrapalhar você enquanto desenvolve e testa seu aplicativo da
web offline. Por exemplo, digamos que você implemente uma versão do seu arquivo de manifesto
de cache e, 10 minutos depois, perceba que precisa adicionar outro recurso a ele. Não tem problema,
certo? Basta adicionar outra linha e reimplantar. Bzzt. Aqui está o que vai acontecer: você recarrega
a página, seu navegador percebe o atributo manifesto, aciona o evento de verificação e então...
nada. Seu navegador insiste teimosamente que o arquivo de manifesto do cache não foi alterado.
Por que? Porque, por padrão, seu servidor web provavelmente está configurado para instruir os
navegadores a armazenar arquivos estáticos em cache por algumas horas (via semântica HTTP,
usando cabeçalhos Cache-Control). Isso significa que seu navegador nunca passará da etapa 1
desse processo de três fases. Claro, o servidor web sabe que o arquivo foi alterado, mas seu
navegador nem sequer pergunta ao servidor web. Por que? Porque a última vez

A Bela Arte da Depuração, também conhecida como “Kill Me! Me mate agora!" | 143

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

seu navegador baixou o manifesto do cache, o servidor da web disse para ele armazenar o recurso em cache por algumas
horas (via semântica HTTP, usando cabeçalhos Cache-Control). E agora, 10 minutos depois, é exatamente isso que o seu
navegador está fazendo.

Para ser claro, isso não é um bug, é um recurso. Tudo está funcionando exatamente como deveria. Se os servidores web não
tivessem uma maneira de dizer aos navegadores (e proxies intermediários) para armazenar coisas em cache, a web entraria
em colapso da noite para o dia. Mas isso não é nenhum conforto depois de passar algumas horas tentando descobrir por que
seu navegador não notará o manifesto de cache atualizado. (E melhor ainda, se você esperar o suficiente, ele começará a
funcionar misteriosamente novamente! Porque o cache HTTP expirou! Exatamente como deveria! Mate-me!

Me mate agora!)

Então, aqui está uma coisa que você absolutamente deve fazer: reconfigurar seu servidor web para que seu arquivo de
manifesto de cache não possa ser armazenado em cache pela semântica HTTP. Se você estiver executando um servidor web
baseado em Apache, estas duas linhas em seu arquivo .htaccess resolverão o problema:

Expira Ativo em
Expira o "acesso" padrão

Na verdade, isso desativará o cache para todos os arquivos nesse diretório e em todos os subdiretórios.
Provavelmente não é isso que você deseja na produção, então você deve qualificar isso com uma diretiva <Files> para que
afete apenas o arquivo de manifesto de cache ou criar um subdiretório que contenha nada além deste arquivo .htaccess e seu
arquivo de manifesto de cache. Como de costume, os detalhes de configuração variam de acordo com o servidor web, portanto
consulte a documentação do seu servidor para saber como controlar os cabeçalhos de cache HTTP.

No entanto, desabilitar o cache HTTP no arquivo de manifesto do cache não resolverá todos os seus problemas. Você ainda
terá momentos em que alterou um dos recursos no appcache, mas ele ainda estará na mesma URL em seu servidor web. Aqui,
a etapa 2 do processo trifásico vai ferrar você. Se o seu arquivo de manifesto de cache não tiver sido alterado, o navegador
nunca notará que um dos recursos armazenados em cache anteriormente foi alterado. Considere o seguinte exemplo:

MANIFESTO DE CACHE

# rev 42
relógio.js
relógio.css

Se você alterar clock.css e reimplantá-lo, não verá as alterações, porque o arquivo de manifesto do cache em si não foi alterado.
Cada vez que você fizer uma alteração em um dos recursos do seu aplicativo Web offline, será necessário alterar o próprio
arquivo de manifesto de cache. Isso pode ser tão simples quanto alterar um único caractere. A maneira mais fácil que encontrei
de fazer isso é incluir uma linha de comentário com um número de revisão no arquivo de manifesto. Sempre que você alterar
um dos recursos, altere o número da revisão no comentário. O servidor web retornará o arquivo de manifesto de cache recém-
alterado, seu navegador notará que o conteúdo do arquivo foi alterado e iniciará o processo para baixar novamente todos os
recursos listados no manifesto:

MANIFESTO DE
CACHE # rev 43

144 | Capítulo 8: Vamos colocar isso off-line

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

relógio.js
relógio.css

Vamos construir um!

Lembra-se do jogo Halma que apresentamos no Capítulo 4 (veja “Um exemplo completo” na página 75) e
posteriormente melhorado salvando o estado com armazenamento local persistente (veja “Armazenamento
HTML5 em ação” na página 132)? Vamos colocar nosso jogo Halma offline.

Para fazer isso, precisamos de um manifesto que liste todos os recursos de que o jogo precisa. Bem, há a
página HTML principal, um único arquivo JavaScript que contém todo o código do jogo e... é isso. Não há
imagens, porque todo o desenho é feito programaticamente através da API canvas (veja o Capítulo 4), e
todos os estilos CSS necessários estão em um elemento <style> no topo da página HTML. Então, este é o
nosso manifesto de cache:
MANIFESTO DE
CACHE halma.html
../halma-localstorage.js

Uma palavra sobre caminhos. Criei um subdiretório offline/ no diretório exemplos/ e esse arquivo de manifesto
de cache fica dentro do subdiretório. Como a página HTML precisará de uma pequena adição para funcionar
off-line (mais sobre isso em um minuto), criei uma cópia separada do arquivo HTML, que também fica no
subdiretório offline/. Mas como não há alterações no código JavaScript em si desde que adicionamos suporte
ao armazenamento local (consulte “Armazenamento HTML5 em ação” na página 132), estou literalmente
reutilizando o mesmo arquivo .js, que fica no diretório pai (exemplos/ ). Ao todo, os arquivos ficam assim: /
examples/localstorage-halma.html /examples/halma-localstorage.js /examples/offline/halma.manifest /
examples/offline/halma.html

No arquivo de manifesto de cache (/examples/offline/halma.manifest), queremos fazer referência a dois


arquivos. A primeira é a versão offline do arquivo HTML (/examples/offline/halma.html), que está listada no
arquivo de manifesto sem qualquer prefixo de caminho porque os dois arquivos estão no mesmo diretório. O
segundo é o arquivo JavaScript, que fica no diretório pai (/examples/halma-localstorage.js) e está listado no
arquivo de manifesto usando a notação de URL relativa: ../halma-localstorage.js. É exatamente como você
pode usar uma URL relativa em um atributo <img src>. Como você verá no próximo exemplo, você também
pode usar caminhos absolutos (que começam na raiz do domínio atual) ou mesmo URLs absolutos (que
apontam para recursos em outros domínios).

Agora, no arquivo HTML, precisamos adicionar o atributo manifest que aponta para o arquivo de manifesto do
cache:

<!DOCTYPE
html> <html lang="en" manifest="halma.manifest">

Vamos construir um! | 145

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

E é isso! Quando um navegador com capacidade off-line carrega pela primeira vez a página
HTML habilitada para off-line, ele baixa o arquivo de manifesto do cache vinculado e começa a
baixar todos os recursos referenciados e a armazená-los no cache do aplicativo off-line. A partir
de então, o algoritmo do aplicativo offline assumirá o controle sempre que você revisitar a página.
Você pode jogar offline e, como ele se lembra de seu estado localmente, você pode sair e voltar
quantas vezes quiser.

Leitura adicional
Padrões:

• Aplicativos web off-line na especificação HTML5


Documentação do fornecedor do navegador:

• “Recursos offline no Firefox” no Mozilla Developer Center • “HTML5


Offline Application Cache”, parte do “Safari Client-Side Storage e
Guia de programação de aplicativos offline”
Tutoriais e demonstrações:

• “Gmail for Mobile HTML5 Series: Using Appcache to Launch Offline - part 1”, por
Andrew Grieve

• “Gmail for Mobile HTML5 Series: Using Appcache to Launch Offline - part 2”, por
Andrew Grieve

• “Gmail for Mobile HTML5 Series: Usando Appcache para iniciar off-line - parte 3”, por
Andrew Grieve

• “Depurando cache de aplicativos offline HTML 5”, por Jonathan Stark • “Um
aplicativo de upload e editor de imagens offline HTML5”, por Paul Rouget

146 | Capítulo 8: Vamos colocar isso off-line

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

CAPÍTULO 9

Uma forma de loucura

Mergulhando

Todo mundo conhece formulários web, certo? Faça um <form>, adicione alguns elementos <input type="text"> e talvez
uma <input type="password">, finalize com um botão <input type="submit"> e pronto .

Você não sabe nem metade disso. HTML5 define mais de uma dúzia de novos tipos de entrada que você pode usar em
seus formulários. E quando digo “usar”, quero dizer que você pode usá-los agora mesmo, sem quaisquer correções, hacks
ou soluções alternativas. Agora não fique muito animado; Não quero dizer que todos esses novos recursos interessantes
sejam realmente suportados em todos os navegadores.
Oh meu Deus, não, não quero dizer isso de jeito nenhum. Nos navegadores modernos, sim, seus formulários vão arrasar
com todo tipo de bunda. Em navegadores legados, seus formulários ainda funcionarão, mas com menos agressões.
O que quer dizer que todos esses recursos são degradados normalmente em todos os navegadores. Até mesmo o IE 6.

Texto de espaço reservado

A primeira melhoria que o HTML5 traz aos formulários da web é a capacidade de definir texto de espaço reservado em um
campo de entrada. O texto do espaço reservado é exibido dentro do campo de entrada enquanto o campo estiver vazio e
sem foco. Assim que você clica (ou tabula) no campo de entrada, o texto do espaço reservado desaparece.

Você provavelmente já viu texto de espaço reservado antes. Por exemplo, o Mozilla Firefox 3.5 agora inclui texto de espaço
reservado na barra de localização que diz “Marcadores e histórico de pesquisa”, conforme mostrado na Figura 9-1.

Figura 9-1. Texto de espaço reservado na caixa de pesquisa do Firefox

147

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Quando você clica (ou tabula) na barra de localização, o texto do espaço reservado desaparece
(Figura 9-2).

Figura 9-2. O texto do espaço reservado desaparece em foco

Ironicamente, o Firefox 3.5 não suporta a adição de texto de espaço reservado aos seus próprios formulários web.
É a vida. O suporte do navegador para espaços reservados é mostrado na Tabela 9-1.

Tabela 9-1. Suporte para espaço reservado

Ou seja Raposa de fogo Safári cromada Ópera Iphone Android

• 3,7+ 4,0+ 4,0+ • • •

Veja como você pode incluir texto de espaço reservado em seus próprios formulários da web:

<formulário>

<input name="q" placeholder="Pesquisar favoritos e histórico">


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

Os navegadores que não suportam o atributo placeholder irão simplesmente ignorá-lo. Nenhum dano,
nenhuma falta.

Pergunte ao professor Markup

P: Posso usar marcação HTML no atributo placeholder ? Quero inserir uma imagem ou
talvez mude as cores.

R: O atributo placeholder só pode conter texto, não marcação HTML. No entanto, há


são algumas extensões CSS específicas do fornecedor que permitem estilizar o texto do espaço reservado em
alguns navegadores.

Campos de foco automático

Muitos sites usam JavaScript para focar automaticamente o primeiro campo de entrada de um formulário da web.
Por exemplo, a página inicial do Google.com focará automaticamente a caixa de entrada para que você possa
digite as palavras-chave de pesquisa sem precisar posicionar o cursor na caixa de pesquisa.
Embora isso seja conveniente para a maioria das pessoas, pode ser irritante para usuários avançados ou pessoas
com necessidades especiais. Se você pressionar a barra de espaço esperando rolar a página, a página irá
não role porque o foco já está em um campo de entrada de formulário. Em vez disso, você digitará um espaço
no campo. Se você focar em um campo de entrada diferente enquanto a página ainda está carregando, o site
O script de foco automático pode “útil” mover o foco de volta para o campo de entrada original após
conclusão, interrompendo seu fluxo e fazendo com que você digite no lugar errado.

148 | Capítulo 9: Uma Forma de Loucura

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Como o foco automático é feito com JavaScript, pode ser complicado lidar com tudo isso
casos extremos, e há poucos recursos para pessoas que não querem que uma página da web seja “roubada”
o foco.

Para resolver esse problema, o HTML5 introduz um atributo autofocus em todos os formulários da web.
trolls. O atributo autofocus faz exatamente o que diz na lata: assim que a página
carrega, ele move o foco de entrada para um campo de entrada específico. Mas porque é apenas marcação
em vez de script, o comportamento será consistente em todos os sites. Além disso, os fornecedores de navegadores (ou
autores de extensões) podem oferecer aos usuários uma maneira de desativar o comportamento de foco automático.
A Tabela 9-2 mostra quais navegadores suportam foco automático.

Tabela 9-2. Suporte para foco automático

Ou seja Raposa de fogo Safári cromada Ópera Iphone Android

• • 4,0+ 3,0+ 10,0+ ÿ ÿ

Veja como você pode definir um campo de formulário para foco automático:

<formulário>

<input name="q" foco automático>


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

Os navegadores que não suportam o atributo autofocus irão simplesmente ignorá-lo.

O que é isso? Você diz que deseja que seus campos de foco automático funcionem em todos os navegadores, não apenas
esses navegadores HTML5 sofisticados? Você pode manter seu script de foco automático atual. Apenas
faça duas pequenas alterações:

1. Adicione o atributo autofocus à sua marcação HTML.

2. Detecte se o navegador suporta o atributo autofocus (consulte “Formulário de foco automático” na página 27) e
execute seu próprio script de foco automático somente se o navegador não suportar.
suporta foco automático nativamente:

<nome do formulário="f">

<input id="q" foco automático>


<roteiro>
if (!("foco automático" em document.createElement("input"))) {
document.getElementById("q").focus();
}
</script>
<input type="submit" value="Ir">
</form>
...

Vá para http:// diveintohtml5.org/ examples/ input-autofocus-with-fallback.html para ver um


exemplo de foco automático com fallback.

Campos de foco automático | 149

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Professor Markup diz que

muitas páginas da web esperam até que window.onload seja acionado para definir o foco. Mas o
evento window.onload não é acionado até que todas as suas imagens sejam carregadas. Se a sua
página tiver muitas imagens, um script tão ingênuo poderá reorientar o campo depois que o usuário
começar a interagir com outra parte da sua página. (É por isso que usuários avançados odeiam
scripts de foco automático.) O exemplo anterior coloca o script de foco automático imediatamente
após o campo de formulário ao qual ele faz referência, mas seus sistemas de back-end podem não
ser tão flexíveis. Se você não conseguir inserir um script no meio da sua página, você deve definir o
foco durante um evento personalizado como $(document).ready() do jQuery em vez de window.onload.

Endereço de e-mail
Durante mais de uma década, os formulários web incluíram apenas alguns tipos de campos – os mais comuns
estão listados na Tabela 9-3.

Tabela 9-3. Tipos de entrada em HTML 4

Tipo de campo Código HTML Notas

Caixa de seleção
<input type="checkbox"> Pode ser ativado ou
Botao de radio desativado <input type="radio"> Pode ser agrupado com outras entradas
Campo de senha <input type="password"> Ecoa pontos em vez de caracteres conforme o usuário digita

Lista suspensa <selecionar><opção>...

Seletor de arquivos <input type="arquivo"> Abre uma caixa de diálogo “abrir arquivo”

Botão enviar <input type="submit">

Texto simples
<input type="texto"> O atributo type pode ser omitido

Todos esses tipos de entrada ainda funcionam em HTML5. Se você estiver “atualizando para HTML5” (talvez
alterando seu tipo de documento; consulte “O tipo de documento” na página 31), não será necessário fazer
nenhuma alteração em seus formulários da web. Viva a compatibilidade com versões anteriores!

No entanto, o HTML5 define vários novos tipos de campos e, por motivos que ficarão claros em breve, não há
razão para não começar a usá-los.

O primeiro desses novos tipos de entrada é para endereços de email. Se parece com isso:

<formulário>

<input type="email"> <input


type="submit" value="Go"> </form>

Eu estava prestes a escrever uma frase que começava com “Em navegadores que não suportam type="email"...”,
mas me contive. Por que? Porque não tenho certeza do que significaria dizer que um navegador não suporta
type = "email". Todos os navegadores “suportam” type="email". Eles podem não fazer nada de especial com
isso (você verá alguns exemplos de

150 | Capítulo 9: Uma Forma de Loucura

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

tratamento especial em breve), mas navegadores que não reconhecem type="email" irão tratá-lo como
type="text" e renderizá-lo como um campo de texto simples.

Não consigo enfatizar o suficiente o quão importante isso é. A Web possui milhões de formulários que
solicitam que você insira um endereço de e-mail, e todos eles usam <input type="text">. Você vê uma caixa
de texto, digita seu endereço de e-mail na caixa de texto e pronto. Depois vem o HTML5, que define
type="email". Os navegadores enlouquecem? Não. Todos os navegadores do planeta tratam um atributo de
tipo desconhecido como type="text" — até mesmo o IE 6. Assim, você pode “atualizar” seus formulários
web para usar type="email" agora mesmo.

O que significaria dizer que um navegador suporta type ="email"? Bem, isso pode significar uma série de
coisas. A especificação HTML5 não exige nenhuma interface de usuário específica para os novos tipos de
entrada. O Opera estiliza o campo do formulário com um pequeno ícone de e-mail.
Outros navegadores HTML5, como Safari e Chrome, simplesmente o renderizam como uma caixa de texto
— exatamente como type="text" — para que seus usuários nunca saibam a diferença (a menos que
visualizem o código-fonte da página).
E depois há o iPhone.

O iPhone não possui teclado físico. Toda a “digitação” é feita tocando em um teclado na tela que aparece
nos momentos apropriados, como quando você foca um campo de formulário em uma página da web. A
Apple fez algo muito inteligente no navegador do iPhone: ele reconhece vários dos novos tipos de entrada
HTML5 e altera dinamicamente o teclado na tela para otimizar esse tipo de entrada.

Por exemplo, endereços de e-mail são texto, certo? Claro, mas são um tipo especial de texto.
Ou seja, praticamente todos os endereços de e-mail contêm o sinal @ e pelo menos um ponto final (.), mas
é improvável que contenham espaços. Portanto, quando um usuário do iPhone se concentra em um
elemento <input type="email"> , ele obtém um teclado na tela que contém uma barra de espaço menor que
o normal, além de teclas dedicadas para @ e . caracteres, conforme mostrado na Figura 9-3.

Resumindo: não há nenhuma desvantagem em converter todos os campos do formulário de endereço de e-


mail para type="email" imediatamente. Praticamente ninguém notará, exceto os usuários do iPhone, que
provavelmente também não notarão. Mas aqueles que perceberem sorrirão silenciosamente e agradecerão
por tornar sua experiência na web um pouco mais fácil.

Endereços da Web

Endereços da Web – conhecidos por muitos como URLs e por alguns pedantes como URIs – são outro tipo
de texto especializado. A sintaxe de um endereço web é limitada pelos padrões relevantes da Internet. Se
alguém solicitar que você insira um endereço da web em um formulário, ele estará esperando algo como
http://www.google.com, e não “125 Farwood Road”. Barras e pontos são comuns, mas espaços são
proibidos. E todo endereço da web tem um sufixo de domínio como “.com” ou “.org”.

Eis...(rufar os tambores, por favor)...<input type="url">. No iPhone, parece com a Figura 9-4.

Endereços da Web | 151

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Figura 9-3. Teclado otimizado para inserir um endereço de e-mail

Figura 9-4. Teclado otimizado para inserir um URL

152 | Capítulo 9: Uma Forma de Loucura

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Assim como acontece com os campos de endereço de e-mail, o iPhone oferece um teclado virtual especial
otimizado para endereços da web. A barra de espaço foi completamente substituída por três teclas virtuais: um
ponto final, uma barra e um botão “.com”. Você pode manter pressionado o botão “.com” para escolher outros
sufixos comuns, como “.org” ou “.net”.

Os navegadores que não suportam HTML5 tratarão type="url" exatamente como type="text", portanto não há
nenhuma desvantagem em usá-lo para todas as suas necessidades de inserção de endereços da web.

Números como caixas giratórias

A seguir: números. Pedir um número é, em muitos aspectos, mais complicado do que pedir um e-mail ou endereço
da web. Em primeiro lugar, os números são mais complicados do que você imagina.
Rápido: escolha um número. –1? Não, eu quis dizer um número entre 1 e 10. 7½? Não, não, nem uma fração,
bobo. ÿ? Agora você está apenas sendo irracional.

O que quero dizer é que você não costuma pedir “apenas um número”. É mais provável que você solicite um
número em um intervalo específico e queira apenas certos tipos de números dentro desse intervalo - talvez
números inteiros, mas não frações ou decimais, ou algo mais esotérico, como números divisíveis por 10. HTML5
tem você cobriu. Vejamos um exemplo:

<input type="número"
min="0"
max="10"
passo="2"
valor="6">

Vamos pegar um atributo de cada vez (você pode acompanhar com um exemplo ao vivo se você gostar):

• type="number" significa que este é um campo numérico. • min="0"

especifica o valor mínimo aceitável para este campo. • max="10" é o valor máximo

aceitável. • step="2", combinado com o valor min , define os

números aceitáveis no
intervalo: 0, 2, 4 e assim por diante, até o valor máximo .
• valor="6" é o valor padrão. Isso deve parecer familiar. É o mesmo nome de atributo que você sempre usou

para especificar valores para campos de formulário. (Mencionei isso aqui para deixar claro que o HTML5 se
baseia em versões anteriores do HTML. Você não precisa reaprender como fazer coisas que já está fazendo.)

Esse é o lado da marcação de um campo numérico. Lembre-se de que todos esses atributos são opcionais. Se
você tiver um mínimo, mas não um máximo, poderá especificar um atributo min , mas nenhum atributo max . O
valor da etapa padrão é 1 e você pode omitir o atributo step , a menos que precise de um valor de etapa diferente.
Se não houver valor padrão, o atributo value pode ser uma string vazia ou até mesmo omitido por completo.

Números como caixas giratórias | 153

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Mas o HTML5 não para por aí. Pelo mesmo preço baixo e gratuito, você também obtém estes
métodos JavaScript úteis:

entrada.stepUp(n)
Aumenta o valor do campo em n
input.stepDown(n)
Diminui o valor do campo em n
input.valueAsNumber
Retorna o valor atual como um número de ponto flutuante (a propriedade input.value é
sempre uma string)

Está tendo problemas para visualizá-lo? Bem, a interface exata de um controle numérico depende
do seu navegador, e diferentes fornecedores de navegadores implementaram suporte de maneiras
diferentes. No iPhone, onde a entrada é difícil no início, o navegador mais uma vez otimiza o
teclado virtual para entrada numérica, conforme mostrado na Figura 9-5.

Figura 9-5. Teclado otimizado para inserir um número

Na versão desktop do Opera, o mesmo campo type="number" é renderizado como um controle


“spinbox”, com pequenas setas para cima e para baixo nas quais você pode clicar para alterar o
valor (Figura 9-6).

154 | Capítulo 9: Uma Forma de Loucura

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Figura 9-6. Uma caixa giratória

O Opera respeita os atributos min, max e step , então você sempre terá um valor numérico aceitável.
Se você aumentar o valor até o máximo, a seta para cima na caixa giratória ficará acinzentada (Figura
9-7).

Figura 9-7. Uma caixa giratória em seu valor máximo

Tal como acontece com todos os outros tipos de entrada que discuti neste capítulo, os navegadores
que não suportam type="number" irão tratá-lo como type="text". O valor padrão aparecerá no campo (já
que está armazenado no atributo value ), mas os outros atributos, como min e max, serão ignorados.
Você está livre para implementá-los sozinho ou pode reutilizar uma das muitas estruturas JavaScript
que já implementaram controles de spinbox. Basta verificar primeiro o suporte nativo ao HTML5 (consulte
“Tipos de entrada” na página 25) , assim: if (!Modernizr.inputtypes.number) { // sem suporte nativo
para campos type="number" // talvez
tente Dojo ou alguma outra estrutura JavaScript }

Números como controles deslizantes

As caixas giratórias, discutidas na seção anterior, não são a única maneira de representar entradas
numéricas. Você provavelmente também já viu controles “deslizantes” semelhantes aos da Figura 9-8.

Figura 9-8. Um controle deslizante

Números como controles deslizantes | 155

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Agora você também pode ter controles deslizantes em seus formulários da web. A marcação parece estranhamente
semelhante ao dos controles spinbox:

<input type="intervalo"
min="0"
máximo="10"

passo = "2"
valor="6">

Os atributos disponíveis são os mesmos de type="number" —min, max, step,


valor - e eles significam a mesma coisa. A única diferença é a interface do usuário. Em vez de
de um campo para digitação, espera-se que os navegadores renderizem type="range" como um controle deslizante.
No momento em que este artigo foi escrito, as versões mais recentes do Safari, Chrome e Opera faziam isso.
(Infelizmente, o iPhone o renderiza como uma simples caixa de texto. Ele nem sequer otimiza sua tela
teclado para entrada numérica.) Todos os outros navegadores simplesmente tratam o campo como type="text",
então não há razão para você não começar a usar type="range" imediatamente.

Seletores de data

O HTML 4 não incluía um controle de seleção de data. Vários frameworks JavaScript têm
pegou a folga - por exemplo, Dojo, interface do usuário jQuery, YUI, e Closure Library - mas de
É claro que cada uma dessas soluções exige “aderir” à estrutura em que a data
selecionador é construído.

O HTML5 finalmente define uma maneira de incluir um controle nativo de seleção de data sem precisar
para fazer o script você mesmo. Na verdade, ele define seis: data, mês, semana, hora, data + hora e
data + hora – fuso horário.

Até agora, como ilustra a Tabela 9-4 , o apoio é...esparso.

Tabela 9-4. Suporte para seletor de data

Tipo de entrada Opera Todos os outros navegadores

9,0+ •
type="data"
9,0+ •
type="mês"
9,0+ •
type="semana"
9,0+ •
tipo = "tempo"
9,0+ •
tipo = "datahora"

type="datahora-local" 9.0+

A Figura 9-9 mostra como o Opera renderiza um <input type="date">.

Se você precisar de um horário para definir essa data, o Opera também suporta <input type="date
tempo">, conforme mostrado na Figura 9-10.

Se você precisar apenas de um mês e um ano (talvez a data de validade do cartão de crédito), o Opera pode
renderizar um <input type="mês">, conforme mostrado na Figura 9-11.

156 | Capítulo 9: Uma Forma de Loucura

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Figura 9-9. Um seletor de data

Figura 9-10. Um seletor de data/ hora

Figura 9-11. Um selecionador de mês

Menos comum, mas também disponível, é a capacidade de escolher uma semana específica do ano com <input
type="week">; veja a Figura 9-12.

Por último, mas não menos importante, você pode escolher um horário com <input type="time">, conforme mostrado
na Figura 9-13.

Selecionadores de data | 157

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Figura 9-12. Um selecionador de semana

Figura 9-13. Um selecionador de tempo

É provável que outros navegadores eventualmente suportem esses tipos de entrada. Enquanto
isso, assim como type="email" (veja “Endereços de e-mail” na página 150) e os outros tipos de
entrada, esses campos de formulário serão renderizados como caixas de texto simples em
navegadores que não reconhecem type="date" e as outras variantes. Se quiser, você pode
simplesmente usar <input type="date"> e amigos, deixar os usuários do Opera felizes e esperar
que outros navegadores o atualizem. Alternativamente, você pode usar <input type="date">,
detectar se o navegador tem suporte nativo para seletores de data (veja “Tipos de entrada” na
página 25) e recorrer a uma solução de script de sua escolha:
<formulário>

<input type="data">
</form>
...
<script>
var i = document.createElement("input");
i.setAttribute("tipo", "data"); if
(i.type == "text") { // Sem
suporte nativo para seletor de data :
( // Use Dojo/jQueryUI/YUI/Closure/alguma outra solução para criar
uma, // então substitua dinamicamente esse elemento

<input>. } </script>

Caixas de pesquisa

OK, este é sutil. Bem, a ideia é bastante simples, mas as implementações podem exigir alguma
explicação. Aqui vai....

158 | Capítulo 9: Uma Forma de Loucura

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Procurar. Não apenas a Pesquisa Google ou o Yahoo! Procurar. (Bem, esses também.) Pense em qualquer caixa de
pesquisa, em qualquer página, em qualquer site. Amazon tem uma caixa de pesquisa. Newegg tem uma caixa de pesquisa.
A maioria dos blogs possui uma caixa de pesquisa. Como eles são marcados? <input type="text">, assim como qualquer
outra caixa de texto na Web. Com HTML5, podemos consertar isso:

<formulário>

<input name="q" type="search"> <input


type="submit" value="Find"> </form>

Em alguns navegadores, você não notará nenhuma diferença em relação a uma caixa de texto normal. Mas se você
estiver usando o Safari no Mac OS X, será semelhante à Figura 9.14.

Figura 9-14. Uma caixa de pesquisa

Você pode ver a diferença? A caixa de entrada tem cantos arredondados! Eu sei, eu sei, você mal consegue conter sua
excitação. Mas espere, tem mais! Quando você começa a digitar na caixa type="search" , o Safari insere um pequeno
botão “x” no lado direito da caixa. Clicar no “x” limpa o conteúdo do campo. (O Google Chrome, que compartilha muita
tecnologia com o Safari, também exibe esse comportamento.) Esses dois pequenos ajustes são feitos para corresponder
à aparência das caixas de pesquisa nativas no iTunes e em outros aplicativos clientes do Mac OS X (Figura 9- 15).

Figura 9-15. Uma caixa de pesquisa focada

A maçã website usa <input type="search"> em sua caixa de pesquisa de site, para ajudar a dar ao site uma sensação
“semelhante ao Mac”. Mas não há nada específico do Mac nisso. É apenas marcação, então cada navegador em cada
plataforma pode optar por renderizar a caixa de pesquisa de acordo com convenções específicas da plataforma. Tal
como acontece com todos os outros novos tipos de entrada, os navegadores que não reconhecem type="search" irão
tratá-lo como type="text", então não há absolutamente nenhuma razão para não começar a usar type="search" para
todas as suas caixas de pesquisa hoje.

Caixas de pesquisa | 159

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Figura 9-16. Opera valida type=“email”

Professor Markup diz Bem,


há uma razão pela qual você pode não querer usar <input type="search">. O Safari não
aplicará os estilos CSS usuais aos campos de pesquisa. (E por “estilos usuais”, quero dizer
coisas básicas como borda, cor de fundo, imagem de fundo, preenchimento, etc.) Mas você
obtém cantos arredondados!

Seletores de cores

HTML5 também define <input type="color">, que permite escolher uma cor e retornar a representação
hexadecimal dessa cor. Nenhum navegador oferece suporte ainda, o que é uma pena, porque sempre
adorei o seletor de cores do Mac OS. Talvez algum dia.

E mais uma coisa...


Neste capítulo, falei sobre novos tipos de entrada e novos recursos, como campos de formulário com
foco automático, mas não mencionei o que talvez seja a parte mais interessante dos formulários
HTML5: validação automática de entrada. Considere o problema comum de inserir um endereço de e-
mail em um formulário da web. Você provavelmente tem alguma validação do lado do cliente em
JavaScript, seguida de validação do lado do servidor em PHP ou Python ou alguma outra linguagem
de script do lado do servidor. Existem dois grandes problemas na validação de endereços de e-mail em JavaScript:

• Um número surpreendente de visitantes (provavelmente cerca de 10%) não terá o JavaScript


ativado. • Você vai
entender errado.

Sério, você vai entender errado. Determinar se uma sequência aleatória de caracteres é um endereço
de e-mail válido é incrivelmente complicado. Quanto mais você olha, mais complicado fica. Eu
mencionei que é muito, muito complicado? Não seria mais fácil descarregar toda a dor de cabeça no
seu navegador?

A captura de tela na Figura 9-16 é do Opera 10, embora a funcionalidade esteja presente desde o
Opera 9. A única marcação envolvida é definir o atributo type como "email" (consulte “Endereços de e-
mail” na página 150). Quando um usuário do Opera tenta enviar um formulário com um campo <input
type="email"> , o Opera oferece automaticamente validação de e-mail compatível com RFC, mesmo
se o script estiver desabilitado.

160 | Capítulo 9: Uma Forma de Loucura

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Figura 9-17. Opera valida tipo=”número”

O Opera também oferece validação de endereços da web inseridos em campos <input type="url"> e
números em campos <input type="number"> . A validação dos números leva em consideração até
mesmo os atributos min e max , portanto o Opera não permitirá que os usuários enviem o formulário se
inserirem um número muito grande (Figura 9-17).

Infelizmente, nenhum outro navegador oferece suporte à validação automática de formulários HTML5
ainda, então você ficará preso a substitutos baseados em script por um tempo.

Leitura adicional
Especificações e padrões:

• tipos de <entrada>
• O atributo <espaço reservado de entrada>
• O atributo <input autofocus>

Bibliotecas JavaScript:

• Modernização, uma biblioteca de detecção HTML5

Leitura adicional | 161

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

CAPÍTULO 10

“Distribuído”, “Extensibilidade” e

Outras palavras extravagantes

Mergulhando
Existem mais de 100 elementos em HTML5. Alguns são puramente semânticos (veja o Capítulo
3) e outros são apenas contêineres para APIs com script (veja o Capítulo 4). Ao longo da
história do HTML (veja o Capítulo 1), especialistas em padrões discutiram sobre quais elementos
deveriam ser incluídos na linguagem. O HTML deve incluir um elemento <figure>? Um
elemento <person>? Que tal um elemento <rant>? Decisões são tomadas, especificações são
escritas, autores criam, implementadores implementam e a Web avança cada vez mais.

É claro que o HTML não agrada a todos. Nenhum padrão pode. Algumas ideias não dão certo. Por
exemplo, não há elemento <person> em HTML5. (Também não há elemento <rant>, caramba!) Não
há nada que impeça você de incluir um elemento <person> em uma página da web, mas ele não será
validado, não funcionará de forma consistente em todos os navegadores (consulte “Uma longa
digressão em Como os navegadores tratam elementos desconhecidos” na página 42) e poderá entrar
em conflito com futuras especificações HTML se for adicionado posteriormente.

Então, se criar seus próprios elementos não é a resposta, o que um autor da web com
inclinação semantica deve fazer? Houve tentativas de estender versões anteriores do HTML.
O método mais popular é com microformatos, que usam os atributos class e rel no HTML
4. Outra opção é o RDFa, que foi originalmente projetado para ser usado em XHTML
(veja “Postscript” na página 14), mas agora está sendo portado para HTML como bem.
Tanto os microformatos quanto o RDFa têm seus pontos fortes e fracos. Eles adotam abordagens
radicalmente diferentes em direção ao mesmo objetivo: estender páginas da Web com semântica
adicional que não faz parte da linguagem HTML central. Não pretendo transformar este capítulo em
um formato de guerra de chamas. (Isso definitivamente exigiria um elemento <rant>!) Em vez disso,
quero me concentrar em uma terceira opção que faz parte e está totalmente integrada ao próprio
HTML5: microdados.

163

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

O que são microdados?

Cada palavra da frase a seguir é importante, então preste atenção.

Professor Markup diz que


microdados anotam o DOM com pares nome/valor com escopo definido de vocabulários
personalizados.

Agora, o que isso significa? Vamos começar do fim e trabalhar de trás para frente. Os microdados giram em
torno de vocabulários personalizados. Pense no “conjunto de todos os elementos HTML5” como um
vocabulário. Este vocabulário inclui elementos para representar uma seção ou um artigo (veja “Novos
Elementos Semânticos em HTML5” na página 41), mas não inclui elementos para representar uma pessoa
ou um evento. Se quiser representar uma pessoa em uma página da web, você precisará definir seu próprio
vocabulário. Microdados permitem que você faça isso. Qualquer pessoa pode definir um vocabulário de
microdados e começar a incorporar propriedades personalizadas em suas próprias páginas da web.

A próxima coisa a saber sobre microdados é que eles funcionam com pares nome/ valor. Cada vocabulário
de microdados define um conjunto de propriedades nomeadas. Por exemplo, um vocabulário de Pessoa
poderia definir propriedades como nome e foto. Para incluir uma propriedade de microdados específica em
sua página da web, forneça o nome da propriedade em um local específico. Dependendo de onde você
declara o nome da propriedade, os microdados possuem regras sobre como extrair o valor da propriedade.
(Mais sobre isso na próxima seção.)

Juntamente com as propriedades nomeadas, os microdados dependem fortemente do conceito de “escopo”.


A maneira mais simples de pensar no escopo de microdados é pensar no relacionamento natural pai-filho
dos elementos no DOM. O elemento <html> (veja “O Elemento Raiz” na página 33) normalmente contém
dois filhos, <head> (veja “O Elemento <head>” na página 34) e <body>. O elemento <body> geralmente
contém vários filhos, cada um dos quais pode ter seus próprios elementos filhos. Por exemplo, sua página
pode incluir um elemento <h1> dentro de um elemento <hgroup> dentro de um elemento <header> (consulte
“Cabeçalhos” na página 45) dentro do elemento <body> . Da mesma forma, uma tabela de dados pode
conter elementos <td> dentro de elementos <tr> dentro de um elemento <table> (dentro de <body>). Os
microdados reutilizam a estrutura hierárquica do próprio DOM para fornecer uma maneira de dizer “todas as
propriedades deste elemento são retiradas deste vocabulário”. Isso permite usar vários vocabulários de
microdados na mesma página. Você pode até aninhar vocabulários de microdados dentro de outros
vocabulários, tudo isso reutilizando a estrutura natural do DOM. (Mostrarei vários exemplos de vocabulários
aninhados ao longo deste capítulo.)

Já mencionei o DOM, mas deixe-me explicar melhor. Microdados tratam da aplicação de semântica adicional
a dados que já estão visíveis em sua página da web. Os microdados não foram projetados para ser um
formato de dados independente. É um complemento ao HTML. Como você verá na próxima seção, os
microdados funcionam melhor quando você já está usando HTML corretamente, mas o vocabulário HTML
não é suficientemente expressivo. Microdados são ótimos para ajustar a semântica dos dados que já estão
no DOM. Se os dados que você está

164 | Capítulo 10: “Distribuído”, “Extensibilidade” e outras palavras sofisticadas

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

a semantificação não está no DOM, você deve recuar e reavaliar se os microdados são a solução certa.

A afirmação do Professor Markup faz mais sentido agora? Espero que sim. Vamos ver como isso
funciona em ação.

O modelo de dados de microdados

Definir seu próprio vocabulário de microdados é fácil. Primeiro você precisa de um namespace, que é
apenas uma URL. O URL do namespace pode apontar para uma página da Web em funcionamento,
embora isso não seja estritamente necessário. Digamos que eu queira criar um vocabulário de
microdados que descreva uma pessoa. Se eu possuir o domínio data-vocabulary.org , usarei a URL
http:// data-vocabulary.org/ Person como namespace para meu vocabulário de microdados. Essa é uma
maneira fácil de criar um identificador globalmente exclusivo: escolha um URL em um domínio que você controla.

Neste vocabulário, preciso definir algumas propriedades nomeadas. Vamos começar com três
propriedades básicas:
• nome (nome completo do

usuário) • foto (um link para uma foto do


usuário) • url (um link para um site associado ao usuário, como um blog ou um perfil do Google)

Duas dessas propriedades são URLs e a outra é texto simples. Cada um deles se presta a uma forma
natural de marcação, mesmo antes de você começar a pensar em microdados ou vocabulários. Imagine
que você tem uma página de perfil ou uma página “sobre”. Seu nome provavelmente está marcado
como um título, como um elemento <h1> . Sua foto provavelmente é um elemento <img> , pois você
deseja que as pessoas a vejam. E quaisquer URLs associados ao seu perfil provavelmente já estão
marcados como hiperlinks, porque você deseja que as pessoas possam clicar neles. Para fins de
discussão, digamos que todo o seu perfil também esteja envolvido em um elemento <section> para
separá-lo do restante do conteúdo da página. Por isso:
<section>
<h1>Mark Pilgrim</
h1> <p><img src="http://www.example.com/photo.jpg" alt="[eu sorrindo]"></
p> <p> <a href="http://diveintomark.org/">weblog</a></
p> </section>

O modelo de dados de microdados consiste em pares nome/valor. Um nome de propriedade de


microdados (como nome , foto ou URL neste exemplo) é sempre declarado em um elemento HTML. O
valor da propriedade correspondente é então obtido do DOM do elemento. Para a maioria dos elementos
HTML, o valor da propriedade é simplesmente o conteúdo do texto do elemento. Contudo, há algumas
exceções, como ilustra a Tabela 10-1 .

O modelo de dados de microdados | 165

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Tabela 10-1. De onde vêm os valores das propriedades dos microdados?

Elemento Valor

<meta> atributo de conteúdo

<áudio> atributo src

<incorporar>

<iframe>

<img>

<fonte>

<vídeo>

<a> atributo href

<área>

<ligação>

atributo de dados
<objeto>

<hora> atributo datahora

Todos os outros elementos Conteúdo de texto

“Adicionar microdados” à sua página é uma questão de adicionar alguns atributos aos elementos
HTML que você já possui. A primeira coisa que você sempre faz é declarar qual vocabulário de
microdados você está usando, adicionando um atributo itemtype . A segunda coisa que você sempre
faz é declarar o escopo do vocabulário, usando um atributo itemscope . Neste exemplo, todos os
dados que queremos semantificar estão em um elemento <section> , então declararemos os atributos
itemtype e itemscope no elemento <section> :
<seção itemscope itemtype="http://data-vocabulary.org/Person">

Seu nome é o primeiro bit de dados dentro do elemento <section> . Está envolvido em um elemento
<h1> . O elemento <h1> não requer nenhum processamento especial, portanto ele se enquadra na
regra “todos os outros elementos” da Tabela 10-1, onde o valor da propriedade microdados é
simplesmente o conteúdo de texto de um elemento (isso funcionaria igualmente bem se seu nome foi
colocado em um elemento <p>, <div> ou <span> ):
<h1 itemprop="name">Marco Peregrino</h1>

Em inglês, diz: “Aqui está a propriedade name do vocabulário http://data-vocabulary.org/ Person . O


valor da propriedade é Mark Pilgrim.”

A seguir está a propriedade da foto . Isto deveria ser um URL. De acordo com a Tabela 10-1, o
“valor” de um elemento <img> é seu atributo src . Ei, olha, o URL da sua foto de perfil já está em um
atributo <img src> ! Tudo que você precisa fazer é declarar que o elemento <img> é a propriedade
photo : <p><img itemprop="photo"
src="http://www.example.com/
photo.jpg" alt="[me sorrindo]"></p>

166 | Capítulo 10: “Distribuído”, “Extensibilidade” e outras palavras sofisticadas

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Em inglês, diz: “Aqui está a propriedade photo do http://data-vocabulary.org/ Vocabulário Person . O


valor da propriedade é http://www.example.com/photo.jpg.”

Finalmente, a propriedade url também é uma URL. De acordo com a Tabela 10-1, o “valor” de um
elemento <a> é seu atributo href . E mais uma vez, isso se ajusta perfeitamente à sua marcação
existente. Tudo que você precisa fazer é dizer que seu elemento <a> existente é a propriedade url :
<a itemprop="url" href="http://diveintomark.org/"> mergulhe na marca</a>

Em inglês, diz: “Aqui está a propriedade url do vocabulário http://data-vocabulary.org/ Person . O valor
da propriedade é http://diveintomark.org/.”

Claro, se a sua marcação parecer um pouco diferente, isso não será um problema. Você pode adicionar
propriedades e valores de microdados a qualquer marcação HTML, até mesmo a era realmente
complicada do século 20, tabelas para layout, oh-Deus-por que-concordei-em-manter-esta marcação.
Embora eu não recomende esse tipo de marcação, ela ainda é muito comum e você ainda pode
adicionar microdados a ela:

<TABELA>

<TR><TD>Nome<TD>Marco Peregrino
<TR><TD>Link<TD>
<A href=# onclick=goExternalLink()>http://diveintomark.org/</A> </TABLE>

Para marcar a propriedade name , basta adicionar um atributo itemprop na célula da tabela que contém
o nome. As células da tabela não possuem regras especiais na tabela de valores da propriedade de
microdados, portanto, elas obtêm o valor padrão, onde a propriedade de microdados é o conteúdo do texto:
<TR><TD>Nome<TD itemprop="name">Marca Peregrino

Adicionar a propriedade url parece mais complicado. Esta marcação não usa o elemento <a>
corretamente. Em vez de colocar o destino do link no atributo href , ele não tem nada de útil no atributo
href e usa JavaScript no atributo onclick para chamar uma função (não mostrada) que extrai a URL e
navega até ela. Para obter pontos extras do tipo “ah, merda, por favor, pare de fazer isso”, vamos fingir
que a função também abre o link em uma pequena janela pop-up sem barras de rolagem. A Internet não
foi divertida no século passado?

De qualquer forma, você ainda pode converter isso em uma propriedade de microdados; você só precisa
ser um pouco criativo. Usar o elemento <a> diretamente está fora de questão. O destino do link não está
no atributo href e não há como substituir a regra que diz “em um elemento <a> , procure o valor da
propriedade microdata no atributo href ”. Mas você pode adicionar um elemento wrapper em torno de
toda a bagunça e usá-lo para adicionar a propriedade url microdata:
<TABLE itemscope itemtype="http://data-vocabulary.org/Person">
<TR><TD>Nome<TD>Mark Pilgrim
<TR><TD>Link<TD>
<span itemprop="url">
<A href=# onclick=goExternalLink()>http://diveintomark.org/</A> </TABLE>

O modelo de dados de microdados | 167

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Como o elemento <span> não possui processamento especial, ele usa a regra padrão, “a propriedade
microdata é o conteúdo do texto”. “Conteúdo de texto” não significa “toda a marcação dentro deste
elemento” (como você faria com, digamos, a propriedade DOM innerHTML ). Significa “apenas o texto,
senhora”. Neste caso, http://diveintomark.org/ é o conteúdo de texto do elemento <a> dentro do elemento
<span> .

Resumindo: você pode adicionar propriedades de microdados a qualquer marcação. Você achará mais fácil
adicionar microdados se estiver usando HTML corretamente do que se sua marcação HTML for uma droga,
mas isso sempre pode ser feito.

Marcando pessoas
Os exemplos iniciais da seção anterior não foram completamente inventados. Existe realmente um vocabulário
de microdados para marcar informações sobre pessoas, e é realmente muito fácil. Vamos olhar mais de perto.

A maneira mais fácil de integrar microdados em um site pessoal é na página “sobre”.


Você tem uma página “sobre”, não é? Caso contrário, você pode acompanhar enquanto eu estendo este
exemplo de página “sobre” com semântica adicional. O resultado final está aqui: http:// divein tohtml5.org/
examples/ person-plus-microdata.html.

Vejamos primeiro a marcação bruta, antes de quaisquer propriedades de microdados serem adicionadas:
<seção>
<img largura="204" altura="250"
src="http://diveintohtml5.org/examples/2000_05_mark.jpg" alt="[Mark Pilgrim, por
volta de 2000]">

<h1>Informações de contato</h1> <dl>

<dt>Nome</dt>
<dd>Mark Pilgrim</dd>

<dt>Posição</dt>
<dd>Defensor do desenvolvedor da Google, Inc.</dd>

<dt>Endereço para correspondência</dt>


<dd>
Rua Principal 100<br>
Qualquer cidade, PA 19999<br>
cervo

</dd>
</dl>
<h1>Minhas pegadas digitais</h1> <ul>
<li><a
href="http://diveintomark.org/">weblog</a></li> <li ><a href="http://www.google.com/
profiles/pilgrim">Perfil do Google</a></li> <li><a href="http://www.reddit.com/user /MarkPilgrim">Perfil Reddit.com</
a></li> <li><a href="http://www.twitter.com/diveintomark">Twitter</a></li> </ul> </seção>

168 | Capítulo 10: “Distribuído”, “Extensibilidade” e outras palavras sofisticadas

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

A primeira coisa que você sempre precisa fazer é declarar o vocabulário que está usando e o
escopo das propriedades que você deseja adicionar. Você faz isso adicionando o itemtype e
atributos itemscope no elemento mais externo que contém os outros elementos que
contêm os dados reais. Neste caso, é um elemento <section> :

<seção itemscope itemtype="http://data-vocabulary.org/Person">

Você pode acompanhar on-line as alterações feitas ao longo deste


seção. Antes: http:// diveintohtml5.org/ examples/ person.html; depois:
http:// diveintohtml5.org/ examples/ person-plus-microdata.html.

Agora você pode começar a definir propriedades de microdados no http://data-vocabu


vocabulário lary.org/Person . Mas quais são essas propriedades? Acontece que você pode ver
a lista de propriedades navegando até http:// data-vocabulary.org/ Person. Os microdados
a especificação não exige isso, mas eu diria que é certamente uma “melhor prática”. Afinal,
se quiser que os desenvolvedores realmente usem seu vocabulário de microdados, você precisa documentá-lo. E
onde melhor colocar sua documentação do que a própria URL do vocabulário?
A Tabela 10-2 lista as propriedades do vocabulário Person.

Tabela 10-2. Vocabulário pessoal

Propriedade Descrição

nome Nome

apelido Apelido

Um link de imagem
foto

título O cargo da pessoa (por exemplo, “Gerente Financeiro”)

papel A função da pessoa (por exemplo, “Contador”)

url Link para uma página da web, como a página inicial da pessoa

afiliação O nome de uma organização à qual a pessoa está associada (por exemplo, um empregador)

amigo Identifica uma relação social entre a pessoa descrita e outra pessoa

contato Identifica uma relação social entre a pessoa descrita e outra pessoa

conhecido Identifica uma relação social entre a pessoa descrita e outra pessoa

endereço A localização da pessoa (pode ter as subpropriedades endereço, localidade, região,


código postal e nome do país)

A primeira coisa neste exemplo de página “sobre” é uma foto minha. Naturalmente, está marcado
com um elemento <img> . Para declarar que este elemento <img> é minha foto de perfil, todos
o que precisamos fazer é adicionar itemprop="photo" a ele:

<img itemprop="foto" largura="204" altura="250"


src="http://diveintohtml5.org/examples/2000_05_mark.jpg"
alt="[Mark Pilgrim, por volta de 2000]">

Marcando Pessoas | 169

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Onde está o valor da propriedade de microdados? Já está lá, no atributo src . Se você se lembra da Tabela
10-1, o “valor” de um elemento <img> é seu atributo src . Cada elemento <img> possui um atributo src —
caso contrário, seria apenas uma imagem quebrada — e o src é sempre uma URL. Ver? Se você estiver
usando HTML corretamente, microdados serão fáceis.

Além disso, este elemento <img> não está sozinho na página. É um elemento filho do elemento <section> ,
aquele que acabamos de declarar com o atributo itemscope . Os microdados reutilizam os relacionamentos
pai-filho dos elementos na página para definir o escopo das propriedades dos microdados. Em linguagem
simples, estamos dizendo: “Este elemento <section> representa uma pessoa. Quaisquer propriedades de
microdados que você possa encontrar nos filhos do elemento <section> são propriedades dessa pessoa.”
Se ajudar, você pode pensar no elemento <section> como o sujeito de uma frase. O atributo itemprop
representa o verbo da frase – algo como “é retratado em” – e o valor da propriedade microdata representa
o objeto da frase:

Esta pessoa [explícita, de <section itemscope itemtype="...">] é retratada em [explícita,

de <img itemprop="photo">] http://diveintohtml5.org/examples/

2000_05_mark.jpg [implícita, do atributo <img src> ]

O assunto só precisa ser definido uma vez, colocando os atributos itemscope e itemtype no elemento
<section> mais externo . O verbo é definido colocando o atributo itemprop="photo" no elemento <img> . O
objeto da frase não precisa de nenhuma marcação especial, porque a Tabela 10-1 diz que o valor da
propriedade de um elemento <img> é seu atributo src .

Passando para a próxima parte da marcação, vemos um cabeçalho <h1> e o início de uma lista <dl> . Nem
o <h1> nem o <dl> precisam ser marcados com microdados. Nem todo pedaço de HTML precisa ser uma
propriedade de microdados. Os microdados tratam das propriedades em si, não da marcação ou dos
cabeçalhos que cercam as propriedades. Este <h1> não é uma propriedade; é apenas um cabeçalho. Da
mesma forma, o <dt> que diz “Nome” é apenas um rótulo, não uma propriedade:

<h1>Informações de contato</h1>
<dl>
<dt>Nome</dt>
<dd>Marco Peregrino</dd>

Então, onde está a informação real? Está no elemento <dd> , então é onde precisamos colocar o atributo
itemprop . Qual é a propriedade? É a propriedade do nome . Onde está o valor do imóvel? É o texto dentro
do elemento <dd> . Isso precisa ser marcado?
A Tabela 10-1 diz que não, os elementos <dd> não têm processamento especial, então o valor da
propriedade é apenas o texto dentro do elemento:
<dd itemprop="name">Marco Peregrino</dd>

O que acabamos de dizer em inglês? “O nome dessa pessoa é Mark Pilgrim.” Bem, ok então.
Avante.

170 | Capítulo 10: “Distribuído”, “Extensibilidade” e outras palavras sofisticadas

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

As próximas duas propriedades são um pouco complicadas. Esta é a marcação, pré-microdados:


<dt>Posição</dt>
<dd>Defensor do desenvolvedor da Google, Inc.</dd>

Se você observar a definição do vocabulário Pessoa, o texto “Defensor do desenvolvedor do Google, Inc.”
na verdade, abrange duas propriedades: título (“Defensor do desenvolvedor”) e afiliação (“Google, Inc.”).
Como você pode expressar isso em microdados? A resposta curta é: você não pode. Os microdados não
têm como dividir trechos de texto em propriedades separadas. Você não pode dizer “os primeiros 18
caracteres deste texto são uma propriedade de microdados e os últimos 12 caracteres deste texto são
outra propriedade de microdados”.

Mas tudo não está perdido. Imagine que você deseja estilizar o texto “Defensor do desenvolvedor” em uma
fonte diferente do texto “Google, Inc.” CSS também não pode fazer isso. Então, o que você faria? Primeiro,
você precisaria agrupar os diferentes pedaços de texto em elementos fictícios, como <span>, e depois
aplicar regras CSS diferentes a cada elemento <span> .

Esta técnica também é útil para microdados. Existem duas informações distintas aqui: um título e uma
afiliação. Se você agrupar cada parte em um elemento <span> fictício , poderá declarar que cada <span>
é uma propriedade de microdados separada: <dt>Position</dt> <dd><span
itemprop="title">
Defensor do desenvolvedor</ span> para <span
itemprop="affiliation">Google, Inc.<span></dd>

Ta-da! Em inglês, diz: “O título desta pessoa é 'Defensor do desenvolvedor'. Esta pessoa é funcionária da
Google, Inc.” Duas frases, duas propriedades de microdados. Um pouco mais de marcação, mas uma troca
que vale a pena.

A mesma técnica é útil para marcar endereços. O vocabulário Person define uma
propriedade de endereço , que é um item de microdados. Isso significa que o endereço
tem seu próprio vocabulário (http:// data-vocabulary.org/ Address) e define suas
próprias propriedades: endereço, localidade, região, código postal e nome do país.
Se você é um programador, provavelmente está familiarizado com a notação de ponto para definir objetos
e suas propriedades. Pense no relacionamento assim:

• Pessoa

• Endereço.pessoa

• Pessoa.endereço.rua-endereço

• Pessoa.endereço.localidade •

Pessoa.endereço.região •

Pessoa.endereço.código postal •

Pessoa.endereço.nome do país

Neste exemplo, o endereço inteiro está contido em um único elemento <dd> . (Mais uma vez, o elemento
<dt> é apenas um rótulo, portanto não desempenha nenhum papel na adição de semântica com

Marcando Pessoas | 171

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

microdados.) É fácil anotar a propriedade do endereço . Basta adicionar um atributo itemprop no


elemento <dd> :

<dt>Endereço para
correspondência</dt> <dd itemprop="address">

Mas lembre-se, a propriedade address é em si um item de microdados. Isso significa que precisamos
adicionar os atributos itemscope e itemtype também:
<dt>Endereço para
correspondência</dt> <dd itemprop="address"
itemscope itemtype="http://data-vocabulary.org/Address">

Já vimos tudo isso antes, mas apenas para itens de nível superior. Um elemento <section> define
itemtype e itemscope, e todos os elementos dentro do elemento <section> que definem propriedades
de microdados têm “escopo” dentro desse vocabulário específico. Mas esta é a primeira vez que
vemos escopos aninhados — definindo um novo itemtype e itemscope (no elemento <dd> ) dentro
de um já existente (no elemento <section> ). Este escopo aninhado funciona exatamente como o
HTML DOM. O elemento <dd> possui um certo número de elementos filhos, todos com escopo
definido para o vocabulário definido no elemento <dd> . Uma vez que o elemento <dd> é fechado
com uma tag </dd> correspondente , o escopo reverte para o vocabulário definido pelo elemento
pai (<section>, neste caso).

As propriedades do vocabulário Endereço sofrem o mesmo problema que encontramos com as


propriedades de título e afiliação . Há apenas um texto longo, mas queremos dividi-lo em diversas
propriedades de microdados separadas. A solução é a mesma. Envolvemos cada informação
distinta em um elemento <span> fictício e, em seguida, declaramos propriedades mi crodata em
cada elemento <span> :
<dd itemprop="address" itemscope
itemtype="http://data-vocabulary.org/Address"> <span
itemprop="street-address">100 Main Street<br> <span itemprop="locality
">Qualquer cidade, <span itemprop="region">PA <span
itemprop="postal-code">19999 <span
itemprop="country-name">EUA</span > </dd> </dl>

Em inglês: “Esta pessoa tem um endereço postal. A parte do endereço postal é '100 Main Street'. A
parte da localidade é 'Anytown'. A região é 'PA'. O código postal é '19999'. O nome do país é 'EUA'.”
Fácil.

Pergunte ao professor Markup

P: Este formato de endereço postal é específico dos EUA?

R: Não. As propriedades do vocabulário Endereço são genéricas o suficiente para descrever a maioria dos
endereços de correspondência do mundo. Nem todos os endereços terão valores para todas as propriedades,
mas tudo bem. Alguns endereços podem exigir o ajuste de mais de uma “linha” em uma única propriedade,
mas tudo bem também. Por exemplo, se o seu endereço postal

172 | Capítulo 10: “Distribuído”, “Extensibilidade” e outras palavras sofisticadas

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

tem um endereço e um número de suíte, ambos iriam para a subpropriedade


de endereço :
<p itemprop="address"
itemscope itemtype="http://data-vocabulary.org/
Address"> <span itemprop="street-
address"> 100
Main
Street Suite 415
...
</p>

Há mais uma coisa neste exemplo de página “sobre”: uma lista de URLs. O cabulário Person possui
uma propriedade para isso, chamada url. Uma propriedade de URL pode ser qualquer coisa, na verdade.
(Bem, tem que ser uma URL, mas você provavelmente adivinhou.) O que quero dizer é que a definição
da propriedade url é muito vaga. A propriedade pode ser qualquer tipo de URL que você queira associar
a uma Pessoa: um blog, uma galeria de fotos ou um perfil em outro site como Facebook ou Twitter.

A outra coisa importante a ser observada aqui é que uma única Pessoa pode ter várias propriedades
de URL . Tecnicamente, qualquer propriedade pode aparecer mais de uma vez, mas até agora não
aproveitamos isso. Por exemplo, você poderia ter duas propriedades de foto , cada uma apontando
para um URL de imagem diferente. Aqui, quero listar quatro URLs diferentes: meu weblog, minha
página de perfil do Google, meu perfil de usuário no Reddit e minha conta do Twitter.
Em HTML, é uma lista de links: quatro elementos <a> , cada um em seu próprio elemento <li> . Nos
microdados, cada elemento <a> recebe um atributo itemprop="url" :
<h1>Minhas pegadas digitais</h1>
<ul>
<li> <a href="http://diveintomark.org/"
itemprop="url"> weblog</a></li>
<li><a href="http://www.google.com/ profiles/pilgrim"
itemprop="url"> Perfil do Google</a></li>
<li> <a href="http://www.reddit.com/user/MarkPilgrim"
itemprop="url"> Reddit. com perfil</a></li> <li>
<a href="http://www.twitter.com/diveintomark"
itemprop="url"> Twitter</a></li>
</ul>

De acordo com a Tabela 10-1, os elementos <a> possuem processamento especial. O valor da
propriedade microdados é o atributo href , não o conteúdo de texto filho. O texto de cada link é
realmente ignorado por um processador de microdados. Assim, em inglês, diz: “Esta pessoa tem uma
URL em http:// diveintomark.org/. Esta pessoa tem outro URL em http:// www.google.com/ profiles/
pilgrim. Esta pessoa tem outro URL em http:// www.reddit.com/ user/ MarkPil sombrio. Essa pessoa
tem outro URL em http:// www.twitter.com/ diveintomark.”

Marcando Pessoas | 173

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Apresentando os Rich Snippets do

Google, quero voltar por um momento e perguntar: “Por que estamos fazendo isso?” Estamos
adicionando semântica apenas por adicionar semântica? Não me interpretem mal; Gosto de mexer
com colchetes angulares tanto quanto qualquer outro webhead. Mas por que microdados? Porque se importar?

Existem duas classes principais de aplicativos que consomem HTML e, por extensão, microdados HTML5:

• Navegadores da Web

• Mecanismos de pesquisa

Para navegadores, HTML5 define um conjunto de APIs DOM para extrair itens de microdados, propriedades e
valores de propriedades de uma página da web. Enquanto escrevo isto, nenhum navegador oferece suporte a esta
API. Nem um único. Então isso é... meio que um beco sem saída, pelo menos até que os navegadores alcancem e
implementem as APIs do lado do cliente.

O outro grande consumidor de HTML são os motores de busca. O que um mecanismo de busca poderia fazer com
propriedades de microdados sobre uma pessoa? Imagine o seguinte: em vez de simplesmente exibir o título da
página e um trecho do texto, o mecanismo de busca poderia integrar algumas dessas informações estruturadas e
exibi-las. Nome completo, cargo, empregador, endereço, talvez até uma pequena miniatura de uma foto de perfil.
Isso chamaria sua atenção? Seria
pegue o meu.

O Google oferece suporte a microdados como parte de seu programa Rich Snippets. Quando o rastreador da Web
do Google analisa sua página e encontra propriedades de microdados que estão em conformidade com o vocabulário
http://data-vocabulary.org/Person , ele analisa essas propriedades e as armazena junto com o restante dos dados
da página. O Google ainda oferece uma ferramenta útil que mostra como o Google “vê” as propriedades de seus
microdados. Testando-o em nossa página “sobre” habilitada para microdados de amostra produz esta saída:

Tipo
de item : http://data-vocabulary.org/person
foto = http://diveintohtml5.org/examples/2000_05_mark.jpg nome =
Mark Pilgrim título =
Afiliação de defensor do
desenvolvedor = Google, Inc.
= http://diveintomark.org/
url = http://www.google.com/profiles/
pilgrim url = http://www.reddit.com/user/MarkPilgrim
url = http://www.twitter.com /mergulhar na marca

Item 1
Tipo: http://data-vocabulary.org/address street-
address = 100 Main Street localidade
= Anytown região =
PA código
postal = 19999 nome
do país = EUA

174 | Capítulo 10: “Distribuído”, “Extensibilidade” e outras palavras sofisticadas

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Está tudo lá: a propriedade photo do atributo <img src> , todos os quatro URLs da lista de
atributos <a href> e até mesmo o objeto de endereço (listado como “Item 1”) e todas as suas
cinco subpropriedades.

E como o Google usa todas essas informações? Depende. Não existem regras rígidas e rápidas
sobre como as propriedades dos microdados devem ser exibidas, quais devem ser exibidas ou
se devem ser exibidas. Se alguém pesquisar por “Mark Pilgrim” e o Google determinar que esta
página “sobre” deve ser classificada nos resultados, e o Google decidir que vale a pena exibir as
propriedades de microdados que ele encontrou originalmente naquela página, a listagem dos
resultados da pesquisa poderá ser semelhante à Figura 10-1.

Figura 10-1. Exemplo de resultado de pesquisa para uma listagem de pessoas aprimorada por microdados

A primeira linha, “Sobre Mark Pilgrim”, é na verdade o título da página, fornecido no elemento
<title> . Isso não é muito emocionante; O Google faz isso para todas as páginas. Mas a segunda
linha está repleta de informações retiradas diretamente das anotações de microdados que
adicionamos à página. “Anytown PA” fazia parte do endereço postal, marcado com o vocabulário
http://data-vocabulary.org/Address . “Defensor do desenvolvedor” e “Google, Inc.” eram duas
propriedades do vocabulário http://data-vocabulary.org/Person (título e afiliação, respectivamente).

Isso é realmente incrível. Você não precisa ser uma grande empresa fazendo acordos especiais
com fornecedores de mecanismos de pesquisa para personalizar suas listagens de resultados
de pesquisa. Reserve 10 minutos e adicione alguns atributos HTML para anotar os dados que
você já estava publicando.

Pergunte ao Professor Markup

P: Fiz tudo o que você disse, mas minha listagem de resultados de pesquisa no Google não parece diferente.

O que da?

R: “O Google não garante que a marcação em qualquer página ou site será usada na pesquisa
(http://www.google.com/support/webmasters/bin/answer.py?hl=pt-BR&answer=99170
resultados" ). Mas
mesmo que o Google decida não usar suas anotações de microdados, outro mecanismo de
busca poderá fazê-lo. Como o resto do HTML5, os microdados são um padrão aberto que
qualquer pessoa pode implementar. É seu trabalho fornecer o máximo de dados possível.
Deixe o resto do mundo decidir o que fazer com isso. Eles podem surpreendê-lo!

Marcando Pessoas | 175

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Marcando organizações
Os microdados não estão limitados a um único vocabulário. As páginas “Sobre” são legais, mas
provavelmente você só tem uma delas. Ainda está com fome de mais? Vamos aprender como marcar
organizações e negócios.

Criei uma página de exemplo de listagens de empresas. Vejamos a marcação HTML


original, sem microdados:
<artigo>
<h1>Google, Inc.</h1>

<p> 1600 Amphitheatre Parkway<br>


Mountain View, CA 94043<br>
EUA
</p>
<p>650-253-0000</
p> <p><a href="http://www.google.com/">Google.com</a></p>
</article >

Você pode acompanhar on-line as alterações feitas nesta seção. Antes:


http:// diveintohtml5.org/ examples/ organization.html; depois: http://
diveintohtml5.org/ examples/ organization-plus-microdata .html.

Curto e grosso. Todas as informações sobre a organização estão contidas no elemento <article> ,
então vamos começar por aí: <article
itemscope itemtype="http://data-vocabulary.org/Organization">

Assim como acontece com a marcação de pessoas, você precisa definir os atributos itemscope e
itemtype no elemento mais externo. Neste caso, o elemento mais externo é um elemento <article> .
O atributo itemtype declara o vocabulário de microdados que você está usando (neste caso, http:// data-
vocabulary.org/ Organization) e o atributo itemscope declara que todas as propriedades definidas em
elementos filhos estão relacionadas a esse vocabulário.

Então, o que há no vocabulário Organização? É muito simples e direto. Na verdade, algumas delas já
deveriam parecer familiares. A Tabela 10-3 lista as propriedades relevantes.

Tabela 10-3. Vocabulário organizacional

Propriedade Descrição

nome O nome da organização (por exemplo, “Initech”).

url Um link para a página inicial da organização.

endereço A localização da organização. Pode conter as subpropriedades rua, localidade, região,


código postal e nome do país.

telefone O número de telefone da organização.

localização geográfica
As coordenadas geográficas do local. Sempre contém duas subpropriedades, latitude e longitude.

176 | Capítulo 10: “Distribuído”, “Extensibilidade” e outras palavras sofisticadas

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

O primeiro bit de marcação dentro do elemento <article> mais externo é um <h1>. Este elemento <h1>
contém o nome de uma empresa, então colocaremos um atributo itemprop="name" diretamente nele:

<h1 itemprop="name">Google, Inc.</h1>

De acordo com a Tabela 10-1, os elementos <h1> não precisam de nenhum processamento especial.
O valor da propriedade de microdados é simplesmente o conteúdo de texto do elemento <h1> . Em
inglês, dissemos apenas: “O nome da Organização é 'Google, Inc.'”

O próximo é um endereço. Marcar o endereço de uma Organização funciona exatamente da mesma


forma que marcar o endereço de uma Pessoa. Primeiro, adicione um atributo itemprop="address" ao
elemento mais externo do endereço (neste caso, um elemento <p> ). Isso afirma que esta é a
propriedade de endereço da Organização.
Mas e as propriedades do próprio endereço? Também precisamos definir os atributos de tipo de item
e itemscope para dizer que este é um item de endereço que possui propriedades próprias:

<p itemprop="address"
itemscope itemtype="http://data-vocabulary.org/Address">

Finalmente, precisamos agrupar cada informação distinta em um elemento fictício <span>


para que possamos adicionar o nome apropriado da propriedade de microdados (endereço,
localidade, região, código postal e nome do país) em cada <span> elemento:
<p itemprop="address" itemscope
itemtype="http://data-vocabulary.org/Address">
<span itemprop="street-address">1600 Amphitheatre Parkway<br>
<span itemprop="locality ">Mountain View,
<span itemprop="region">CA
<span itemprop="postal-code">94043<br>
<span itemprop="country-name"> EUA </
p>

Em inglês, dissemos apenas: “Esta organização tem um endereço. A parte do endereço é '1600
Amphitheatre Parkway'. A localidade é 'Mountain View'. A parte da região é 'CA'.
O código postal é '94043'. O nome do país é ‘EUA’.”

A seguir: um número de telefone da Organização. Os números de telefone são notoriamente


complicados e a sintaxe exata é específica do país. (E se você quiser ligar para outro país, é ainda
pior.) Neste exemplo, temos um número de telefone dos Estados Unidos, em formato adequado para
ligar de qualquer outro lugar dos Estados Unidos:
<p itemprop="tel">650-253-0000</p>

(Ei, caso você não tenha notado, o vocabulário Endereço saiu do escopo quando seu elemento <p>
foi fechado. Agora voltamos a definir propriedades no vocabulário Organização.)

Se quiser listar vários números de telefone – talvez um para clientes nos Estados Unidos e outro para
clientes internacionais – você pode fazer isso. Qualquer propriedade de microdados pode ser

Marcando organizações | 177

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

repetido. Apenas certifique-se de que cada número de telefone esteja em seu próprio elemento HTML, separado
de qualquer rótulo que você possa fornecer:

<p>
Clientes dos EUA: <span itemprop="tel">650-253-0000<br>
Clientes do Reino Unido: <span itemprop="tel">00 + 1* + 6502530000 </p>

De acordo com a Tabela 10-1, nem o elemento <p> nem o elemento <span> possuem processamento especial. O
valor da propriedade tel de microdados é simplesmente o conteúdo do texto. O vocabulário de microdados da
Organização não tenta subdividir as diferentes partes de um número de telefone. Toda a propriedade tel é apenas
texto de formato livre. Se quiser colocar o código de área entre parênteses ou usar espaços em vez de travessões
para separar os números, você pode fazer isso. Se um cliente que consome microdados quiser analisar o número
de telefone, isso depende inteiramente dele.

A seguir, temos outra propriedade familiar: url. Assim como associar uma URL a uma Pessoa conforme descrito na
seção anterior, você pode associar uma URL a uma Organização.
Pode ser a página inicial da empresa, uma página de contato, uma página de produto ou qualquer outra coisa. Se
for um URL sobre, de ou pertencente à Organização, marque-o com um atributo itemprop="url" :

<p> <a itemprop="url" href="http://www.google.com/"> Google.com</a></p>

De acordo com a Tabela 10-1, o elemento <a> possui processamento especial. O valor da propriedade microdados
é o valor do atributo href , não o texto do link. Em inglês, diz: “Esta organização está associada ao URL http://
www.google.com/.” Não diz nada mais específico sobre a associação e não inclui o texto do link “Google.com”.

Por fim, quero falar sobre geolocalização. Não, não é a API de geolocalização do W3C (consulte o Capítulo 6).
Estou falando sobre como marcar a localização física de uma organização usando microdados.

Até o momento, todos os nossos exemplos se concentraram na marcação de dados visíveis . Ou seja, você tem um
<h1> com o nome de uma empresa, então você adiciona um atributo itemprop ao elemento <h1> para declarar que
o texto do cabeçalho (visível) é, de fato, o nome de uma Organização. Ou você tem um elemento <img> que aponta
para uma foto, então você adiciona um atributo itemprop ao elemento <img> para declarar que a imagem (visível)
é uma foto de uma Pessoa.

Neste exemplo, as informações de geolocalização não são assim. Não há nenhum texto visível que forneça a
latitude e longitude exatas (com quatro casas decimais!) da Organização. Na verdade, o exemplo de página da
organização sem microdados não tem nenhuma informação de geolocalização. Possui um link para o Google Maps,
mas mesmo o URL desse link não contém coordenadas de latitude e longitude. (Ele contém informações
semelhantes em um formato específico do Google.) Mesmo que tivéssemos um link para um hipotético serviço de
mapeamento on-line que usasse coordenadas de latitude e longitude como parâmetros de URL, os microdados não
teriam como separar as diferentes partes de um URL. . Você não pode declarar que a primeira consulta de URL

178 | Capítulo 10: “Distribuído”, “Extensibilidade” e outras palavras sofisticadas

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

parâmetro é a latitude, o segundo parâmetro de consulta de URL é a longitude e o restante dos


parâmetros de consulta são irrelevantes.

Para lidar com casos extremos como esse, o HTML5 fornece uma maneira de anotar dados invisíveis.
Esta técnica só deve ser usada como último recurso. Se houver uma maneira de exibir ou renderizar os
dados de seu interesse, você deverá fazê-lo. Dados invisíveis que apenas máquinas podem ler tendem
a “ficar obsoletos” muito rapidamente. Ou seja, é provável que alguém apareça mais tarde e atualize o
texto visível, mas esqueça de atualizar os dados invisíveis. Isso acontece com mais frequência do que
você pensa e acontecerá com você também.

Ainda assim, há casos em que os dados invisíveis são inevitáveis. Talvez seu chefe realmente queira
informações de geolocalização legíveis por máquina, mas não queira sobrecarregar a interface com
pares de números incompreensíveis de seis dígitos. Dados invisíveis são a única opção. A única graça
salvadora aqui é que você pode colocar os dados invisíveis imediatamente após o texto visível que eles
descrevem, o que pode ajudar a lembrar a pessoa que aparece mais tarde e atualiza o texto visível que
ela precisa atualizar os dados invisíveis logo após ele.

Neste exemplo, podemos criar um elemento <span> fictício dentro do mesmo elemento <article> que
todas as outras propriedades da Organização e, em seguida, colocar os dados de geolocalização
invisíveis dentro do elemento
<span>: <span itemprop="geo"
itemscope itemtype= "http://data-vocabulary.org/
Geo"> <meta itemprop="latitude" content="37.4149" /
> <meta itemprop="longitude" content="-122.078" /> </
article >

As informações de geolocalização são definidas em vocabulário próprio, como o endereço de uma


Pessoa ou Organização. Portanto, este elemento <span> precisa de três atributos:

itemprop="geo"
Diz que este elemento representa a propriedade geográfica da organização circundante.
itemtype="http://data-vocabulary.org/Geo"
Diz a qual vocabulário de microdados as propriedades deste elemento estão em

conformidade. itemscope Diz que este elemento é o elemento envolvente para um item de microdados
com seu próprio vocabulário (fornecido no atributo itemtype). Todas as propriedades dentro deste
elemento são propriedades do vocabulário Geo (http://data-vocabulary.org/Geo), e não do
vocabulário da Organização circundante (http://data-vocabulary.org/Organization).

A próxima grande questão que este exemplo responde é: “Como você anota dados invisíveis?” Você faz
isso com o elemento <meta>. Nas versões anteriores do HTML, você só podia usar o elemento <meta>
dentro do <head> da sua página (consulte “O elemento <head>” na página 34). No HTML5, você pode
usar o elemento <meta> em qualquer lugar. E é exatamente isso que estamos fazendo aqui:

<meta itemprop="latitude" content="37.4149" />

Marcando organizações | 179

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

De acordo com a Tabela 10-1, o elemento <meta> possui processamento especial. O valor da propriedade
microdados é o atributo de conteúdo . Como esse atributo nunca é exibido de forma visível, temos a
configuração perfeita para quantidades ilimitadas de dados invisíveis. Com grandes poderes vem grandes
responsabilidades. Nesse caso, é sua responsabilidade garantir que esses dados invisíveis permaneçam
sincronizados com o texto visível ao seu redor.

Não há suporte direto para o vocabulário Organização nos Rich Snippets do Google, então não tenho nenhum
exemplo bonito de listagem de resultados de pesquisa para mostrar a você. Mas as organizações aparecem
fortemente nos próximos dois estudos de caso, eventos e análises, e são apoiados pelo Google Rich Snippets.

Marcando eventos
Coisas acontecem. Algumas coisas acontecem em horários predeterminados. Não seria bom se você pudesse
dizer aos mecanismos de pesquisa exatamente quando as coisas estavam para acontecer? Existe um colchete
angular para isso.

Vamos começar examinando um exemplo de cronograma de minhas palestras:


<artigo>
<h1>Dia do Desenvolvedor Google 2009</
h1> <img width="300" height="200"
src="http://diveintohtml5.org/examples/gdd-2009-prague-pilgrim.jpg" alt="[ Mark
Pilgrim no pódio]">

<p> Os Google Developer Days são uma oportunidade de aprender


sobre os produtos para desenvolvedores do Google com os engenheiros
que os criaram. Esta conferência de um dia inclui seminários e
“horário comercial” sobre tecnologias da web como Google Maps,
OpenSocial, Android, APIs AJAX, Chrome e Google
Web

Toolkit. </p> <p> <time datetime="2009-11-06T08:30+01:00">2009 6 de novembro, 8h30</time>


&ndash;
<time datetime="2009-11-06T20:30+01:00">20:30</time> </p>
<p>

Centro de Congressos<br>
5th kvÿtna 65<br>
140 21 Praha 4<br>
República Tcheca
</p>
<p><a href="http://code.google.com/intl/cs/events/developerday/2009/home.html"> página inicial
do GDD/Praga</a></ p> </artigo>

Você pode acompanhar on-line as alterações feitas nesta seção. Antes: http://
diveintohtml5.org/ examples/ event.html; depois: http:// diveintohtml5.org/
examples/ event-plus-microdata.html.

180 | Capítulo 10: “Distribuído”, “Extensibilidade” e outras palavras sofisticadas

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Todas as informações sobre o evento estão contidas no elemento <article> , então isso é
onde precisamos colocar os atributos itemtype e itemscope :
<artigo itemscope itemtype="http://data-vocabulary.org/Event">

A URL para o vocabulário Evento é http:// data-vocabulary.org/ Event, que também contém um pequeno
gráfico que descreve as propriedades do vocabulário. E o que são
essas propriedades? A Tabela 10-4 os lista.

Tabela 10-4. Vocabulário de eventos

Propriedade Descrição

O nome do evento.
resumo
url Um link para a página de detalhes do evento.

localização O local ou local do evento. Opcionalmente, pode ser representado por uma organização aninhada (consulte “Marcando

Organizações” na página 176) ou Endereço (consulte “Marcando Pessoas” na página 171).

descrição Uma descrição do evento.

data de início A data e hora de início do evento no formato de data ISO.

data final A data e hora de término do evento no formato de data ISO.

duração A duração do evento no formato de duração ISO.

tipo de evento A categoria do evento (por exemplo, “Concerto” ou “Palestra”). Esta é uma string de formato livre, não uma enumerada
atributo.

localização geográfica
As coordenadas geográficas do local. Sempre contém duas subpropriedades, latitude e

longitude.

foto Um link para uma foto ou imagem relacionada ao evento.

O nome do Evento está em um elemento <h1> . De acordo com a Tabela 10-1, os elementos <h1> têm
nenhum processamento especial. O valor da propriedade microdados é simplesmente o conteúdo do texto do
elemento <h1> . Então, tudo o que precisamos fazer é adicionar o atributo itemprop para declarar que este
O elemento <h1> contém o nome do Evento:

<h1 itemprop="summary"> Dia do desenvolvedor do Google 2009</h1>

Em inglês, diz: “O nome deste evento é 'Google Developer Day 2009.'”

Este anúncio de evento possui uma foto, que pode ser marcada com a propriedade da foto . Como
como seria de esperar, a foto já está marcada com um elemento <img> . Como
a propriedade photo no vocabulário Person (consulte “A propriedade de dados de microdados
Modelo” na página 166), a propriedade Foto do evento é uma URL. Como a Tabela 10-1 diz que
o valor da propriedade de um elemento <img> é seu atributo src , a única coisa que precisamos fazer
é adicionar o atributo itemprop ao elemento <img> :
<img itemprop="foto" largura="300" altura="200"
src="http://diveintohtml5.org/examples/gdd-2009-prague-pilgrim.jpg"
alt="[Marcar Peregrino no pódio]">

Marcando eventos | 181

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Em inglês, diz: “A foto deste evento está em http:// diveintohtml5.org/ examples/ gdd-2009-prague-
pilgrim.jpg .”

A seguir está uma descrição mais longa do Evento, que é apenas um parágrafo de texto de formato livre:
<p itemprop="description">Os Google Developer Days são uma oportunidade
de aprender sobre os produtos para desenvolvedores do Google com os engenheiros
que os desenvolveram. Esta conferência de um dia inclui seminários e "horário
comercial" sobre tecnologias da web como Google Maps, OpenSocial,
Android, APIs AJAX, Chrome e Google Web Toolkit.</p>

A próxima parte é algo novo. Os eventos geralmente ocorrem em datas específicas e começam e
terminam em horários específicos. No HTML5, datas e horas devem ser marcadas com o elemento
<time> (veja “Datas e Horas” na página 49), e já estamos fazendo isso aqui.
Então a questão é: como adicionamos propriedades de microdados a esses elementos <time> ?
Olhando novamente para a Tabela 10-1, vemos que o elemento <time> tem processamento especial. O
valor de uma propriedade de microdados em um elemento <time> é o valor do atributo datetime . E ei,
as propriedades startDate e endDate do vocabulário Event levam uma data no estilo ISO, assim como
a propriedade datetime de um elemento <time> .
Mais uma vez, a semântica do vocabulário HTML central se encaixa perfeitamente com a semântica do
nosso vocabulário personalizado de microdados. Marcar datas de início e término com microdados é tão
simples quanto:

1. Usar HTML corretamente em primeiro lugar (usar elementos <time> para marcar datas
e tempos)

2. Adicionando um único atributo itemprop :

<p>
<time itemprop="startDate" datetime="2009-11-06T08:30+01:00">2009 6 de novembro, 8h30</time>
&ndash;
<time itemprop="endDate" datetime="2009-11-06T20:30+01:00">20:30</time> </p>

Em inglês, diz: “Este evento começa em 6 de novembro de 2009, às 8h30 da manhã, e vai até 6 de
novembro de 2009, às 20h30 (horário local de Praga, GMT+1).”

A seguir está a propriedade location . A definição do vocabulário de eventos diz que pode ser uma
Organização ou um Endereço. Neste caso, o Evento será realizado num local especializado em
conferências, o Centro de Congressos de Praga. Marcar como Organização permite-nos incluir o nome
do local, bem como o seu endereço.

Primeiro, vamos declarar que o elemento <p> que contém o endereço é a propriedade location do Evento,
e que este elemento também é seu próprio item de microdados que está em conformidade com o
vocabulário http://data-vocabulary.org/Organization : < p
itemprop="localização" itemscope
itemtype="http://data-vocabulary.org/Organization">

Em seguida, marque o nome da Organização envolvendo o nome em um elemento fictício <span> e


adicionando um atributo itemprop ao elemento <span> :
<span itemprop="name"> Centro de Congressos<br>

182 | Capítulo 10: “Distribuído”, “Extensibilidade” e outras palavras sofisticadas

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

"nome" define uma propriedade no vocabulário Organização, não no vocabulário Evento.


O elemento <p> definiu o início do escopo das propriedades da Organização, e esse elemento <p>
ainda não foi fechado com uma tag </p> . Quaisquer propriedades de microdados que definimos aqui
são propriedades do vocabulário com escopo mais recente. Vocabulários aninhados são como uma
pilha. Ainda não estouramos a pilha, então ainda estamos falando sobre propriedades da Organização.

Na verdade, vamos adicionar um terceiro vocabulário à pilha – um endereço para a organização do


evento: <span
itemprop="address" itemscope
itemtype="http://data-vocabulary.org/Address">

Mais uma vez, queremos marcar cada parte do endereço como uma propriedade de microdados
separada, então precisamos de uma série de elementos <span> fictícios para pendurar nossos
atributos itemprop (se estou indo rápido demais para você aqui, volte e leia sobre como marcar o
endereço de uma Pessoa (consulte “Marcando Pessoas” na página 171) e como marcar o endereço de uma Pessoa.
Organização (consulte “Marcando organizações” na página 177)): <span
itemprop="street-address">5th kvÿtna 65<br> <span
itemprop="postal-code">140 21 <span
itemprop="locality">Praha 4<br> <span
itemprop="country-name"> República Tcheca

Não há mais propriedades do Endereço, então fechamos o elemento <span> que iniciou o escopo do
Endereço e abrimos a pilha:

Também não há mais propriedades da Organização, então fechamos o elemento <p> que iniciou o
escopo da Organização e abrimos a pilha novamente:
</p>

Agora voltamos a definir propriedades no Event. A próxima propriedade é geo, para representar a
localização física do Evento. Isso usa o mesmo vocabulário geográfico que usamos para marcar a
localização física de uma organização na seção anterior. Precisamos de um elemento <span> para
atuar como contêiner; ele obtém o itemtype e o itemscope nos tributos. Dentro desse elemento
<span> , precisamos de dois elementos <meta> , um para a propriedade latitude e outro para a
propriedade longitude :
<span itemprop="geo" itemscope itemtype="http://data-vocabulary.org/Geo">
<meta itemprop="latitude" content="50.047893" />
<meta itemprop="longitude" content="14.4491" />

Como fechamos o <span> que continha as propriedades Geo, voltamos a definir as propriedades do
Evento. A última propriedade é a propriedade url , que deve parecer familiar. Associar uma URL a um
Evento funciona da mesma maneira que associar uma URL a uma Pessoa (consulte “Marcando
Pessoas” na página 173) e associar uma URL a uma Organização (consulte “Marcando Organizações”
na página 178). Se você estiver usando HTML

Marcando eventos | 183

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

corretamente (marcando hiperlinks com <a href>), declarar que o hiperlink é uma propriedade de url mi crodata é
simplesmente uma questão de adicionar o atributo itemprop :

<p> <a itemprop="url"


href="http://code.google.com/intl/cs/events/developerday/2009/home.html"> página inicial
do GDD/Praga </a> </p
> </

artigo>

A página de evento de exemplo também lista um segundo evento, minha palestra na conferência ConFoo em
Montreal. Para ser breve, não vou passar por essa marcação linha por linha. É essencialmente o mesmo que o
evento em Praga: um item de evento com itens geográficos e de endereço aninhados. Menciono isso apenas de
passagem para reiterar que uma única página pode ter vários eventos, cada um marcado com microdados.

O retorno dos rich snippets do Google


De acordo com a ferramenta de teste de Rich Snippets do Google, estas são as informações que os rastreadores
do Google coletarão em nosso exemplo de página de listagem de eventos:
Tipo
de item : http://data-vocabulary.org/Resumo do
evento = Dia do desenvolvedor do Google
2009 eventType = foto da
conferência = http://diveintohtml5.org/examples/gdd-2009-prague-pilgrim.jpg description
= Os dias do desenvolvedor do Google são uma chance de aprender sobre o desenvolvedor do Google
produtos dos engenheiros que os construíram. Esta conferência de um
dia inclui seminários e horário comercial sobre tecnologias da web como Goo...
startDate =
2009-11-06T08:30+01:00 endDate =
2009-11-06T20:30+01:00 location =
Item(__1) geo = Item
(__3) url = http://
code.google.com/intl/cs/events/developerday/2009/home.html

ID
do item:
__1 Tipo: http://data-vocabulary.org/Nome da organização
= Endereço do Centro de
Congressos = Item (__2)

Item
Id: __2
Tipo: http://data-vocabulary.org/Address street-
address = 5th kvÿtna 65 código postal
= 140 21 localidade =
Praha 4 nome do país
= República Tcheca

Item
Id: __3

184 | Capítulo 10: “Distribuído”, “Extensibilidade” e outras palavras sofisticadas

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Tipo: http://data-vocabulary.org/Geo
latitude = 50,047893
longitude = 14,4491

Como você pode ver, todas as informações que adicionamos nos microdados estão lá. Propriedades que são
itens de microdados separados recebem IDs internos (Item(__1), Item(__2) e assim por diante), mas isso não
faz parte da especificação de microdados. É apenas uma convenção que a ferramenta de teste do Google usa
para linearizar a saída da amostra e mostrar o agrupamento de itens aninhados e suas propriedades.

Então, como o Google poderia escolher representar esta página de exemplo em seus resultados de pesquisa?
(Novamente, devo começar com a isenção de responsabilidade de que este é apenas um exemplo; o Google
pode alterar o formato de seus resultados de pesquisa a qualquer momento e não há garantia de que o Google
prestará atenção à sua marcação de microdados.) Pode ser que isso aconteça. semelhante à Figura 10-2.

Figura 10-2. Exemplo de resultado da pesquisa para uma listagem de eventos aprimorada por microdados

Após o título da página e o texto do trecho gerado automaticamente, o Google começa a usar a marcação de
microdados que adicionamos à página para exibir uma pequena tabela de eventos. Observe o formato da data:
“Sexta-feira, 6 de novembro”. Essa não é uma string que apareceu em qualquer lugar de nossa marcação HTML
ou de microdados. Usamos duas strings totalmente qualificadas no formato ISO, 2009-11-06T08:30+01:00 e
2009-11-06T20:30+01:00. O Google pegou essas duas datas, descobriu que eram no mesmo dia e decidiu
exibir uma única data em um formato mais amigável.

Agora observe os endereços físicos. O Google optou por exibir apenas o nome
do local + localidade + país, não o endereço exato. Isso é possível porque
dividimos o endereço em cinco subpropriedades – nome, endereço, região,
localidade e nome do país – e marcamos cada parte do endereço como uma
propriedade de microdados diferente. O Google aproveita isso para mostrar um endereço abreviad
Outros consumidores da mesma marcação de microdados podem fazer escolhas diferentes sobre o que exibir
ou como exibi-lo. Não há escolha certa ou errada aqui. Cabe a você fornecer o máximo de dados possível, com
a maior precisão possível. Cabe ao resto do mundo interpretá-lo.

Marcando avaliações
Aqui está outro exemplo de como tornar a Web (e possivelmente as listagens de resultados de pesquisa) melhor
por meio de marcação: análises de empresas e produtos.

Marcando avaliações | 185

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Esta é uma breve resenha que escrevi sobre minha pizzaria favorita perto da minha casa. (A propósito,
este é um restaurante de verdade. Se você estiver em Apex, NC, eu o recomendo fortemente.) Vejamos a
marcação original:
<article>
<h1>Anna's Pizzeria</h1>
<p>ÿÿÿÿÿ (4 estrelas de 5)</p> <p>Pizza
estilo nova-iorquino bem no centro histórico de Apex</p> <p > A

comida é de primeira qualidade. A atmosfera é perfeita para uma "pizzaria


de bairro". O restaurante em si é um pouco apertado; se você estiver
acima do peso, poderá ter dificuldade para entrar e sair da cadeira e
navegar entre outras mesas. Usado para dar nós de alho soltos
quando você se sentava; agora eles te dão pão simples e você tem que
pagar pelas coisas boas. No geral, é um vencedor. </p> <p> 100 North

Salem Street<br> Apex, NC


27502<br> EUA </
p>
<p>
— revisado por Mark Pilgrim, última atualização em 31 de março de
2010</p> </article>

Você pode acompanhar on-line as alterações feitas nesta seção. Antes: http://
diveintohtml5.org/ examples/ review.html; depois: http:// diveintohtml5.org/
examples/ review-plus-microdata.html.

Esta revisão está contida em um elemento <article> , então é onde colocaremos os atributos itemtype e
itemscope . Aqui está o URL do namespace para este vocabulário:

<artigo itemscope itemtype="http://data-vocabulary.org/Review">

Quais são as propriedades disponíveis no vocabulário Review? Estou feliz que você perguntou. Eles estão
listados na Tabela 10-5.

Tabela 10-5. Revise o vocabulário

Descrição

Propriedade itemreviewed O nome do item que está sendo revisado. Pode ser um produto, serviço, negócio, etc.

avaliação Uma classificação numérica de qualidade para o item, em uma escala de 1 a 5. Também pode ser uma classificação

aninhada usando o vocabulário http://data-vocabulary.org/Rating para usar uma escala não padronizada.

revisor O nome do autor que escreveu a resenha.

revisado A data em que o item foi revisado no formato de data ISO.

resumo Um breve resumo da revisão.

descrição O corpo da revisão.

186 | Capítulo 10: “Distribuído”, “Extensibilidade” e outras palavras sofisticadas

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

A primeira propriedade é simples: itemreviewed é apenas texto, e aqui está contido em um


elemento <h1> , então é onde devemos colocar o atributo itemprop : <h1
itemprop="itemreviewed">Anna's Pizzeria</h1>

Vou pular a classificação real e voltar a ela no final.

As próximas duas propriedades também são diretas. A propriedade summary é uma breve
descrição do que você está revisando, e a propriedade description é o corpo da revisão:

<p itemprop="summary"> Pizza estilo nova-iorquino bem no centro histórico de Apex</


p> <p itemprop="description">
A comida é de primeira qualidade. A atmosfera é perfeita para uma
"pizzaria de bairro". O restaurante em si é um pouco apertado; se você
estiver acima do peso, poderá ter dificuldade para entrar e sair da
cadeira e navegar entre outras mesas. Usado para dar nós de
alho soltos quando você se sentava; agora eles te dão pão simples
e você tem que pagar pelas coisas boas. No geral, é um vencedor. </
p>

As propriedades de localização e geográfica não são nada que não tenhamos abordado antes
(consulte as seções anteriores sobre marcação do endereço de uma Pessoa, marcação do
endereço de uma Organização e marcação de informações de geolocalização):
<p itemprop="location" itemscope
itemtype="http://data-vocabulary.org/Address">
<span itemprop="street-address"> Rua North Salem, 100<br> <span
itemprop=" localidade">Apex, <span
itemprop="region">NC <span
itemprop="postal-code">27502<br> <span
itemprop="country-name"> EUA </p>

<span itemprop="geo"
itemscope itemtype="http://data-
vocabulary.org/Geo"> <meta itemprop="latitude"
content="35.730796" /> <meta itemprop ="longitude"
content="-78.851426" />

A linha final apresenta um problema familiar: contém dois bits de informação em um elemento. O
nome do revisor é Mark Pilgrim e a data da revisão é 31 de março de 2010. Como marcamos
essas duas propriedades distintas? Como sempre, podemos envolvê-los em seus próprios
elementos (veja “Marcando Pessoas” na página 171) e colocar um atributo itemprop em cada
elemento. Na verdade, a data neste exemplo deveria ter sido marcada com um elemento <time>
em primeiro lugar, de modo que fornece um gancho natural para pendurar nosso atributo
itemprop . O nome do revisor pode ser simplesmente colocado em um elemento fictício <span> :

<p> <span itemprop="reviewer">Mark Pilgrim, última atualização


<time itemprop="dtreviewed" datetime="2010-03-31">
31 de março de
2010 </time>

Marcando avaliações | 187

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

</p>
</artigo>

OK, vamos falar de classificações. A parte mais complicada de marcar uma avaliação é a classificação. Por
padrão, as classificações no vocabulário Revisão estão em uma escala de 1 a 5, sendo 1 “terrível” e 5
“incrível”. Se quiser usar uma escala diferente, você definitivamente pode fazer isso. Mas vamos falar primeiro
sobre a escala padrão:

<p>ÿÿÿÿÿ (<span itemprop="rating">4 estrelas de 5)</p>

Se você estiver usando a escala padrão de 1 a 5, a única propriedade que você precisa marcar é a própria
classificação (4, neste caso). Mas e se você quiser usar uma escala diferente? Você pode fazer isso; você só
precisa declarar os limites da escala que está usando. Por exemplo, se você quisesse usar uma escala de 0 a
10, ainda assim declararia a propriedade itemprop="rating" , mas em vez de fornecer o valor da classificação
diretamente, usaria uma classificação aninhada com o vocabulário de http:// data-vocabulary.org/Rating para
declarar os piores e melhores valores em sua escala personalizada e o valor real da classificação dentro dessa
escala:
<p itemprop="rating" itemscope
itemtype="http://data-vocabulary.org/Rating">
ÿÿÿÿÿÿÿÿÿÿ (<span
itemprop="value">9 em um escala de <span
itemprop="worst">0 a <span
itemprop="best">10) </p>

Em inglês, diz: “O produto que estou analisando tem uma classificação de 9 em uma escala de
0–10.”

Mencionei que os microdados de revisão podem afetar as listagens de resultados de pesquisa? Ah, sim, pode.
Aqui estão os “dados brutos” que a ferramenta Google Rich Snippets extraiu da minha análise aprimorada
de microdados:
Item
Tipo: http://data-vocabulary.org/Review
itemreviewed = Classificação da
Anna's
Pizzeria = 4 summary = Pizza estilo nova-iorquino bem no centro histórico
Descrição do Apex = A comida é de primeira qualidade. A atmosfera é
perfeita ... endereço =
Item (__1) geo =
Item (__2) revisor = Mark
Pilgrim dtreviewed = 31/03/2010

ID
do item:
__1 Tipo: http://data-vocabulary.org/Organization
endereço = 100 North Salem Street
localidade =
região Apex
= código postal NC =
27502 nome do país = EUA

Item

188 | Capítulo 10: “Distribuído”, “Extensibilidade” e outras palavras sofisticadas

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Id: __2
Tipo: http://data-vocabulary.org/Geo
latitude = 35,730796
longitude = -78,851426

A Figura 10-3 (módulo os caprichos do Google, a fase da lua e assim por diante) mostra como minha
avaliação ficaria em uma listagem de resultados de pesquisa.

Figura 10-3. Exemplo de resultado de pesquisa para uma listagem de revisão aprimorada por microdados

Os colchetes angulares não me impressionam muito, mas tenho que admitir, isso é muito legal.

Leitura adicional
Recursos de microdados:

• Playground de microdados ao
vivo • Especificação de microdados HTML5

Recursos do Google Rich Snippets: •

“Sobre rich snippets e dados estruturados” • “Pessoas”


• “Empresas
e organizações”
• “Eventos”
• “Avaliações”

• “Avaliar classificações”
• Ferramenta de teste de rich snippets do
Google • Dicas e truques para rich snippets do Google

Leitura adicional | 189

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

APÊNDICE

O multifuncional quase alfabético


Guia para detectar tudo

Confuso? Leia o Capítulo 2 para uma introdução conceitual. Quer uma biblioteca multifuncional? Experimente o Modernizr.

Lista de Elementos

<áudio> http://bit.ly/cZxI7K

return !!document.createElement('audio').canPlayType;

<áudio> em formato MP3 http://en.wikipedia.org/wiki/MP3

var a = document.createElement('áudio');
return !!(a.canPlayType && a.canPlayType('audio/mpeg;').replace(/no/, ''));

<áudio> no formato Vorbis http://en.wikipedia.org/wiki/Vorbis

var a = document.createElement('áudio');
return !!(a.canPlayType && a.canPlayType('audio/
ogg; codecs="vorbis"').replace(/no/, ''));

191

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

<áudio> em formato WAV http://en.wikipedia.org/wiki/WAV

var a = document.createElement('áudio');
retornar !!(a.canPlayType && a.canPlayType('audio/
wav; codecs="1"').replace(/no/, ''));

<áudio> no formato AAC http://en.wikipedia.org/wiki/Advanced_Audio_Coding

var a = document.createElement('áudio');
retornar !!(a.canPlayType && a.canPlayType('audio/
mp4; codecs="mp4a.40.2"').replace(/no/, ''));

<tela> Consulte o Capítulo 4

return !!document.createElement('canvas').getContext;

API de texto <canvas> Consulte “Texto” na página 63

var c = document.createElement('canvas');
return c.getContext && typeof c.getContext('2d').fillText == 'função';

<comando> http://bit.ly/aQt2Fn

retorne 'tipo' em document.createElement('command');

<lista de dados> http://bit.ly/9WVz5p

retorne 'opções' em document.createElement('datalist');

<detalhes> http://bit.ly/cO8mQy

retorne 'aberto' em document.createElement('details');

<dispositivo> http://bit.ly/aaBeUy

retorne 'tipo' em document.createElement('device');

192 | Apêndice: O guia quase alfabético completo para detectar tudo

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

validação de restrição <form> http://bit.ly/cb9Wmj

retorne 'noValidate' em document.createElement('form');

<caixa de areia iframe> http://blog.whatwg.org/whats-next-in-html-episode-2-sandbox

retornar 'sandbox' em document.createElement('iframe');

<iframe srcdoc> http://blog.whatwg.org/whats-next-in-html-episode-2-sandbox

retorne 'srcdoc' em document.createElement('iframe');

Consulte “Campos de foco automático” na página 148


<foco automático de entrada>

retorne 'autofoco' em document.createElement('input');

Consulte “Texto de espaço reservado” na página 147


<espaço reservado de entrada>

retornar 'espaço reservado' em document.createElement('input');

<input type="cor"> http://bit.ly/9HkeNn

var i = document.createElement('input');
i.setAttribute('tipo', 'cor');
return i.type !== 'texto';

Consulte “Endereços de e-mail” na página 150


<input type="e-mail">

var i = document.createElement('input');
i.setAttribute('tipo', 'e-mail');
return i.type !== 'texto';

Consulte “Números como caixas giratórias” na página 153


<tipo de entrada = "número">

var i = document.createElement('input');
i.setAttribute('tipo', 'número');
return i.type !== 'texto';

Lista de Elementos | 193

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

<input type="intervalo"> Consulte “Números como controles deslizantes” na página 155

var i = document.createElement('input');
i.setAttribute('tipo', 'intervalo');
return i.type !== 'texto';

<input type="pesquisar"> Consulte “Caixas de pesquisa” na página 158

var i = document.createElement('input');
i.setAttribute('tipo', 'pesquisar');
return i.type !== 'texto';

<input type="tel"> http://bit.ly/bZm0Q5

var i = document.createElement('input');
i.setAttribute('tipo', 'tel'); return
i.type !== 'texto';

<input type="url"> Consulte “Endereços da Web” na página 151

var i = document.createElement('input');
i.setAttribute('tipo', 'url'); return
i.type !== 'texto';

<input type="data"> Consulte “Seletores de data” na página 156

var i = document.createElement('input');
i.setAttribute('tipo', 'data');
return i.type !== 'texto';

<input type="tempo"> Consulte “Seletores de data” na página 156

var i = document.createElement('input');
i.setAttribute('tipo', 'hora');
return i.type !== 'texto';

194 | Apêndice: O guia quase alfabético completo para detectar tudo

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

<input type="datahora"> Consulte “Seletores de data” na página 156

var i = document.createElement('input');
i.setAttribute('tipo', 'datahora');
return i.type !== 'texto';

<input type="datetime-local"> Consulte “Seletores de data” na página 156

var i = document.createElement('input');
i.setAttribute('tipo', 'datahora-local);
return i.type !== 'texto';

<input type="mês"> Consulte “Seletores de data” na página 156

var i = document.createElement('input');
i.setAttribute('tipo', 'mês');
return i.type !== 'texto';

<input type="semana"> Consulte “Seletores de data” na página 156

var i = document.createElement('input');
i.setAttribute('tipo', 'semana');
return i.type !== 'texto';

<metro> http://bit.ly/c0pX0l

retornar 'valor' em document.createElement('meter');

<saída> http://bit.ly/asJaqH

retornar 'valor' em document.createElement('output');

<progresso> http://bit.ly/bjDMy6

retorne 'valor' em document.createElement('progress');

Lista de Elementos | 195

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

<hora> http://bit.ly/bI62jp

retorne 'valueAsDate' em document.createElement('time');

<vídeo> Consulte o Capítulo 5

retornar !!document.createElement('video').canPlayType;

<vídeo> legendas http://bit.ly/9mLiRr

retorne 'track' em document.createElement('track');

<poster de vídeo> http://bit.ly/b6RhzT

retorne 'poster' em document.createElement('video');

<vídeo> no formato WebM http://www.webmproject.org

var v = document.createElement('vídeo');
retornar !!(v.canPlayType && v.canPlayType('video/webm; codecs="vp8,
vorbis"').replace(/no/, ''));

<vídeo> no formato H.264 Consulte “H.264” na página 84

var v = document.createElement('vídeo');
retornar !!(v.canPlayType && v.canPlayType('video/mp4; codecs="avc1.42E01E,
mp4a.40.2"').replace(/no/, ''));

<vídeo> no formato Theora Veja “Theora” na página 84

var v = document.createElement('vídeo');
retornar !!(v.canPlayType && v.canPlayType('video/ogg; codecs="theora,
vorbis"').replace(/no/, ''));

conteúdoEditável http://bit.ly/aLivbS

retorne 'isContentEditable' em document.createElement('span');

196 | Apêndice: O guia quase alfabético completo para detectar tudo

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Mensagens entre documentos http://bit.ly/cUOqXd

return !!window.postMessage;

Arraste e solte http://bit.ly/aN0RFQ

retorne 'arrastável' em document.createElement('span');

API de arquivo http://dev.w3.org/2006/webapi/FileAPI/

return typeof FileReader! = 'indefinido';

Geolocalização Consulte o Capítulo 6

return !!navigator.geolocalização;

História http://bit.ly/9JGAGB

retornar !!(window.history && window.history.pushState &&


janela.history.popState);

Armazenamento local http://dev.w3.org/html5/webstorage/

return ('localStorage' na janela) && window['localStorage'] !== null;

Microdados http://bit.ly/dBGnqr

retornar !!document.getItems;

Aplicativos da web off-line Consulte o Capítulo 8

retornar !!window.applicationCache;

Lista de Elementos | 197

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Eventos enviados pelo servidor http://dev.w3.org/html5/eventsource/

return typeof EventSource! == 'indefinido';

Armazenamento de sessão http://dev.w3.org/html5/webstorage/

tentar {
return ('sessionStorage' na janela) && window['sessionStorage'] !== null;
} pegar(e) {
retorna falso;
}

SVG http://www.w3.org/TR/SVG/

retornar !!(document.createElementNS && document.createElementNS


('http://www.w3.org/2000/svg', 'svg').createSVGRect);

SVG em texto/html http://hacks.mozilla.org/2010/05/firefox-4-the-html5-parser-inline-svg-speed-and-more/

var e = document.createElement('div');
e.innerHTML = '<svg></svg>';
retornar !!(window.SVGSVGElement && e.firstChild instanceof window.SVGSVGElement);

WebSimpleDB http://dev.w3.org/2006/webapi/WebSimpleDB/

retornar !!window.indexedDB;

Soquetes da Web http://dev.w3.org/html5/websockets/

retornar !!window.WebSocket;

Banco de dados SQL da Web http://dev.w3.org/html5/webdatabase/

retornar !!window.openDatabase;

198 | Apêndice: O guia quase alfabético completo para detectar tudo

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Trabalhadores da Web http://bit.ly/9jheof

retornar !!janela.Worker;

Desfazer http://bit.ly/bs6JFR

return typeof UndoManager !== 'indefinido';

Leitura adicional

Especificações e padrões:

•HTML5

• Geolocalização
• Eventos enviados pelo servidor

• WebSimpleDB • Web
Sockets

• Banco de dados Web SQL

• Armazenamento
na Web • Web Workers

Bibliotecas JavaScript:

• Modernizr, uma biblioteca de detecção HTML5

Leitura adicional | 199

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Índice

breadcrumbs, relações de link, 39


A
navegadores
AAC (codificação de áudio avançada), 87
com suporte para áudio e vídeo,
Modo quase padrão, 32 relações de
88 suporte para foco automático,
link alternativo, 37
28, 149 suporte para
APIs
tela, 16 suporte para texto em
API canvas, 16–18 API
tela, 17 tipos de documento e
de texto canvas, 17
modos, 31 tratamento
ExplorerCanvas, 74 geo.js,
de erros, 13 suporte para
123 API de
geolocalização, 24 manipulação de elementos
geolocalização, 24, 117–120 API de
desconhecidos, 42–45 cabeçalhos, 1
banco de dados indexado, 135 Web
Tipos de entrada HTML5, 26
Worker, 23 aplicativos
Suporte HTML5, 15
de
JavaScript, 23
armazenamento local, 127–
armazenamento local,
136 aplicativos web offline, 23, 137 –146 arquivos,
132 suporte a microdados, 29
relações de link, 38 elemento de
Internet Explorer, 73, 114, 123
artigo, 41, 47 elemento de
Midas, 3
lado, 41 codecs de
Mosaico, 3
áudio sobre, 85–
suporte offline, 24 suporte
88 codificação de
para espaço reservado, 27
vídeo Ogg Vorbis, 91–99 formato de contêiner
suporte para texto de espaço reservado, 148
de vídeo Audio Video Interleave, 82
Suporte a banco de dados SQL, 134

autores, relações de link, 38 foco


automático, formulários da web, 27, 148
atributo de reprodução automática, 110 Manifesto de cache C , aplicativos da web offline, 138–141,
143 função
canPlayType(), 20
B
tela
compatibilidade com versões
aproximadamente,
anteriores,
16–18 coordenadas,
11 XHTML,
60 texto de desenho, 63–
codificação de 12
66 imagens, 70–
lotes, codec de vídeo H.264,
73 caminhos, 61–
107 codec de vídeo Ogg Vorbis, 98
63 elemento de tela, 57

Gostaríamos de ouvir suas sugestões para melhorar nossos índices. Envie um e-mail para index@oreilly.com.

201

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

API de texto de tela, elemento de artigo, 41, 47


codificação de 17 caracteres, elemento de lado, 41
35 elemento de tela, 16, 57
codecs sobre, elemento de dd, 170
20 áudio, 85–88, 91–99 elemento de rodapé, 41, 52
vídeo, 83, 90, 100–109 manipulação de elementos desconhecidos, 42–
seletores de cores, formulários da web, 45 elemento de cabeça, 34–
160 comentários condicionais, 74 40 elemento de cabeçalho,
contêineres, vídeo, 81 41 elemento hgroup, 41
Cabeçalho Content-Type, 1 elemento img, 2, 8, 70
cookie, comparado ao armazenamento HTML5, 21 relações de link, 37
coordenadas, tela, 60 elemento de marca, 41
vocabulários personalizados, microdados, 164 elemento de
navegação, 41
elemento raiz, 33 elemento
de seção, 41 elemento de
Seletores de data D , formulários da origem, 112 elemento
web, 156 datas e horas, de tempo, 41 elemento de
49 elementos dd, 170 vídeo, 18–21
depuração de aplicativos da web off-line, 142–144 suporte endereços de e-mail validados em
para JavaScript, 160
detecção de foco automático, formulários da web,
28 suporte para telas, 16 150
suporte para texto em tela, 17 tratamento de
suporte para geolocalização, 24 erros sobre, 11 navegadores, 13 geolocalização, 120
Tipos de entrada HTML5, 26 eventos
Suporte a HTML5, suporte Eventos DOM, 141
a 15 microdados, suporte a marcação, 180–185 eventos
29 offline, suporte a 24 de armazenamento, 131
espaços reservados, 27 tipos exemplos
de documentos, 31 geo.js, 125
DOM (Document Object Model) sobre, 15 jogo Halma, 75–79, 132, 145 Video for
detecção de
Everybody!, 114 ExplorerCanvas,
suporte a tela, 16 detecção de suporte 74 relações de link externo,
a texto em tela, 17 vídeo, 19, 20 38

Eventos DOM, 141


desenhos, 57–79
coordenadas da tela, 60 Seção de fallback F , manifesto de cache,

gradientes, 67 descoberta automática de 140


Exemplo de jogo Halma, 75–79 feeds, 37 ffmpeg2theora,
foco
imagens, 70–73
caminhos, 61–63 automático de 98

formas, 58 campos, 148 endereços de e-mail, 150


textos, 63–66 Fogo de Fogo, 91-98
Formato de contêiner de vídeo Flash Video, 82
FlowPlayer, 114
tamanhos de
E elementos fonte, 65 elementos de
sobre, 163 rodapé, 41 rodapés, 52

202 | Índice

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

formatos, vídeo, 19 história anterior ao HTML5, 128 usando,


formulários (ver formulários web) 130–132

EU

Plug-in G Gears, 128 Suporte para áudio e vídeo


geo.js, 123–125 IE (Internet Explorer), 89 telas e
geolocalização, 117–126 suporte VML, 73 geolocalização, 123
sobre, 24 estilos de elementos
API, 117–120 desconhecidos, 42 suporte para vídeo,
tratamento de erros, 120 114 imagens, exibição,
geo.js, 123–125 70–73 elemento img, 2, 8, 70
métodos para calcular localização, 121 usando
dados invisíveis, 178 vocabulário , API de banco de dados indexado,

179 função 135 tipos de


getCurrentPosition(), 118, 120, 122, 124 entrada, 25
formulários da web,

Google 147 iPhone, formulários da web, 151


Em2, 85
Trechos avançados, 174, 184 J.

GPS (Sistema de Posicionamento Global), 121


Foco
gradientes, desenho, 67
automático
JavaScript, 27 em execução em segundo plano, 23
H

Codec de vídeo H.264, 84, 90, 100–108 Exemplo


de jogo Halma, 75–79, 132, 145 HandBrake, codec
Linguagem L ,
de vídeo H.264, 100–108 elemento de cabeça, 34–40
34 bibliotecas, Modernizr, 16
elemento de cabeçalho, 41
relações de link de licença, 39
cabeçalhos sobre, 45 –47
licenciamentos, codec de vídeo H.264, 90
Content-
relações de link, 36–40
Type, 1 elemento
armazenamento local (consulte Armazenamento HTML5)
hgroup, 41 histórico
LSOs (Objetos Compartilhados Locais), 128
HTML, 7–11 HTML5, ix

armazenamento local
antes de Formato de endereço de
HTML5, 128 desenvolvimento de padrões, 2–7 correspondência M ,
XHTML, 10 XML, 10 HTML elemento de
marca 172, 41
microdados sobre, 28, modo de dados 164, 165–168
Suporte para áudio e vídeo do
visões concorrentes, 11 Microsoft Internet Explorer, 89
história de desenvolvimento, suporte para canvas e VML, 73 para
estrutura de 7 a 11 páginas, 33 geolocalização, 123
Grupo de Trabalho HTML, 9 para estilizar elementos desconhecidos,
Armazenamento HTML5, 127–136 42 para suporte a vídeo, 114
sobre, 21, 129 Navegador Midas, 3
futuro de, 134 Tipos MIME
Exemplo de jogo Halma, 132 sobre, 1

Índice | 203

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

importância de, 10 vídeo,


R
113
tamanhos de fonte relativos,
HTML, 9, 10
65 revisões, marcação, 185–189
Modernizar, 16
Rich Snippets, 174, 184 elemento
Navegador mosaico, 3
raiz, 33
MP3 (camada de áudio MPEG-1 3), 86
Formato de contêiner de vídeo MPEG-4, 82

N Escopo S , microdados, 164

microdados de scripts, 11 caixas

namespaces, 165 de pesquisa, formulários da web, 158

necessidades, relações de links de pesquisa,

33 elementos de 40 elementos de seção, 41

navegação, 41 formas, desenho, 58 relações

navegação de links de barra lateral, 40

sobre, 51 migalhas de pão, 39 controles deslizantes, números

seção de rede, manifesto de cache, relação de link como, 155 elementos de

139 nofollow, relação de link 39 origem, 112 caixas giratórias, números como, 153

noreferrer, 39 números, formulários Suporte a banco de dados SQL, 134


padrões
da web, 153–156
História HTML, 7–9
implementações e especificações, 1 processo de
criação, 2–7
Objetos O , DOM, 15
Modo padrão, 32
aplicativos da web offline, 137–146 sobre, 23
armazenamento (consulte Armazenamento HTML5)
manifesto de
Objetos StorageEvent, relação de
cache, 138–141 depuração, 142–
link de folha de estilo 131, 37
144 fluxo de eventos, 141

Exemplo de jogo Halma, 145


Formato de contêiner de vídeo Ogg, 82 Relação de link de tag T , 40

Codec de áudio Ogg Vorbis, 87, 91–99 conjuntos de tags, XML, 9


texto
organizações, marcação, 176–180
API de texto de tela,

P codificação de 17 caracteres, 35
desenhos, 63–66 texto
de espaço reservado, 27, 147
caminhos sobre,
Codec de vídeo Theora, 84
145 telas, 61–63
elementos de tempo,
pessoas, marcação, 168–175 relação de
41 horários e datas, 49
link de pingback, 39 texto de espaço
alterações de rastreamento na área de armazenamento HTML5,
reservado sobre, 27
131 traduções, links, 38
formulários
da web, 147 relação
EM
de link de pré-busca, 40 atributo de
pré-carregamento, 110 data de
publicação, 49 Microdados de URLs, 166
Vocabulário pessoal, 173
formulários da web, 151
P
Modo peculiaridades, 32

204 | Índice

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Consórcio World Wide Web (ver W3C)


V
validação de endereços de e-mail em JavaScript,
X
160 vídeo, 81–
115 sobre, 18– XForms, compatibilidade com versões anteriores, 12
21 codecs de áudio, 85–88, 91– HTML
99 suporte a navegador, sobre, 10
88 contêineres, compatibilidade com versões anteriores,
81 marcação, 110– 12 histórico de desenvolvimento, 9
113 Microsoft Internet Explorer, 114 XML
codecs de vídeo, 83, 90, 100–109 histórico de desenvolvimento, 10

Vídeo para todos! exemplo, codec de conjuntos de tags, 9

áudio 114 Vorbis, 87, 91–99 codec


de vídeo VP8, 85

EM

W3C (Consórcio World Wide Web)


Grupo de Trabalho HTML, 9
O QUE Grupo de Trabalho, 13
Workshop sobre Aplicações Web e
Documentos Compostos, 11
função watchPosition(), 123 endereços
da web, formulários da web, 151
armazenamento local
de aplicativos da web, 127–
136 offline, 23, 137–146
navegadores da web (ver navegadores)
formulários da web, 147–
161 foco
automático, 27 campos de
foco automático, 148
seletores de cores,
160 seletores de data, 156
endereços
de e-mail, 150
históricos, 9 tipos de
entrada, 25 números, 153–156
texto de espaço
reservado, 27, 147 caixas de pesquisa, 158 endereços da web, 151
Trabalhadores da Web, 23

Formato de vídeo WebM, 82, 89, 108


Grupo de Trabalho O QUE e W3C, 13
grupos de trabalho
sobre, 12
Grupo de Trabalho HTML, 9
W3C, 11, 13
O QUE Grupo de Trabalho, 13
Workshop sobre Aplicações Web e
Documentos Compostos, 11

Índice | 205

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Sobre o autor
Mark Pilgrim é um defensor sênior de desenvolvedores no Google, Inc. Ele é especialista em código aberto e
padrões abertos. Mark é autor de vários livros técnicos, incluindo Dive Into Python (APress) e Dive Into
Accessibility, um tutorial online gratuito sobre acessibilidade na web. Ele mora na Carolina do Norte com a
esposa, dois filhos e um cachorro grande e babão.

Colofão O

animal na capa do HTML5: Up and Running é uma camurça alpina (Rupicapra rupicapra), uma espécie
semelhante a uma cabra ou antílope nativa das cadeias montanhosas da Europa, incluindo os Cárpatos, os
Apeninos, os Tatras, os Balcãs, o Cau casus e os Alpes. A camurça alpina também pode ser encontrada na
Nova Zelândia, tendo sido introduzida lá em 1907 pelo imperador austríaco Franz Joseph I.

A camurça alpina vive em altitudes relativamente altas e se adaptou a terrenos íngremes, acidentados e
rochosos. Eles crescem até um tamanho de cerca de 75 centímetros de altura e pesam entre 20 e 30
quilogramas (embora os indivíduos na Nova Zelândia pesem frequentemente cerca de 20% menos do que os
seus irmãos europeus). Tanto os machos quanto as fêmeas apresentam chifres curtos que se curvam para trás
perto da ponta e pêlo que é marrom escuro durante o verão e cinza claro no inverno. Muitas camurças também
exibem rosto e garupa caracteristicamente brancos, com listras pretas sob os olhos e ao longo das costas.

As camurças machos adultos vivem principalmente vidas solitárias, reunindo-se apenas uma vez por ano para
competir pela atenção das fêmeas não acasaladas. As fêmeas, entretanto, vivem em rebanhos com seus filhotes.
Todas as variedades de camurças são animais de caça populares; sua carne é considerada saborosa e seu
couro é excepcionalmente macio e absorvente. Além disso, um tufo de cabelo retirado da nuca de uma camurça,
chamado gamsbart, é tradicionalmente usado como decoração de chapéu em todos os países alpinos. Esta
prática pode ser um pouco mais difícil nos tempos modernos, no entanto, uma vez que algumas subespécies de
camurça ganharam protecção da União Europeia. Em contrapartida, o Departamento de Conservação da Nova
Zelândia incentiva a caça da camurça alpina, na esperança de limitar o impacto do animal na flora nativa.

A imagem da capa é do Animate Creation de JG Wood. A fonte da capa é Adobe ITC Garamond. A fonte do
texto é Linotype Birka; a fonte do título é Adobe Myriad Con densa; e a fonte do código é TheSansMonoCondensed
da LucasFont.

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>


Machine Translated by Google

Baixe da Biblioteca do Wow! e-book <www.wowebook.com>

Você também pode gostar