Sintaxes prescritivas

O elemento <picture> não renderiza nada por conta própria, mas atua como um mecanismo de decisão para um elemento <img> interno. informando o que deve ser renderizado. <picture> segue um precedente já definido pelos elementos <audio> e <video>: um elemento wrapper. que contém elementos <source> individuais.

<picture>
   <source …>
   <source …>
    <img …>
</picture …>

Esse <img> interno também fornece um padrão de substituição confiável para navegadores mais antigos sem suporte a imagens responsivas: se o elemento <picture> não for reconhecido pelo navegador do usuário, ele será ignorado. Em seguida, os elementos <source> também são descartados. já que o navegador não os reconhecerá ou não terá contexto significativo para eles sem um pai <video> ou <audio>. No entanto, o elemento <img> interno será reconhecido por qualquer navegador, e a origem especificada no src será renderizada conforme o esperado.

"Com direção de arte" imagens com <picture>

Fazer alterações no conteúdo ou na proporção de uma imagem com base no tamanho da imagem na página é normalmente chamado de "direcionado à arte" imagens responsivas. srcset e sizes foram criados para funcionar de forma invisível, trocando origens perfeitamente conforme exigido pelo navegador do usuário. No entanto, há momentos em que convém alterar as fontes nos pontos de interrupção para destacar melhor o conteúdo, da mesma forma que você adapta layouts de página. Por exemplo: uma imagem de cabeçalho de largura total com um foco central pequeno pode funcionar bem em uma janela de visualização grande:

Imagem de cabeçalho da largura de uma flor-laxante cercada por folhas e caules, sendo visitada por uma abelha.

Mas, quando reduzida para se ajustar a janelas de visualização pequenas, o foco central da imagem pode ser perdido:

Imagem da largura do cabeçalho de uma flor azul-lavanda, reduzida. A abelha quase não está visível.

O assunto dessas fontes de imagens é o mesmo, mas para focar melhor nesse assunto visualmente, você precisará que as imagens proporções da origem da imagem sejam alteradas entre os pontos de interrupção. Por exemplo, um zoom mais restrito no centro da imagem e alguns dos detalhes nas bordas cortados:

Uma safra ampliada da flor azul-lavanda.

Esse tipo de "corte" pode ser alcançado por CSS, mas deixaria um usuário solicitando todos os dados que compõem essa imagem, mesmo que eles nunca acabem vendo.

Cada elemento source tem atributos que definem as condições para a seleção dessa source: media, que aceita uma consulta de mídia, e type, que aceita um tipo de mídia (anteriormente conhecido como "tipo MIME"). O primeiro <source> na origem para corresponder ao contexto de navegação atual do usuário é selecionado e o conteúdo do atributo srcset nesse source serão usados para determinar os candidatos certos para esse contexto. Neste exemplo, o primeiro source com um atributo media que corresponda ao tamanho da janela de visualização do usuário será o selecionado:

<picture>
  <source media="(min-width: 1200px)" srcset="wide-crop.jpg">
  <img src="close-crop.jpg" alt="…">
</picture>

Sempre especifique o img interno por último na ordem, se nenhum dos elementos source corresponder ao media ou type padrão, a imagem será "padrão" fonte. Se você estiver usando consultas de mídia min-width, convém ter a maior origens, como vimos no código anterior. Ao usar consultas de mídia max-width, coloque a menor origem primeiro.

<picture>
   <source media="(max-width: 400px)" srcset="mid-bp.jpg">
   <source media="(max-width: 800px)" srcset="high-bp.jpg">
   <img src="highest-bp.jpg" alt="…">
</picture>

Quando uma fonte é escolhida com base nos critérios especificados, o atributo srcset em source é transmitido para o <img> como se tivesse sido definido no próprio <img>, o que significa que você pode usar sizes para otimizar a imagem direcionada por arte fontes de informações relevantes.

