Telas de retina, imagens de fundo de alta resolução

102

Isso pode soar como uma pergunta boba.

Se eu usar este snippet CSS para monitores regulares (onde box-bg.pngé 200px por 200px);

.box{
    background:url('images/box-bg.png') no-repeat top left;
    width:200px;
    height:200px
}

e se eu usar uma consulta de mídia como esta para visar telas de retina (com a imagem @ 2x sendo a versão de alta resolução);

@media (-webkit-min-device-pixel-ratio: 2), 
(min-resolution: 192dpi) { 

    .box{background:url('images/[email protected]') no-repeat top left;}
}

Preciso dobrar o tamanho do .boxdiv para 400 px por 400 px para corresponder à nova imagem de fundo de alta resolução?

Dean Elliott
fonte
Qual é a dimensão de images/[email protected]? Faça a pergunta para ficar absolutamente claro.
TMS de

Respostas:

184

Preciso dobrar o tamanho da div .box para 400px por 400px para corresponder à nova imagem de fundo de alta resolução

Não, mas você precisa definir a background-sizepropriedade para corresponder às dimensões originais:

@media (-webkit-min-device-pixel-ratio: 2), 
(min-resolution: 192dpi) { 

    .box{
        background:url('images/[email protected]') no-repeat top left;
        background-size: 200px 200px;
    }
}

EDITAR

Para adicionar um pouco mais a esta resposta, aqui está a consulta de detecção de retina que costumo usar:

@media
only screen and (-webkit-min-device-pixel-ratio: 2),
only screen and (   min--moz-device-pixel-ratio: 2),
only screen and (     -o-min-device-pixel-ratio: 2/1),
only screen and (        min-device-pixel-ratio: 2),
only screen and (                min-resolution: 192dpi),
only screen and (                min-resolution: 2dppx) { 

}

- Fonte

NB. Este min--moz-device-pixel-ratio:não é um erro de digitação. É um bug bem documentado em certas versões do Firefox e deve ser escrito assim para oferecer suporte a versões mais antigas (anteriores ao Firefox 16). - Fonte


Como @LiamNewmarch mencionado nos comentários abaixo, você pode incluir o background-sizeem sua backgrounddeclaração abreviada da seguinte forma:

.box{
    background:url('images/[email protected]') no-repeat top left / 200px 200px;
}

No entanto, eu pessoalmente não aconselharia o uso da forma abreviada, pois não é compatível com iOS <= 6 ou Android, tornando-a não confiável na maioria das situações.

Nabo
fonte
alguma dica que você daria para definir o tamanho do plano de fundo para um plano de fundo de página inteira? eu sei a largura do componente x, mas e quanto ao y?
Randy L
3
@ theOther Nesse caso, você provavelmente deseja usar background-size: cover;. Isso manterá a proporção de aspecto enquanto "cobre" todo o fundo com a imagem.
Turnip
4
Se você quiser, você pode integrar a background-sizepropriedade para o backgroundassim: background: url('images/[email protected]') no-repeat top left / 200px 200px. Observe que os navegadores que não oferecem suporte background-sizeirão ignorar esta regra.
Liam Newmarch
2
@LiamNewmarch Eu não recomendaria que eu, já que o Android não entenda a forma abreviada
Turnip
@ 3rror404 ah ok, bastante justo. Obrigado!
Liam Newmarch
16

Aqui está uma solução que também inclui dispositivos de alto (er) DPI ( MDPI ) > ~ 160 pontos por polegada, como alguns dispositivos não iOS (ex: Google Nexus 7 2012 ):

.box {
    background: url( 'img/box-bg.png' ) no-repeat top left;
    width: 200px;
    height: 200px;
}
@media only screen and ( -webkit-min-device-pixel-ratio: 1.3 ),
       only screen and (    min--moz-device-pixel-ratio: 1.3 ),
       only screen and (      -o-min-device-pixel-ratio: 2.6/2 ), /* returns 1.3, see Dev.Opera */
       only screen and (         min-device-pixel-ratio: 1.3 ),
       only screen and ( min-resolution: 124.8dpi ),
       only screen and ( min-resolution: 1.3dppx ) {

       .box {
           background: url( 'img/[email protected]' ) no-repeat top left / 200px 200px;
       }

}

Como @ 3rror404 incluiu em sua edição após receber feedback dos comentários, existe um mundo além do Webkit / iPhone. Uma coisa que me incomoda com a maioria das soluções até agora, como aquela referenciada como fonte acima no CSS-Tricks , é que isso não é totalmente levado em consideração.
A fonte original já foi mais longe.

Como exemplo, a tela do Nexus 7 (2012) é uma tela TVDPI com um estranho device-pixel-ratiode1.325 . Ao carregar as imagens com resolução normal, elas são aumentadas por interpolação e, portanto, borradas. Para mim, a aplicação desta regra na consulta de mídia para incluir esses dispositivos obteve o melhor feedback do cliente.

Volker E.
fonte
1
Uma imagem 2x de cada dimensão tem exatamente 4x os pixels (por exemplo, pode-se teoricamente esperar que tenha 4x de tamanho), enquanto 1,325 * 1,325 suporta apenas 1,755625 aumento em pixels. Acho que a qualidade da imagem seria perdida de qualquer maneira com 1,325dppi, mas se você for HiDPI, o cliente simplesmente terá que esperar mais pelo carregamento da página, terá maior consumo de energia redimensionando a imagem (e as tabelas do Nexus 7 são bastante conhecido por reinicializações aleatórias) e consomem mais largura de banda. Então, eu recomendo continuar @2xsendo servido apenas para 2dppx+ clientes.
cnst
3

Se você planeja usar a mesma imagem para retina e tela não retina, aqui está a solução. Digamos que você tenha uma imagem de 200x200e dois ícones na linha superior e dois ícones na linha inferior. Portanto, são quatro quadrantes.

.sprite-of-icons {
  background: url("../images/icons-in-four-quad-of-200by200.png") no-repeat;
  background-size: 100px 100px /* Scale it down to 50% rather using 200x200 */
}

.sp-logo-1 { background-position: 0 0; }

/* Reduce positioning of the icons down to 50% rather using -50px */
.sp-logo-2 { background-position: -25px 0 }
.sp-logo-3 { background-position: 0 -25px }
.sp-logo-3 { background-position: -25px -25px }

Escalando e posicionando os ícones do sprite em 50% do valor real, você pode obter o resultado esperado.


Outra solução de mixin SCSS útil por Ryan Benhase .

/****************************
 HIGH PPI DISPLAY BACKGROUNDS
*****************************/

@mixin background-2x($path, $ext: "png", $w: auto, $h: auto, $pos: left top, $repeat: no-repeat) {

  $at1x_path: "#{$path}.#{$ext}";
  $at2x_path: "#{$path}@2x.#{$ext}";

  background-image: url("#{$at1x_path}");
  background-size: $w $h;
  background-position: $pos;
  background-repeat: $repeat;

  @media all and (-webkit-min-device-pixel-ratio : 1.5),
  all and (-o-min-device-pixel-ratio: 3/2),
  all and (min--moz-device-pixel-ratio: 1.5),
  all and (min-device-pixel-ratio: 1.5) {
    background-image: url("#{$at2x_path}"); 
  }
}

div.background {
  @include background-2x( 'path/to/image', 'jpg', 100px, 100px, center center, repeat-x );
}

Para mais informações sobre o mixin acima, LEIA AQUI .

Syed
fonte