# Imagem de largura total em layout com limite de largura

> Imagem de largura total em layout com largura limitada. Técnica CSS para breakout de imagens full-width sem quebrar grid ou container. Truque incrível!

URL: https://dpw.dev/css/imagem-largura-total-layout-largura-limitada/  
Publicado em: 2017-07-11  
Categoria: css  
Tags: interface, layout, web-design-responsivo  
Autor: Tárcio Zemel

Quem já trabalha há algum tempo com CSS certamente já deve ter se deparado com uma questão: **como fazer uma imagem ocupar a largura total em um layout com limite de largura**? Existem diferentes técnicas para alcançar o efeito, mas a que está apresentada aqui certamente vai surpreender você!

> Artigo baseado em [Breaking Out With Viewport Units and Calc](https://cloudfour.com/thinks/breaking-out-with-viewport-units-and-calc/).

Para conteúdos mais extensos, normalmente é uma boa idéia [limitar o comprimento de linha](http://practicaltypography.com/line-length.html) para facilitar a legibilidade. Até então, a maneira mais fácil de fazer isso é envolver o conteúdo do post em um contêiner:

```scss
.u-containProse {
    margin-left: auto;
    margin-right: auto;
    max-width: 40em;
}

```

```html
<div class="u-containProse">
<p>...</p>
<p>...</p>
</div>
```

Mas e se for preciso que algum conteúdo se estenda para além dos limites do contêiner? Certas imagens podem ter maior impacto se preencherem toda a viewport.

![Elemento largura total em layout com limite de largura: exemplo](/images/blog/imagem-largura-total-layout-largura-limitada/1499801787-elemento-largura-total-layout-largura-limitada-container-image.webp)

Usando técnicas não tão atuais, era possível resolver a questão envolvendo tudo, exceto imagens de largura total, com a classe de contêiner:

```html
<div class="u-containProse">
    <p>...</p>
</div>

<img src="/images/blog/imagem-largura-total-layout-largura-limitada/..." alt="..." />

<div class="u-containProse">
    <p>...</p>
</div>
```

Mas adicionar esses contêineres a cada postagem torna-se tedioso muito rapidamente -- sem contar que pode ser bem complicado implementar a técnica quando sistema de gerenciamento de conteúdo estão envolvidos.

Um passo natural para tentar resolver o problema pode ser tentar limitar a largura de elementos descendentes específicos (parágrafos, listas etc.):

```typescript
.u-containProse p,
.u-containProse ul,
.u-containProse ol,
.u-containProse blockquote /* etc. */ {
    max-width: 40em;
    margin-left: auto;
    margin-right: auto;
}
```

Além de esse seletor dar pesadelos em muita gente, essa técnica pode causar sobreposições de largura, margens e outros problemas de comportamentos inesperados dentro dos conteúdos. Também, não resolverá o problema se o CMS usado envolver imagens soltas em parágrafos.

O problema com ambas as soluções é que elas complicam os elementos mais comuns (parágrafos e outros conteúdos) ao invés dos _outliers_ (imagens de largura total).

## Solução para imagem de largura total em layout com limite de largura

Para liberar o elemento filho de seu contêiner, é preciso saber quanto espaço há entre a borda do contêiner e o limite da viewport, o que dá metade da largura da viewport menos a metade da largura do contêiner. É possível determinar esse valor usando a função [calc()](https://developer.mozilla.org/pt-BR/docs/Web/CSS/calc), [unidades de viewport](/css/unidades-de-viewport-controle-tipografia-web-design-responsivo/) e a boa e velha porcentagem (para a largura do container):

```scss
.u-release {
    margin-left: calc(-50vw + 50%);
    margin-right: calc(-50vw + 50%);
}
```

_Voilà_! Qualquer imagem/elemento com esta classe aplicada ocupará a largura total da tela, independentemente do tamanho do contêiner. Aqui está em ação:

See the Pen [Full-width element in fixed-width container example](https://codepen.io/tylersticka/pen/XdvBXm/) by Tyler Sticka ([@tylersticka](https://codepen.io/tylersticka)) on [CodePen](https://codepen.io).
Navegadores que não suportam `calc()` ou unidades de viewport, como Opera Mini, simplesmente as ignorarão.

### Um grande problema

Essa solução é demais, é tão mais inteligente, direta, previsível e concisa em comparação com outras técnicas! Mas, se não observar com cuidado, pode ser que um pequeno grande problema passe despercebido: **uma barra de rolagem horizontal!**

![Elemento largura total em layout com limite de largura: barra de rolagem horizontal](/images/blog/imagem-largura-total-layout-largura-limitada/1499804347-imagem-largura-total-layout-largura-scrollbar.webp)

Em qualquer página com esta classe de utilidade em uso, uma barra de rolagem vertical visível sempre será acompanhada por uma barra de rolagem horizontal _desagradável_. As páginas mais curtas não sofrerão esse problema e os navegadores sem barras de rolagem visíveis (iOS Safari, Android Chrome etc.) também parecerão imunes.

A solução para esta degraça de barra de rolagem horizontal pode ser encontrada ao ler a [especificação sobre unidades de viewport](https://www.w3.org/TR/css3-values/#viewport-relative-lengths):

> Os comprimentos de viewport em porcentagem são relativos ao tamanho do [bloco que contém (containing block) inicial](https://www.w3.org/TR/CSS21/visudet.html#containing-block-details). Quando a altura ou largura do containing block inicial é alterada, eles são dimensionados de acordo. No entanto, **quando o valor do overflow no elemento raiz é auto, quaisquer barras de rolagem são assumidas como não existentes**. Observe que o tamanho do containing block inicialmente é afetado pela presença de barras de rolagem na viewport. (grifo nosso)

Traduzindo: unidades de viewport não levam em conta as dimensões da barra de rolagem a menos que se defina explicitamente os valores de `overflow` para `scroll` -- mas nem isso funciona no Chrome ou no Safari (bugs [aqui](https://bugs.chromium.org/p/chromium/issues/detail?id=377331) e [aqui](https://bugs.webkit.org/show_bug.cgi?id=133271)).

![Thats it gif animado](/images/blog/imagem-largura-total-layout-largura-limitada/1499804939-thatsit.gif)

Mas existe um macete que pode ser usado:

```scss
html,
body {
    overflow-x: hidden;
}
```

É uma pena que (no momento) isso seja mesmo necessário... Torçamos para que os bugs sejam arrumados o quanto antes.

---

Fonte: [dpw - desenvolvimento para web](https://dpw.dev/) (pt-BR).
Guia para agentes: https://dpw.dev/llms.txt
Índice completo: https://dpw.dev/sitemap-index.xml
Feed: https://dpw.dev/rss.xml