<picture>
   <source media="(min-width: 800px)" srcset="high-bp-1600.jpg 1600w, high-bp-1000.jpg 1000w">
   <source srcset="lower-bp-1200.jpg 1200w, lower-bp-800.jpg 800w">
   <img src="fallback.jpg" alt="…" sizes="calc(100vw - 2em)">
</picture>

É claro que uma imagem com proporções que podem variar dependendo do elemento <source> selecionado causa um problema de desempenho: O <img> só oferece suporte a um único atributo width e height, mas a omissão desses atributos pode atrapalhar a experiência do usuário. Por isso, uma amostra relativamente recente, mas tem um bom suporte, além de uma adição ao HTML permite o uso dos atributos height e width em elementos <source>. Elas também servem para reduzir as trocas de layout como no <img>, com o espaço adequado reservado no layout para qualquer elemento <source> selecionado.

<picture>
   <source
      media="(min-width: 800px)"
      srcset="high-bp-1600.jpg 1600w, high-bp-1000.jpg 1000w"
      width="1600"
      height="800">
   <img src="fallback.jpg"
      srcset="lower-bp-1200.jpg 1200w, lower-bp-800.jpg 800w"
      sizes="calc(100vw - 2em)"
      width="1200"
      height="750"
      alt="…">
</picture>

É importante observar que a direção de arte pode ser usada para mais do que decisões baseadas no tamanho da janela de visualização. Isso deve ser feito, dado que a maioria desses casos pode ser resolvida de forma mais eficiente com srcset/sizes. Por exemplo, selecionar melhor uma fonte de imagem adequados para o esquema de cores determinado pela preferência do usuário:

<picture>
   <source media="(prefers-color-scheme: dark)" srcset="hero-dark.jpg">
   <img srcset="hero-light.jpg">
</picture>

O atributo type

O atributo type permite que você use o mecanismo de decisão de solicitação única do elemento <picture> para veicular apenas formatos de imagem. a navegadores compatíveis com elas.

Como você aprendeu em Formatos e compactação de imagens, uma codificação que o navegador não puder analisar não será reconhecível como dados de imagem.

Antes da introdução do elemento <picture>, as soluções de front-end mais viáveis para disponibilizar novos formatos de imagem eram necessárias o navegador solicite e tente analisar um arquivo de imagem antes de determinar se deve descartá-lo e carregar um substituto. Um um exemplo comum foi um script nesta linha:

   <img src="image.webp"
    data-fallback="image.jpg"
    onerror="this.src=this.getAttribute('data-fallback'); this.onerror=null;"
    alt="...">

Com esse padrão, uma solicitação de image.webp ainda seria feita em todos os navegadores, o que significava uma transferência desperdiçada para os navegadores. sem compatibilidade com WebP. Os navegadores que não pudessem analisar a codificação WebP gerariam um evento onerror e trocariam o valor data-fallback em src. Foi uma solução ruim, mas, novamente, abordagens como essa eram a única opção disponíveis no front-end. O navegador começa a fazer solicitações de imagens antes que qualquer script personalizado tenha uma de serem executados ou mesmo analisados. Por isso, não podemos forçar a interrupção desse processo.

O elemento <picture> foi projetado explicitamente para evitar essas solicitações redundantes. Ainda não é possível usar o navegador para reconhecer um formato incompatível sem solicitá-lo, o atributo type alerta o navegador sobre a origem. codificações de entrada, para que possa decidir se deve ou não fazer uma solicitação.

No atributo type, você fornece o Tipo de mídia (antigo tipo MIME). da origem da imagem especificada no atributo srcset de cada <source>. Isso fornece ao navegador todas as informações precisa determinar imediatamente se a imagem candidata a imagem fornecida por essa source pode ser decodificada sem fazer Solicitações: se o tipo de mídia não for reconhecido, o <source> e todos os seus candidatos serão desconsiderados, e o navegador seguirá em frente.

<picture>
 <source type="image/webp" srcset="pic.webp">
 <img src="pic.jpg" alt="...">
</picture>

