Design & UX

1 abr, 2014

Desenvolvimento Responsivo e Viewport

Publicidade

Você estudou muito, quebrou a cabeça, planejou, resolveu bugs e, finalmente, seu projeto responsivo está pronto. Testou no seu desktop e está bonitão. Você redimensiona o navegador e vê a mágica acontecer. Testou em serviços online, como o responsinator, e tá tudo muito lindo! Aí veio aquela hora de testar ao vivo no mobile… A expectativa é alta e… Nada acontece. Abre como um site comum de 980px. Mas você fez tudo certo! O que aconteceu, afinal?

Bom, muito provavelmente você esqueceu de especificar o Viewport do seu projeto. Se acalme, não é nada tão grave. Neste artigo, quero levar você a conhecer mais sobre o assunto, mostrar o que está surgindo de novo e porque ele é fundamental quando estamos desenvolvendo um projeto responsivo.

Declarando viewport

Bate-bola, jogo rápido: coloque isso entre as tags <head> do seu código:

<meta name="viewport" content="width=device-width,initial-scale=1">

De tudo o que você for ler sobre o assunto, decore isso. Anote em papéis, faça uma tatuagem, nomeie seu filho com esta linha ou – sendo mais prático – coloque em seu boilerplate para iniciar o seu projeto. O importante é não esquecer.

Eu poderia ser simplista e parar por aqui. Mas não sou. E você que está lendo este artigo também não é. Além de estudioso, também é um curioso. E pessoas curiosas gostam de saber como tudo funciona. Então, como bons curiosos, vamos começar entender o por que disso tudo.

O pixel que não vale um pixel

Basicamente, 1 pixel é a menor unidade de uma imagem digital. As imagens projetadas na sua tela são formadas por milhares de pontinhos, e cada pontinho é 1 pixel. O tamanho e a quantidade de pixel apresentados vai variar de acordo com a densidade da tela. E, como veremos, vai variar também de acordo com o que estamos medindo.

No webdesign é comum tratarmos um pixel como uma medida exata, embora não seja. E isso não é um erro. Acontece que existem três tipos de pixel diferente a serem levados em consideração e, desses três, apenas 2 interessam: o CSS pixel e o pixel do dispositivo, que podem ter o mesmo valor. Temos também o “dpi pixel”, mas ele não é tão importante para o webdesign.

Como a Dani Guerrato falou em seu artigo “Design Responsivo e Retina Display”, até pouco tempo atrás era comum presumir que, para monitores a resolução era de 72dpi. Com o tempo, o padrão se tornou 96dpi. No entanto, começaram a surgir telas com uma densidade de pixel cada vez mais alta, o que criou uma pluralidade grande de resoluções e dpis espalhadas por ai. No caso de smartphones, os modelos mais em conta tem uma densidade menor do que os top de linha.

O dpi é a quantidade de pixels que cabe em uma polegada. Dizer que uma tela tem 300dpi significa que, para cada polegada, temos 300 “pontinhos” formando a imagem. Isso permite resoluções muito maiores em telas que tem fisicamente o mesmo tamanho. Um iPad com tela retina, por exemplo, tem a resolução de 2048×1536, enquanto um iPad sem tela retina tem a resolução de 1024×768. No entanto, os dois aparelhos tem, fisicamente, telas do mesmo tamanho. A diferença é que o dpi do iPad com tela retina é o dobro da tela de seu antecessor. Para fins didáticos, neste artigo chamarei essa medida de “dpi pixel”.

Para nós, webdesigners que vamos trabalhar essencialmente com CSS, o “dpi pixel” só será importante para pensarmos na resolução das imagens do nosso projeto. O que nos interessa aqui é o CSS pixel.

O CSS Pixel é a medida usada no CSS para declaramos o tamanho de um objeto. Por exemplo: ao declarar “font-size: 16px”, estamos informando ao browser que o tamanho do texto é de 16 CSS Pixel.

