Skip to content
This page has been auto-translated and may contain errors.View in English

Imagens e mídia

docs.scrimba.com

Texto carrega muita coisa em uma página web, mas não tudo. Fotos, diagramas, ilustrações, vídeos e áudio também são conteúdo, e HTML tem elementos para cada um deles. Este capítulo é sobre a marcação que coloca mídia em uma página: como apontar para um arquivo de imagem, como descrevê-lo para pessoas que não conseguem vê-lo, e como servir o arquivo certo para a tela certa sem desperdiçar dados de ninguém.

O elemento de imagem

Você coloca uma imagem em uma página com o elemento de imagem, escrito como <img>. Ele não tem conteúdo e não tem tag de fechamento. Em vez disso, você o configura através de dois atributos: qual arquivo mostrar e do que é a imagem.

html
<img src="golden-retriever.jpg" alt="Um golden retriever sentado em grama alta">

src é a fonte: o caminho ou endereço web do arquivo de imagem. alt é o texto alternativo: uma breve descrição da imagem em palavras. Se a imagem não conseguir carregar, ou se alguém estiver ouvindo a página com um leitor de tela em vez de olhá-la, o texto alt é o que eles recebem. Então escreva como se estivesse descrevendo a imagem para um amigo ao telefone.

O elemento <img> puxa um arquivo externo para dentro da página. É um elemento void, então não tem tag de fechamento; tudo o que precisa fica nos seus atributos. Dois são essenciais:

html
<img src="/images/team-photo.jpg" alt="Os cinco membros do time de design nas suas mesas">

src é o caminho do arquivo, relativo à página ou uma URL absoluta. alt é o texto alternativo, as palavras que substituem a imagem quando ela não é exibida ou não consegue ser vista.

Acertar o alt é a parte que as pessoas pulam e não deveriam. Descreva o conteúdo e a finalidade da imagem, não os detalhes do arquivo. "Gráfico de barras mostrando vendas dobrando entre 2023 e 2024" diz ao leitor o que o gráfico mostra; "chart.png" não diz nada. Mantenha em uma frase e não comece com "Imagem de", o navegador já anuncia que é uma imagem.

<img> é um elemento void que carrega um recurso externo e o layout é feito inline com texto por padrão. Dois atributos fazem o trabalho real: src (a URL do recurso) e alt (a alternativa em texto). O resto desta seção é sobre alt, porque é onde a acessibilidade e a correção de uma imagem realmente vivem.

O atributo alt não é uma legenda e não é uma descrição do arquivo. É uma substituição: o texto que um navegador renderiza no lugar da imagem quando a imagem está ausente, e o texto que um leitor de tela (software que lê uma página em voz alta para pessoas que não conseguem vê-la) fala em vez da imagem. O teste é equivalência funcional. Se você removesse a imagem e colocasse seu texto alt no fluxo, a frase ainda faria sentido e carregaria a mesma informação? Um bom alt passa nesse teste; "foto1" não.

Duas regras decorrem disso. Primeiro, descreva a finalidade, não os pixels: um ícone de lupa dentro de um botão de busca tem alt="Buscar", não alt="lupa", porque seu trabalho na página é a ação, não o desenho. Segundo, imagens decorativas levam um alt vazio. Quando uma imagem não adiciona informação, um enfeite de fundo ou um divisor, escreva alt="" com nada entre as aspas. Isso não é o mesmo que deixar alt de fora. Um alt vazio diz à tecnologia assistiva "pule isso, não tem significado", enquanto um alt faltando faz um leitor de tela voltar a ler o nome do arquivo em voz alta, o que é pior que silêncio.

html
<!-- Significativo: descreva o que comunica -->
<img src="revenue-2024.png" alt="A receita subiu de 1,2 para 2,4 milhões em 2024">