Aqui, qualquer navegador compatível com a codificação WebP reconhecerá o tipo de mídia image/webp especificado no atributo type do elemento <source>, selecione esse <source> e, como fornecemos apenas um candidato em srcset, instrua a parte interna <img> para solicitar, transferir e renderizar pic.webp. Qualquer navegador sem suporte para WebP desconsiderará source, e Sem instruções em contrário, o <img> vai renderizar o conteúdo de src da mesma forma que faz desde 1992. Não é necessário especificar um segundo elemento <source> com type="image/jpeg" aqui, é claro que você pode presumir que há suporte universal para JPEG.

Independentemente do contexto de navegação do usuário, tudo isso é conseguido com uma única transferência de arquivos, sem desperdício de largura de banda origens de imagem que não podem ser renderizadas. Isso também é inovador: à medida que formatos de arquivo mais novos e eficientes surgirão com tipos de mídia próprios, e podemos aproveitá-los graças à picture, sem JavaScript e sem servidor dependências e toda a velocidade de <img>.

O futuro das imagens responsivas

Todos os padrões de marcação discutidos aqui foram um grande aumento em termos de padronização: alterar a funcionalidade de algo tão estabelecido e central para a Web quanto o <img> não foi um trabalho fácil, e o conjunto de problemas que essas mudanças visavam a de resolver era extenso, para dizer o mínimo. Se você já percebeu que essas ferramentas podem melhorar bastante padrões de marcação, você acertou. Desde o início, esses padrões foram criados para oferecer uma referência tecnologias para desenvolver.

Todas essas soluções dependeram necessariamente de marcações para que sejam incluídas na carga inicial do servidor, e chegam a tempo para o navegador solicitar origens de imagem, uma limitação que levou ao atributo sizes admitidamente pesado.

No entanto, como esses recursos foram introduzidos na plataforma Web, um método nativo de adiar solicitações de imagem foi introduzido. Os elementos <img> com o atributo loading="lazy" não são solicitados até que o layout da página seja conhecido, a fim de adiar solicitações de imagens fora da janela de visualização inicial do usuário até um momento posterior do processo de renderização da página, possivelmente evitando solicitações desnecessárias. Como o navegador compreende totalmente o layout da página no momento em que essas solicitações são feitas, uma O atributo sizes="auto" foi proposto como uma adição à especificação HTML para evitar a tarefa de criar atributos sizes manualmente nesses casos.

O elemento <picture> está sendo lançado em breve, para combinar com algumas mudanças excepcionalmente interessantes. ao estilo dos layouts de página. Embora as informações da janela de visualização sejam uma base sólida para decisões de layout de alto nível, elas nos impede de adotar uma abordagem de desenvolvimento totalmente em nível de componente, ou seja, um componente que pode ser incluído qualquer parte de um layout de página, com estilos que respondem ao espaço que o próprio componente ocupa. Essa preocupação levou para a criação de consultas de contêiner: um método de estilização de elementos com base no tamanho do contêiner pai, e não apenas na janela de visualização.

Embora a sintaxe de consulta do contêiner tenha acabado de se estabilizar, e a compatibilidade com navegadores é muito limitada, No momento em que este artigo foi escrito, a adição das tecnologias de navegação que as permitem fornecerá ao elemento <picture> um significa fazer a mesma coisa: um possível atributo container que permite o critério de seleção <source> com base no espaçar o <picture> elemento <img> ocupa, e não com base no tamanho da janela de visualização.

Se isso parece um pouco vago, há um bom motivo: essas discussões sobre padrões da Web estão em andamento, mas estão longe de serem resolvidas. Você eles ainda não podem ser usados.

Embora a marcação de imagem responsiva prometa ser mais fácil de trabalhar ao longo do tempo, como qualquer tecnologia da Web, há vários de serviços, tecnologias e estruturas para ajudar a aliviar o fardo de escrever à mão essa marcação disponível. No próximo módulo, veremos como integrar tudo o que aprendemos sobre formatos de imagens, compactação e imagens responsivas em um fluxo de trabalho de desenvolvimento moderno.