Em desktops e notebooks, na maioria das vezes, o tamanho do CSS Pixel equivale ao tamanho da largura e altura da resolução que você está utilizando. Mas, em monitores de altíssima resolução isso faria com que alguns elementos ficassem muito pequenos. Para contornar este problema, em telas de alta densidade o CSS pixel equivale a mais do que 1 dpi pixel.

Exemplo: um iPhone sem a tela retina, por exemplo, tem 163dpi. Um iPhone com a tela retina tem 326dpi. Em teoria, isso significa que o tamanho da resolução do iPhone com a tela retina é duas vezes maior do que o iPhone sem retina. Mas os elementos são sempre do mesmo tamanho. Isso acontece porque, no iPhone com tela retina 1 CSS Pixel equivale a 2 DPI Pixel.

css-pixel-vs-dpi-pixel

O pixel físico de seu aparelho

Para dispositivos móveis, temos um terceiro tipo de pixel: o “device-pixel”. Ele, basicamente, representa a largura do seu aparelho em pixels quando comparado a um monitor com 96dpi.

Ficou difícil? Vou exemplificar. Pega um monitor grande com 96dpi. Coloque o seu dispositivo móvel na frente dele. Meça quantos pixels da tela o aparelho ocupa. Teremos ai a quantidade de pixels físicos do aparelho. É comum pensarmos em celulares em pé com 320px de largura. Este foi o padrão criado pelo primeiro iPhone, e muitos smartphones o adotaram no começo.

O pixel físico, ou “device-pixel” corresponde ao tamanho da tela do seu aparelho. Isso é diferente da resolução. E, hoje em dia, com a quantidade cada vez maior de tablets e smartphones é cada vez mais difícil encontrar um padrão. Acredito que esta lista do i-skool pode te ajudar nessa tarefa.

graphic-arrays-1-2000-800x494

E, finalmente, o Viewport

Viewport, basicamente, é a porção visível do seu site. Em um desktop ou notebook, o padrão é que o Viewport seja a largura em pixels do seu navegador. Se você redimensionar o browser, verá menos do site. Logo, o Viewport será menor. Por seguir este padrão, conseguimos ver todo o trabalho que fizemos de responsividade em nosso projeto apenas redimensionando a largura da janela do seu browser. Se você está modificando a largura do seu viewport, as @media-queries começam a ser lidas e a mágica acontece.

Em um dispositivo móvel a coisa é bem diferente. Basicamente, não existe como redimensionar a tela do navegador de seu celular. Todos os aplicativos ocupam 100% da largura. No começo dos smartphones, onde ainda não se falava em desenvolvimento responsivo, foi preciso contornar este problema. Seria muito trabalhoso abrir um site e ver apenas uma porção pequena dele. Teria barra de rolagem para todo lado e o conteúdo apresentado seria muito pequeno. Pensando nisso, foi padronizado que o Viewport de mobiles seria de 980px.

Basicamente, se não existe a meta-tag viewport declarada, o dispositivo móvel irá encolher seu site para mostra-lo com a largura de 980px. Em sites que não são responsivos, eles ficam como miniaturas quando acessados pelo mobile. Veja o exemplo do nytimes.com.

nytimes

Essa miniaturização do visual do site irá influenciar em todo o comportamento do seu CSS Pixel!

Simplesmente deixar o site encolhido não é uma boa opção. Os textos encolhidos são ruim de ler, os links pequenos são difíceis de serem tocados. Simplesmente tem uma usabilidade horrível no celular. Para efeito de comparação, note como o site da revista Time, este sim responsivo, é muito mais gostoso e fácil de ler em uma tela pequena:

time1

Vamos brincar de pensar na lógica da coisa: você está em um celular com a largura física de 320px. Este celular tem uma tela de alta resolução, com 326dpi. Isso quer dizer que para cada 1 pixel físico, teremos 2 “dpi pixel”. Logo, a resolução do celular em “dpi pixel” é de 640px. E o nosso viewport está no padrão de 980px. Obviamente que estes 980px não ocupam os mesmos 980px de seu monitor. Cada 1 css pixel dos 980px está menor, para que todos caibam dentro dos 640 dpi pixel do smartphone. Em uma conta rápida descobrimos que, neste caso, 1 css pixel equivale a menos que 1 dpi pixel. Assim, todos os textos, imagens e elementos do seu site ficam menores para caber dentro da tela.