<!-- Decorativo: alt vazio, então a tecnologia assistiva pula -->
<img src="corner-flourish.svg" alt="">
JunoO elemento de imagem Uma imagem precisa de duas coisas: src, que é o arquivo a mostrar, e alt, que descreve a imagem em palavras. Escreva o alt como se estivesse dizendo a alguém ao telefone o que há na foto. É a parte que é pulada mais, e é a parte que importa mais.
JunoO elemento de imagem<img> é um elemento void: sem tag de fechamento, tudo nos atributos. Descreva o que a imagem mostra, não o arquivo, e nunca comece com Imagem de, o navegador já sabe que é uma imagem. O alt de um gráfico deve dizer a alguém o número que o gráfico está fazendo.
JunoO elemento de imagem Um bom alt é uma substituição, não uma legenda: coloque-o na frase e o significado deve sobreviver. Descreva a função, não o desenho, então um ícone de busca lê Buscar. E alt="" para imagens decorativas é uma escolha real, diz a um leitor de tela para pular, enquanto um alt faltando faz ler o nome do arquivo em voz alta.

Imagens responsivas

Uma foto que fica nítida em um laptop pode ser muito maior do que um telefone precisa. Enviar esse arquivo de tamanho completo para uma tela pequena desperdiça os dados do visitante e desacelera a página. HTML permite que você ofereça ao navegador algumas versões da mesma imagem e deixe-o escolher a que se encaixa.

Você não precisa disso para cada imagem enquanto está começando. Uma única <img> com um arquivo sensível é tudo bem. Mas ajuda saber que a ideia existe: a mesma foto pode vir em vários tamanhos, e o navegador escolhe.

html
<img src="beach-800.jpg" alt="Ondas rolando em uma praia tranquila ao pôr do sol">

Imagens responsivas deixam o navegador escolher um arquivo baseado na tela. Em vez de hardcodear uma fonte, você lista várias com srcset e descreve quão larga a imagem será exibida com sizes. O navegador faz as contas e baixa o melhor correspondência.

html
<img
  src="beach-800.jpg"
  srcset="beach-400.jpg 400w, beach-800.jpg 800w, beach-1600.jpg 1600w"
  sizes="(max-width: 600px) 100vw, 50vw"
  alt="Ondas rolando em uma praia tranquila ao pôr do sol">

Em srcset, cada entrada emparelha um arquivo com sua largura real em pixels (400w significa que o arquivo tem 400 pixels de largura). Em sizes, você diz ao navegador quanto espaço a imagem ocupará: aqui ela preenche toda a largura da viewport (100vw) em telas até 600 pixels, e metade da largura (50vw) caso contrário. O src permanece como um fallback para navegadores mais antigos. Note que o alt é escrito uma vez e se aplica a cada fonte, porque são todas a mesma imagem.

Quando você precisa de mais do que uma troca de tamanho, use <picture>. Ela envolve vários elementos <source> e um <img>, e o navegador usa o primeiro <source> que corresponde. Isso lida com direção de arte, servindo uma imagem com corte diferente em larguras diferentes, e formatos de arquivo modernos:

html
<picture>
  <source srcset="hero.avif" type="image/avif">
  <source srcset="hero.webp" type="image/webp">
  <img src="hero.jpg" alt="Dois ciclistas subindo uma estrada de montanha ao amanhecer">
</picture>

O navegador lê de cima para baixo, escolhe o primeiro formato que entende, e volta para o <img> comum se nenhum corresponder. O <img> dentro é obrigatório; é o que realmente renderiza e onde alt vive.

Imagens responsivas resolvem um problema de comutação de resolução: a mesma imagem, diferentes dimensões de pixels para diferentes displays, escolhidas pelo navegador antes do download para que ninguém pague por pixels que não consegue ver. Há duas ferramentas, e elas respondem perguntas diferentes.

srcset com sizes responde "qual resolução?". Você dá ao navegador um conjunto de arquivos candidatos, cada um marcado com sua largura intrínseca em pixels usando o descritor w, e um valor sizes dizendo-lhe quão larga a imagem renderizará em vários breakpoints. Um breakpoint é um limite de largura de tela em que o layout muda. O navegador combina sua dica sizes com a densidade de pixel do dispositivo para escolher o menor arquivo que ainda se parece nítido.

html
<img
  src="product-800.jpg"
  srcset="product-400.jpg 400w, product-800.jpg 800w, product-1200.jpg 1200w"
  sizes="(max-width: 700px) 100vw, 350px"
  alt="Mochila de couro mostrada pela frente">

