Porcentagem de redimensionamento da imagem CSS de si mesma?

109

Estou tentando redimensionar uma imagem com uma porcentagem de si mesma. Por exemplo, eu só quero reduzir a imagem pela metade, redimensionando-a para 50%. Mas a aplicação width: 50%;irá redimensionar a imagem para 50% do elemento do recipiente (o elemento pai que pode ser, <body>por exemplo).

A questão é: posso redimensionar a imagem com uma porcentagem dela sem usar javascript ou do lado do servidor? (Não tenho informações diretas do tamanho da imagem)

Tenho certeza de que você não pode fazer isso, mas só quero ver se há uma solução apenas para CSS inteligente. Obrigado!

Min Ming Lo
fonte
Ele ocupará a porcentagem do elemento que o contém, se você usar width: <number>%. Eu não acho que haja uma maneira de fazer isso!
Aniket

Respostas:

111

Eu tenho 2 métodos para você.

Método 1. demonstração em jsFiddle

Este método redimensiona a imagem apenas visual, não nas dimensões reais no DOM, e o estado visual após o redimensionamento centralizado no meio do tamanho original.

html:

<img class="fake" src="example.png" />

css:

img {
  -webkit-transform: scale(0.5); /* Saf3.1+, Chrome */
     -moz-transform: scale(0.5); /* FF3.5+ */
      -ms-transform: scale(0.5); /* IE9 */
       -o-transform: scale(0.5); /* Opera 10.5+ */
          transform: scale(0.5);
             /* IE6–IE9 */
             filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.9999619230641713, M12=-0.008726535498373935, M21=0.008726535498373935, M22=0.9999619230641713,SizingMethod='auto expand');
}​

Navegador suporte nota: estatísticas navegadores mostrou inlinecss.

Método 2. demonstração em jsFiddle

html:

<div id="wrap">
    <img class="fake" src="example.png" />
    <div id="img_wrap">
        <img class="normal" src="example.png" />
    </div>
</div>

css:

#wrap {
    overflow: hidden;
    position: relative;
    float: left;
}

#wrap img.fake {
    float: left;
    visibility: hidden;
    width: auto;
}

#img_wrap {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
}

#img_wrap img.normal {
    width: 50%;
}​

Nota: img.normal eimg.fakeé a mesma imagem.
Nota de suporte de navegador: este método funcionará em todos os navegadores, porque todos os navegadores suportamcsspropriedades usadas no método.

O método funciona desta maneira:

  1. #wrape #wrap img.faketem fluxo
  2. #wraptem de overflow: hiddenmodo que suas dimensões sejam idênticas à imagem interna ( img.fake)
  3. img.fakeé o único elemento interno #wrapsem absoluteposicionamento para não quebrar a segunda etapa
  4. #img_wraptem absoluteposicionamento interno #wrape se estende em tamanho para todo o elemento ( #wrap)
  5. O resultado da quarta etapa é que #img_wraptem as mesmas dimensões da imagem.
  6. Ao definir width: 50%em img.normal, seu tamanho é 50%de #img_wrap, e, portanto, 50%do tamanho da imagem original.
Vladimir Starkov
fonte
Isso não redimensiona a imagem para 50% de seu tamanho original, agora é 50% do pai de img_wrap ..
Wesley
Veja minha resposta atualizada para uma tentativa de resolver o problema. O que você acha?
Wesley
Acho que deveria ser possível usar display: none em vez da visibilidade, como no meu código. Em seu exemplo, o espaço para a imagem oculta falsa ainda está "reservado", o que atrapalha o fluxo se você colocar conteúdo em torno dele
Wesley
é impossível, porque o truque principal está em duas tags aninhadas e flutuadas.
Vladimir Starkov
1
A transform:scale()solução tem um grande problema. Não interage bem com o modelo de caixa CSS. Com isso quero dizer que ele não interage com ele de forma alguma , então você obtém um layout que parece totalmente errado. Veja: jsfiddle.net/kahen/sGEkt/8
kahen
46

HTML:

<span>
    <img src="example.png"/>
</span>

CSS:

span {
    display: inline-block;
}
img {
    width: 50%;
}

Essa deve ser uma das soluções mais simples usando a abordagem de elemento de contêiner.