Não se preocupe, você não precisa decorar esta formula e ficar fazendo conta. Saber essas informações é apenas uma curiosidade bacana. O que precisamos ter em mente sempre é: a quantidade de pixel físico do seu aparelho para declarar nos @media-queries e os valores em CSS pixel confortáveis para a leitura e visualização do seu site.

Basicamente, o CSS pixel do seu site (e gostaria de deixar muito grifado aqui a parte “do seu site”, pois isso muda quando pensamos em design de apps) é sempre relativo a viewport que está sendo utilizada.

Especificando a largura do meu viewport

Sabe aquela linha de código que tem bem no começo deste post? Então, é ela que utilizaremos para dizer qual é o nosso campo de visão do navegador.

<meta name="viewport" content="width=device-width,initial-scale=1">

Repare que no parâmetro “width” nós utilizamos a medida “device-width”. Isso avisa ao navegador que a porção visível do meu conteúdo será equivalente a largura dos pixels físicos do meu dispositivo. Em um smartphone com 320px de largura, o meu viewport é de 320px.

Eu posso determinar um valor exato para essa medida. Para isso, é só substituir o “device-width” pelo tamanho desejado. Por exemplo:

<meta name="viewport" content="width=800px,initial-scale=1">

Desta forma, eu irei visualizar apenas 800px da largura do meu layout.

E por que isso é a pedra filosofal para que o meu design responsivo funcione?

Ora, você é um cara antenado. Leu os artigos (12 e 3) da Dani Guerrato sobre Design Responsivo. Assistiu, também, o Devcast que eu dei sobre o tema. E entendeu todo o assunto.

Isso quer dizer que você não usou medidas absolutas para desenvolver seu código. Seja usando um pré-processador ou fazendo todas as contas na unha, você está medindo o seu site em porcentagem (%) e “em”.

Utilizar uma medida absoluta na largura do seu site significa dizer que, ao aplicar um viewport de 320px o browser não irá visualizar o conteúdo inteiro. Se no container do seu site você declarou o valor de 960px, por exemplo, irá aparecer uma barra de rolagem horizontal para que você consiga acessar todo o conteúdo.

Utilizar porcentagem como medida de tamanho de um elemento significa que ele ocupará uma determinada porção da parte visível do seu navegador. Se determinarmos que a largura do site é de 100% em um viewport de 320px ela equivalerá (pasmem) 320px e, em um viewport de 1400px ela equivalerá a (pasmem novamente) 1400px.

iPhone5-dpi-pixel

Declarar o viewport para o seu site é fundamental para o funcionamento dos @media-queries. Quando digo que um @media-querie irá atuar com a max-width: 400px, é da largura do viewport que estamos falando. Ou seja, quando o viewport for menor que 400px, ele irá ler os comandos de CSS do @media-querie.

E o que o CSS pixel tem a ver com isso? Ora, se declaramos que a largura do viewport é a mesma largura do nosso dispositivo móvel, também estamos dizendo que o tamanho do CSS pixel é o mesmo do pixel físico do aparelho. Assim, temos garantidos que 16px em uma tela desktop terá o mesmo tamanho no tablet e smartphone.

Outros parametros do viewport

Se você prestar atenção na linha de código que escrevi neste post, notará que não estou falando só da largura do meu viewport. Também estou dizendo que a escala inicial dele equivale a 1. Veja o valor do parâmetro “initial-scale”:

<meta name="viewport" content="width=device-width,initial-scale=1">

Isso quer dizer que o site não iniciará com o Zoom ativado. Ele irá renderizar os elementos no tamanho do CSS pixel no tamanho real deles.

Dar zoom no celular não irá alterar a viewport. Ele não irá realinhar seus elementos ou ler outros @media-queries. Ele irá apenas aumentar ou diminuir o tamanho de tudo. É comum que, ao dar zoom, o usuário consiga scrollar o site horizontalmente. Isso não significa que a viewport foi alterada, mas sim que a escala dos elementos foi modificada e ocupa um espaço maior na tela.