O elemento <picture> responde uma pergunta diferente: "qual fonte inteiramente?". É para casos onde o arquivo em si deve mudar, não apenas sua escala. Duas razões comuns. Direção de arte, onde um banner largo se transforma em retrato tall em telas estreitas para que o assunto permaneça visível, precisa de arquivos de imagem diferentes, não um arquivo dimensionado para baixo. E negociação de formato, onde você oferece um formato moderno com um fallback, precisa que o navegador escolha por o que consegue decodificar.

html
<picture>
  <source media="(max-width: 600px)" srcset="hero-portrait.avif" type="image/avif">
  <source media="(max-width: 600px)" srcset="hero-portrait.jpg">
  <source srcset="hero-wide.avif" type="image/avif">
  <img src="hero-wide.jpg" alt="Chefe apresentando um prato em uma cozinha movimentada">
</picture>

A ordem importa: o navegador pega o primeiro <source> cujo media e type ele satisfaz, então coloque suas opções mais preferidas e mais restritas primeiro. O <img> final é obrigatório e é o elemento que a página realmente renderiza; srcset e sizes nas fontes o alimentam, mas alt, width, height e comportamento de carregamento tudo pertence àquele <img> interno.

JunoImagens responsivas A mesma foto pode vir em alguns tamanhos, e o navegador pode escolher o que se encaixa na tela para que um telefone não baixe um arquivo do tamanho de um laptop. Você não precisa disso no primeiro dia; um <img> simples está bom. A opção existe para quando uma página começa a parecer pesada no mobile.
JunoImagens responsivas Use srcset e sizes quando você quer que o navegador escolha um tamanho, e <picture> quando você quer trocar o arquivo em si, por um corte diferente ou um formato moderno. O <img> dentro de <picture> é obrigatório e é onde alt vive. Escreva o alt uma vez; cada fonte é a mesma imagem.
JunoImagens responsivas Dois trabalhos diferentes: srcset mais sizes escolhe uma resolução, <picture> escolhe uma fonte inteira para direção de arte ou negociação de formato. As fontes são lidas de cima para baixo, primeira correspondência vence, então ordene a mais restrita primeiro. Tudo que renderiza ainda fica pendurado no <img> interno, então é lá que alt e dimensionamento vão.

Vídeo e áudio

HTML consegue reproduzir vídeo e áudio sem nenhum plug-in. Para um clipe, você usa o elemento <video>; para áudio, <audio>. Adicione o atributo controls e o navegador lhe dá um botão de play, uma timeline e um controle de volume de graça.

html
<video src="tutorial.mp4" controls></video>

<audio src="podcast-episode.mp3" controls></audio>

Diferente de uma imagem, esses têm uma tag de fechamento, porque você pode colocar texto de fallback ou configurações extras entre as tags de abertura e fechamento. A coisa mais importante de lembrar no começo: sempre inclua controls, ou o visitante não tem jeito de apertar play.

Os elementos <video> e <audio> embutem um reprodutor de mídia nativo na página. O atributo controls mostra a interface nativa de play, pause, busca e volume do navegador; sem ele, não há controles.

html
<video src="product-demo.mp4" controls width="640" poster="demo-cover.jpg"></video>

Alguns atributos merecem seu lugar. poster define uma imagem estática mostrada antes do vídeo começar, então o reprodutor não é uma caixa preta. width reserva o tamanho do reprodutor. Você também pode adicionar autoplay, loop e muted, embora a maioria dos navegadores só permita autoplay quando o vídeo também está muted, então esses dois viajam juntos.

Para oferecer mais de um formato de arquivo, solte o src e liste elementos <source> dentro. O navegador reproduz o primeiro que consegue:

html
<video controls width="640" poster="demo-cover.jpg">
  <source src="product-demo.webm" type="video/webm">
  <source src="product-demo.mp4" type="video/mp4">
  Seu navegador não consegue reproduzir este vídeo.
</video>

O texto após as fontes é conteúdo de fallback, mostrado apenas se o navegador não conseguir reproduzir nenhuma delas. <audio> funciona da mesma forma, com o mesmo padrão controls e <source>, menos os atributos visuais como poster e width.