Ao usar a abordagem de elemento de contêiner, esta pergunta é uma variação da pergunta . O truque é deixar o elemento contêiner encolher a imagem filho, para que tenha um tamanho igual ao da imagem sem tamanho. Assim, ao definir a widthpropriedade da imagem como um valor percentual, a imagem é redimensionada em relação à sua escala original.

Algumas das outras propriedades permitindo shrinkwrapping e valores de propriedade são: float: left/right, position: fixede min/max-width, como mencionado na pergunta ligada. Cada um tem seus próprios efeitos colaterais, mas display: inline-blockseria uma escolha mais segura. Matt mencionou float: left/rightem sua resposta, mas ele erroneamente atribuiu isso a overflow: hidden.

Demo no jsfiddle


Edit: Conforme mencionado pelo trojan , você também pode aproveitar as vantagens do módulo de dimensionamento intrínseco e extrínseco do CSS3 recém-introduzido :

HTML:

<figure>
    <img src="example.png"/>
</figure>

CSS:

figure {
    width: intrinsic;
}
img {
    width: 50%;
}

No entanto, nem todas as versões populares de navegadores o suportam no momento da escrita .

Comunidade
fonte
@Qualquer um, como consertar o não colapso das fronteiras? violino
CoR,
Isso era exatamente o que eu precisava ... algo rápido e simples, obrigado. Eu usei assim: HTML: <img src="https://www.google.com/images/srpr/logo11w.png"/> CSS: img { display: inline-block; width: 15%; }
Chnikki
Para futuros leitores: o valor correto a ser definido figureé a width: fit-content;partir de agora. O suporte do navegador também está muito melhor hoje.
Dániel Kis-Nagy
12

Experimente zoompropriedade

<img src="..." style="zoom: 0.5" />

Edit: Aparentemente, o FireFox não oferece suporte à zoompropriedade. Você deveria usar;

-moz-transform: scale(0.5);

para FireFox.

Emir Akaydın
fonte
4
Não existe uma propriedade CSS como "zoom" e não é compatível com ninguém além do IE. É uma coisa proprietária da Microsoft e fora do padrão.
Rob
9
Infelizmente, esta informação está desatualizada. O zoom é compatível com os navegadores Internet Explorer, Chrome e Safari no momento. FireFox e Opera ainda não o suportam. É por isso que adicionei a parte de edição. O IE é o primeiro a oferecer suporte, mas não o único.
Emir Akaydın
De acordo com este link, o Opera parece suportar zoom também. FireFox é o único que não oferece suporte. fix-css.com/2011/05/css-zoom
Emir Akaydın
2
É por isso que o IE perdeu metade de sua participação no mercado nos últimos 8 anos. Se você não pode contar com os navegadores para oferecer suporte a algo, você não tem um terreno comum. A especificação é escrita pelos próprios fornecedores do navegador. Se eles não o colocarem lá, não confie nele ou você estará escrevendo várias linhas de marcação como fez. Não estamos em 1998 novamente.
Rob
1
Não sei se você percebeu, mas o "zoom" é compatível com Internet Explorer, Chrome, Safari e Opera. esta é a prova de que o "zoom" não é específico do fornecedor. apenas o FireFox é diferente. então eu repito minha pergunta. qual é a solução limpa com propriedade css compatível? minha resposta é a melhor resposta até que alguém encontre uma solução padrão adequada.
Emir Akaydın
5

Outra solução é usar:

<img srcset="example.png 2x">

Não validará porque o srcatributo é obrigatório, mas funciona (exceto em qualquer versão do IE porque srcsetnão é suportado).

Benface
fonte
2

Na verdade, isso é possível, e descobri o quanto por acidente, enquanto projetava meu primeiro site de design responsivo em grande escala.

<div class="wrapper">
  <div class="box">
    <img src="/logo.png" alt="">
  </div>
</div>

.wrapper { position:relative; overflow:hidden; }

.box { float:left; } //Note: 'float:right' would work too

.box > img { width:50%; }

O overflow: hidden dá ao wrapper altura e largura, apesar do conteúdo flutuante, sem usar o hack do clearfix. Você pode então posicionar seu conteúdo usando as margens. Você pode até tornar o div do wrapper um bloco embutido.

Matt
fonte
2

Este é um tópico muito antigo, mas eu o encontrei enquanto procurava uma solução simples para exibir a captura de tela de retina (alta resolução) em uma tela de resolução padrão.