É possível, através da meta viewport, especificar qual é o máximo e o mínimo de zoom que o usuário pode dar. Também é possível travar o zoom. Isso é um soco no estômago da UX, e eu não recomendo que faça em nenhuma situação. É bem importante deixar o usuário decidir o quão ele quer aproximar ou distanciar os elementos. Muitas vezes um usuário com problemas de visão utilizam muito o zoom para facilitar a leitura.

Para definir qual é o zoom máximo e mínimo que o usuário pode dar, utilizamos o parâmetro “minimum-scale” e “maximum-scale”. No exemplo, o usuário pode aumentar o tamanho dos elementos em até 4 vezes e diminuir em até 0.5 vezes.

<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=0.5,maximum-scale=4">

Para travar o zoom, usamos o “user-scalable=no”

<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">

Mais uma vez: não trave o zoom do usuário. Estou mostrando isso aqui para fins didáticos, mas não é recomendável que você o faça. A não ser que você tenha uma desculpa muito boa e motivos muito convincentes, nunca proíba o usuário de fazer isso.

@viewport

A meta-tag viewport nunca foi uma especificação da W3C. Foi algo criado pela Apple para que, nos primeiros modelos do iPhone, os sites abrissem corretamente. Rapidamente este padrão foi adotado por todos os navegadores. Assim, utilizar esta tag é um padrão não-normativo. Ou seja: apesar de aceito, nunca foi um padrão formal da W3C.

Assumindo que a meta “viewport” é diretamente ligada ao layout e diagramação do site e não à marcação de conteúdo, faz sentido que ela seja um parâmetro de CSS, não de HTML. E é esta regra que a W3C está criando: @viewport. Declaramos ela como no exemplo abaixo:

@viewport {
width: device-width;
zoom: 1;
}

Ao colocarmos isso no começo do nosso CSS, estamos dizendo exatamente a mesma coisa que a meta-tag “<meta name=”viewport” content=”width=device-width, initial-scale=1″>”. A diferença é que agora, ao invés de chamar “initial-scale”, estamos dizendo apenas “zoom”.

Os parâmetros minimum e maximum-scale agora são min- e max-zoom:

@viewport {
width: device-width;
zoom: 1;
min-zoom: 0.5;
max-zoom: 4;
}

E o “user-zoom” é equivalente ao “user-scalable”. Para travar o zoom, basta colocar o “user-zoom” como “fixed”:

@viewport {
width: device-width;
user-zoom: fixed;
}

E, podemos também utilizar o parâmetro “orientation”, que pode ser “auto”, “portrait” ou “landscape”. O que acontecerá é que o seu layout pode ficar fixo em uma única orientação do seu dispositivo móvel (retrato ou paisagem), ou você pode usar o “auto”, onde o seu site irá girar junto com o celular. Por padrão, este parâmetro está sempre em “auto”.

@viewport {
width: device-width;
zoom: 1;
min-zoom: 0.5;
max-zoom: 4;
orientation: portrait;
}

É possível também utilizar o @viewport dentro dos @media-queries. Assim, você pode conseguir uma padronização maior do seu CSS. É especialmente útil se você está fazendo o design adaptivo, não o responsivo.

Veja o exemplo:

@media screen and (min-width: 640px) and (max-width: 1024px) {
@viewport { width: 700px; }
}

Aqui estou dizendo que em telas com a largura maior que 640px e menor que 1024px o viewport será sempre de 700px. Pode ser útil caso você necessite de uma padronização bem grande de seu layout. Pessoalmente, eu não vejo uma grande utilidade disso em design responsivo, mas é interessante quando estamos trabalhando com design adaptivo ou quando pegamos o código de terceiros para torna-lo responsivo. No entanto, eu ainda gosto mais do layout fluindo pixel a pixel.