<video> e <audio> embutem o pipeline de mídia nativo do navegador, decodificação, buffering e uma UI de reprodutor integrada, sem um plug-in de terceiros. Ambos levam controls (mostram a UI nativa), e ambos aceitam múltiplos filhos <source> para que você possa oferecer vários codecs (os formatos de compressão que um arquivo de vídeo ou áudio é codificado) e deixar o navegador escolher o primeiro que consegue decodificar.

html
<video controls width="640" height="360" poster="demo-cover.jpg" preload="metadata">
  <source src="demo.webm" type="video/webm">
  <source src="demo.mp4" type="video/mp4">
  <track kind="captions" src="demo-captions.en.vtt" srclang="en" label="Inglês" default>
  Seu navegador não consegue reproduzir este vídeo.
</video>

Duas preocupações de produção dominam aqui. A primeira é acessibilidade, tornando a mídia utilizável por pessoas que não conseguem ouvir ou ver. É para isso que <track> é: ela anexa um arquivo de texto cronometrado, geralmente em formato WebVTT (um formato de legenda em texto simples, arquivos terminando .vtt), à mídia. kind="captions" fornece uma versão em texto de fala e sons importantes para espectadores que são surdos ou em um cenário sem som, que é a maioria das pessoas rolando em público. kind="subtitles" traduz diálogos para outro idioma. O atributo default ativa uma faixa sem o usuário procurá-la. Vídeo sem legendas exclui uma fatia real do seu público, e legendas também ajudam mecanismos de busca, que não conseguem assistir a um vídeo mas conseguem ler uma transcrição.

A segunda preocupação é largura de banda. preload controla quão avidamente o navegador busca a mídia antes da reprodução: preload="none" não baixa nada até o usuário apertar play, preload="metadata" pega apenas duração e dimensões, e preload="auto" pode puxar o arquivo inteiro. Padrão para metadata ou none para qualquer coisa abaixo da dobra, porque um vídeo com autoload é uma das coisas mais pesadas que uma página pode fazer silenciosamente. E a mesma advertência autoplay se aplica: navegadores bloqueiam autoplay com som, então um vídeo que é autoplay deve ser muted, que é outra razão pela qual legendas importam.

JunoVídeo e áudio<video> reproduz um clipe e <audio> reproduz som, sem plug-ins necessários. Adicione controls ou não há botão de play e o visitante fica preso. Ambos têm tags de fechamento, porque você pode colocar configurações e texto de fallback dentro deles, diferente de uma imagem.
JunoVídeo e áudio Sempre adicione controls, defina um poster para que o reprodutor não seja um retângulo preto, e liste elementos <source> para oferecer mais de um formato. autoplay só funciona se o vídeo for muted, então esses dois vão juntos. Áudio é o mesmo padrão sem os atributos visuais.
JunoVídeo e áudio Adicione um <track> com legendas; a maioria das pessoas assiste sem som, e mecanismos de busca leem o texto que não conseguem assistir. Mantenha preload em metadata ou none para qualquer coisa abaixo da dobra, um vídeo com autoload é uma das maneiras mais silenciosas de fazer uma página pesada. E autoplay com som é bloqueado, então autoplay significa muted, que é uma razão a mais para legendar.

Dimensionamento, lazy loading e desempenho

Quando uma imagem carrega, ela pode empurrar o resto da página para um lado. Você está lendo um parágrafo, uma foto termina de carregar acima, e de repente o texto pula para baixo. Esse pulo é irritante, e você consegue evitá-lo: diga ao navegador o tamanho da imagem antecipadamente com width e height.

html
<img src="team-lunch.jpg" alt="O time compartilhando almoço na varanda do escritório"
     width="800" height="600">

Com esses números, o navegador reserva a quantidade certa de espaço antes da imagem chegar, então nada pula quando ela chega. Você dá as dimensões reais em pixels do arquivo, e CSS ainda consegue redimensioná-lo na tela.

Imagens afetam duas coisas que você sente como usuário: quanto a página muda enquanto carrega, e quanto de dados ela puxa. HTML te dá atributos para ambos.