Portanto, há uma solução somente HTML para navegadores modernos:

<img srcset="image.jpg 100w" sizes="50px" src="image.jpg"/>

Isso informa ao navegador que a imagem tem o dobro da dimensão do tamanho de exibição pretendido. Os valores são proporcionais e não precisam refletir o tamanho real da imagem. Pode-se usar 2w 1px também para obter o mesmo efeito. O atributo src é usado apenas por navegadores legados.

O bom efeito disso é que ele exibe o mesmo tamanho na retina ou na tela padrão, encolhendo na última.

Max_B
fonte
0
function shrinkImage(idOrClass, className, percentShrinkage){
'use strict';
    $(idOrClass+className).each(function(){
        var shrunkenWidth=this.naturalWidth;
        var shrunkenHeight=this.naturalHeight;
        $(this).height(shrunkenWidth*percentShrinkage);
        $(this).height(shrunkenHeight*percentShrinkage);
    });
};

$(document).ready(function(){
    'use strict';
     shrinkImage(".","anyClass",.5);  //CHANGE THE VALUES HERE ONLY. 
});

Esta solução usa js e jquery e redimensiona com base apenas nas propriedades da imagem e não no pai. Ele pode redimensionar uma única imagem ou um grupo com base em parâmetros de classe e id.

para mais, acesse: https://gist.github.com/jennyvallon/eca68dc78c3f257c5df5

Jenny Vallon
fonte
0

Esta não é uma abordagem difícil:

<div>
    <img src="sample.jpg" />
</div>

then in css:
div {
    position: absolute;
}

img, div {
   width: ##%;
   height: ##%;
}
nickthehero
fonte
0

Na verdade, a maioria das respostas aqui realmente não dimensionar a imagem à largura de si .

Precisamos ter uma largura e altura automática no imgpróprio elemento para que possamos começar com seu tamanho original.

Depois disso, um elemento de contêiner pode dimensionar a imagem para nós.

Exemplo de HTML simples:

<figure>
    <img src="[email protected]" />
</figure>

E aqui estão as regras CSS. Eu uso um contêiner absoluto neste caso:

figure {
    position: absolute;
    left: 0;
    top: 0;
    -webkit-transform: scale(0.5); 
    -moz-transform: scale(0.5);
    -ms-transform: scale(0.5); 
    -o-transform: scale(0.5);
    transform: scale(0.5);
    transform-origin: left;
} 

figure img {
    width: auto;
    height: auto;
}

Você pode ajustar o posicionamento da imagem com regras como transform: translate(0%, -50%);.

Floris
fonte
-1

Acho que você está certo, simplesmente não é possível com CSS puro, tanto quanto eu sei (não cross-browser, quero dizer).

Editar:

Ok, eu não gostei muito da minha resposta, então fiquei um pouco confuso. Posso ter encontrado uma ideia interessante que poderia ajudar .. talvez seja possível afinal (embora não seja a coisa mais bonita de todas):

Editar: Testado e funcionando no Chrome, FF e IE 8 e 9. . Não funciona no IE7.

Exemplo de jsFiddle aqui

html:

<div id="img_wrap">
    <img id="original_img" src="http://upload.wikimedia.org/wikipedia/en/8/81/Mdna-standard-edition-cover.jpg"/>
    <div id="rescaled_img_wrap">
        <img id="rescaled_img" src="http://upload.wikimedia.org/wikipedia/en/8/81/Mdna-standard-edition-cover.jpg"/>
    </div>
</div>

css:

#img_wrap {
    display: inline-block;       
    position:relative;    
}

#rescaled_img_wrap {
    width: 50%;
}
#original_img {
    display: none;
}
#rescaled_img {
    width: 100%;
    height: 100%;
}
Wesley
fonte
seu exemplo de redimensionamento de imagem não proporcional
Vladimir Starkov
Seu método torna possível diminuir a imagem através do redimensionamento da janela
Vladimir Starkov
é porque você está usando inline-block, é por isso que a largura #img_wrapdepende não apenas da largura interna do html, mas também da largura do contêiner de contexto.
Vladimir Starkov
Pelo que eu posso dizer, aquele display: none image não faz nada e pode ser removido. Ou eu estou esquecendo de alguma coisa?
trêmulo