Infelizmente o @viewport não é aceito em todos os browsers. O primeiro navegador a aceita-lo foi o IE10 (e você gosta de xingar o IE, né?). As versões mais recentes do Opera e do Chrome também o aceitam bem. Acredito que o Firefox não demorará a ser compatível.

Para o IE e o Opera você deve declarar com os respectivos prefixos -ms- e -o-. A sintaxe fica assim:

@-ms-viewport {
width: device-width;
}
 
@-o-viewport {
width: device-width;
}
 
@viewport {
width: device-width;
}

Medidas relativas de Viewport para tipografia (vw e vh)

Este parâmetro é novo, e é suportado pelo IE10+, Firefox 19+, Chrome 20+ e Safari 6+. Dos browsers mobile, apenas pelo Safari do iOS 6 ou superior.

O que este parâmetro diz é que a fonte ocupará uma porcentagem do viewport. Afirmar que a minha font-size tem 1vw significa que ela terá sempre o tamanho de 1% da largura do meu viewport.

A unidade de medida “vw” se refere a largura do viewport e a “vh” a altura. Para facilitar:

  • font-size: 1vw /*a fonte ocupa 1% da largura do meu viewport*/
  • font-size: 1vh /*a fonte ocupa 1% da altura do meu viewport*/
  • font-size: 1vmin /*a fonte tera 1vw ou 1vh. Será escolhido sempre o valor menor*/
  • font-size: 1vmax /*a fonte terá 1vw ou 1vh, dependendo de quem tiver o valor maior*/

Isso é especialmente interessante quando se está trabalhando com um texto que não é possível alterar a quantidade de palavras por linha em seu conteúdo. Aqui temos um vídeo disso funcionando:

Se liga então na hora da revisão

Ufa! Quanta coisa para só uma linha de código. Mas, não se preocupe que preparei uma revisão para auxiliar seus estudos. Vamos lá:

  • Viewport: porção visível do seu site no navegador aberto. Em browsers, por padrão, é sempre a largura da sua janela. Em dispositivos móveis, na sua maioria, é 980px por padrão. Isso pode ser alterado através da meta-tag Viewport ou do parâmetro de CSS @viewport.
  • DPI Pixel ou Pixel Real: Número REAL de pixels na tela do seu dispositivo. Dizer que um aparelho tem 300 dpi significa que ele tem 300 pixels por polegada.
  • Pixel Físico ou Device Pixel: o tamanho físico do seu dispositivo medido em pixels quando comparado a um monitor com 96dpi. Quando declaramos que a largura do viewport será a largura do meu dispositivo (width=device-width), estamos dizendo que a porção visível do site equivale ao tamanho do seu aparelho. Com o número cada vez maior de dispositivos móveis no mercado, existem cada vez mais viewports diferentes.
  • CSS Pixel: representa o pixel declarado no CSS. Varia de tamanho de acordo com o viewport declarado. Quando estamos trabalhando com o viewport do tamanho do dispositivo, 1 CSS pixel equivale a 1 Pixel físico
  • @viewport: parâmetro CSS proposto pela W3C para substituir a meta-tag “viewport”. Por enquanto só é aceita pelo IE10+, Opera e versões mais atuais do Chrome.
  • Unidades de medida relativas ao viewport (vw, vh): são unidades para fontes, indicando que elas ocuparão uma porcentagem do Viewport. 1vw equivale a 1% da largura do Viewport enquanto 1vh representa 1% da altura do viewport.

Concluindo…

Uma linha de código pode fazer toda a diferença. Já conversei com desenvolvedores que fizeram o projeto inteiro responsivo, e muito bem feito, mas que não funcionava no mobile de jeito algum. Quando fomos analisar o código, vimos que estava faltando esta declaração.

Saber como funciona e estar antenado no que acontece de novo é importante para prevermos para onde o webdesign vai evoluir, e estarmos prontos para atender os mais diferentes dispositivos que se conectarão à rede no futuro. Já temos óculos e relógios que navegam pela internet. Imagine o que teremos no futuro! Estudar o desenvolvimento responsivo e todos os seus segredos é a melhor maneira de ficar preparado para o que virá depois.