Definir width e height previne deslocamento de layout, conteúdo pulando para cima e para baixo enquanto imagens carregam. Quando você declara as dimensões, o navegador reserva esse espaço imediatamente em vez de colapsar a imagem para nada e então expandir uma vez que o arquivo chega.

html
<img src="article-header.jpg" alt="Visão aérea de uma redação movimentada"
     width="1200" height="675" loading="lazy">

O atributo loading="lazy" diz ao navegador não baixar a imagem até o leitor estar prestes a rolar para vê-la. Para imagens longe em uma página longa, isso economiza dados e acelera o primeiro paint. Uma regra: não faça lazy-load da imagem que o visitante vê primeiro, no topo da página. Essa você quer carregada o mais rápido possível, então deixe loading de fora dela (ou defina loading="eager").

Mídia é geralmente a parte mais pesada de uma página, então os atributos que governam seu carregamento são controles de desempenho, não decoração. Três importam.

Primeiro, cumulative layout shift (deslocamento cumulativo de layout), uma medida de quanto conteúdo visível pula enquanto a página carrega. A causa comum é uma imagem sem tamanho declarado: o navegador lhe dá altura zero, organiza tudo abaixo, então reflua a coluna inteira uma vez que o arquivo chega e sua altura real é conhecida. Você previne isso dando ao navegador a proporção de aspecto antecipadamente. Defina width e height para as dimensões reais em pixels do arquivo, e o navegador computa a proporção e reserva a caixa certa mesmo enquanto CSS redimensiona a exibição:

html
<img src="feature.jpg" alt="Painéis solares em um campo verde"
     width="1600" height="900" loading="lazy" decoding="async">

Você pode expressar a mesma intenção em CSS com a propriedade aspect-ratio; o ponto é que a proporção deve ser conhecível antes dos pixels baixarem.

Segundo, loading="lazy" adia o download de imagens fora da tela até o leitor se aproximar delas, cortando a carga inicial em páginas longas. A exceção crítica é seu elemento LCP (Largest Contentful Paint, a maior imagem ou bloco visível sem rolar, e uma métrica que navegadores e ranking de busca observam). Fazer lazy-load dessa imagem adia exatamente o que a métrica mede, então o herói acima da dobra deve carregar avidamente.

Terceiro, decoding="async" deixa o navegador decodificar a imagem fora da thread principal, então transformar bytes comprimidos em pixels não bloqueia outra renderização. É uma pequena vitória segura para imagens que não são a primeira coisa na tela.

Formato é a outra alavanca. WebP e AVIF são formatos de imagem modernos que comprimem muito menores do que JPEG ou PNG com a mesma qualidade visual; AVIF geralmente vence em tamanho de arquivo, WebP em suporte de navegador e velocidade de codificação. A troca é compatibilidade e tooling, que é exatamente do que <picture> com fontes type é construído para gerenciar: ofereça AVIF primeiro, WebP próximo, e um fallback JPEG ou PNG por último, e todo navegador recebe o melhor arquivo que realmente consegue decodificar.

JunoDimensionamento, lazy loading e desempenho Dê a cada imagem um width e height e a página para de pular enquanto fotos carregam. Use o tamanho real em pixels do arquivo; CSS ainda consegue encolhê-lo na tela. Esse hábito único corrige o glitch de carregamento mais irritante que existe.
JunoDimensionamento, lazy loading e desempenhowidth e height reservam espaço para que nada se mova conforme imagens carregam, e loading="lazy" segura o download de imagens até elas estarem prestes a rolar para dentro da visualização. A imagem que não é para fazer lazy-load é a primeira da página; essa deve carregar direto.
JunoDimensionamento, lazy loading e desempenho Declare width e height (ou defina aspect-ratio) para que o navegador reserve a caixa e o layout pare de pular; a proporção só precisa ser conhecida antes dos pixels chegarem. Faça lazy-load de tudo exceto o herói acima da dobra, já que fazer lazy-load da sua maior imagem visível desacelera a métrica que a observa. E sirva AVIF ou WebP através de <picture> com um fallback JPEG para que todo navegador receba o menor arquivo que consegue decodificar.