¿Porcentaje de cambio de tamaño de la imagen CSS de sí mismo?

109

Estoy tratando de cambiar el tamaño de una imagen con un porcentaje de sí mismo. Por ejemplo, solo quiero reducir la imagen a la mitad cambiando su tamaño al 50%. Pero la aplicación width: 50%;cambiará el tamaño de la imagen para que sea el 50% del elemento contenedor (el elemento principal, que tal vez sea, <body>por ejemplo).

La pregunta es, ¿puedo cambiar el tamaño de la imagen con un porcentaje de sí misma sin usar javascript o el lado del servidor? (No tengo información directa del tamaño de la imagen)

Estoy bastante seguro de que no puede hacer esto, pero solo quiero ver si hay una única solución de CSS inteligente. ¡Gracias!

Min Ming Lo
fuente
Tomará el porcentaje del elemento contenedor si lo usara width: <number>%. ¡No creo que haya una forma de hacerlo!
Aniket

Respuestas:

111

Tengo 2 métodos para ti.

Método 1. demostración en jsFiddle

Este método cambia el tamaño de la imagen solo visualmente, no sus dimensiones reales en DOM, y el estado visual después del cambio de tamaño se centra en el medio del tamaño 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');
}​

Nota de compatibilidad del navegador : las estadísticas de los navegadores se muestran en línea encss.

Método 2. demostración en 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 yimg.fakees la misma imagen.
Nota de compatibilidad con el navegador: este método funcionará en todos los navegadores, porque todos los navegadores admiten lascsspropiedades utilizadas en el método.

El método funciona de esta manera:

  1. #wrapy #wrap img.faketener flujo
  2. #wraptiene overflow: hiddenpara que sus dimensiones sean idénticas a la imagen interior ( img.fake)
  3. img.fakees el único elemento dentro #wrapsin absoluteposicionar para que no rompa el segundo escalón
  4. #img_wraptiene absoluteposicionamiento en el interior #wrapy se extiende en tamaño a todo el elemento ( #wrap)
  5. El resultado del cuarto paso es que #img_wraptiene las mismas dimensiones que la imagen.
  6. Al establecer width: 50%en img.normal, su tamaño es 50%de #img_wrap, y por lo tanto 50%del tamaño de la imagen original.
Vladimir Starkov
fuente
Esto no cambia el tamaño de la imagen al 50% de su tamaño original, ahora es el 50% del padre de img_wrap ..
Wesley
Vea mi respuesta actualizada para intentar resolver el problema. ¿Qué piensas?
Wesley
Creo que debería ser posible usar display: none en lugar de la visibilidad, como en mi código. En su ejemplo, el espacio para la imagen oculta falsa todavía está 'reservado', lo que arruina el flujo si coloca contenido a su alrededor
Wesley
es imposible, porque el truco principal está en dos etiquetas anidadas y flotantes.
Vladimir Starkov
1
Sin transform:scale()embargo, la solución tiene un gran problema. No interactúa bien con el modelo de caja CSS. Con lo que quiero decir que no interactúa con él en absoluto , por lo que obtienes un diseño que se ve mal. Ver: jsfiddle.net/kahen/sGEkt/8
kahen
46

HTML:

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

CSS:

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

Esta tiene que ser una de las soluciones más simples que utilizan el enfoque del elemento contenedor.

Cuando se utiliza el enfoque del elemento contenedor, esta pregunta es una variación de esta pregunta . El truco consiste en dejar que el elemento contenedor envuelva la imagen secundaria para que tenga un tamaño igual al de la imagen sin tamaño. Por lo tanto, al establecer la widthpropiedad de la imagen como un valor porcentual, la imagen se escala en relación con su escala original.

Algunas de las otras propiedades shrinkwrapping de habilitación y los valores de propiedad son: float: left/right, position: fixedy min/max-width, como se mencionó en la pregunta vinculada. Cada uno tiene sus propios efectos secundarios, pero display: inline-blocksería una opción más segura. Matt lo ha mencionado float: left/righten su respuesta, pero lo atribuyó erróneamente a overflow: hidden.

Demostración en jsfiddle


Editar: como lo mencionó el troyano , también puede aprovechar el módulo de tamaño intrínseco y extrínseco CSS3 recién introducido :

HTML:

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

CSS:

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

Sin embargo, no todas las versiones de navegadores populares lo admiten en el momento de escribir este artículo .

Comunidad
fuente
@Alguien cómo arreglar los bordes del tramo que no colapsan? violín
CoR
Esto era justo lo que necesitaba ... algo rápido y sencillo, gracias. Lo usé así: HTML: <img src="https://www.google.com/images/srpr/logo11w.png"/> CSS: img { display: inline-block; width: 15%; }
Chnikki
Para futuros lectores: el valor correcto para establecer figurees a width: fit-content;partir de ahora. El soporte del navegador también es mucho mejor hoy.
Dániel Kis-Nagy
12

Probar zoompropiedad

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

Editar: Aparentemente, FireFox no es compatible con la zoompropiedad. Deberías usar;

-moz-transform: scale(0.5);

para FireFox.

Emir Akaydın
fuente
4
No existe una propiedad CSS como "zoom" y no es compatible con nadie más que en IE. Es propiedad de Microsoft y no es estándar.
Rob
9
Desafortunadamente, esta información está desactualizada. Zoom es compatible con los navegadores Internet Explorer, Chrome y Safari en este momento. FireFox y Opera aún no lo admiten. Por eso agregué la parte de edición. IE es el primero en admitirlo, pero no el único.
Emir Akaydın
Según este enlace, Opera parece ser compatible con el zoom también. FireFox es el único que no admite. fix-css.com/2011/05/css-zoom
Emir Akaydın
2
Es por eso que IE ha perdido la mitad de su participación de mercado en los últimos 8 años. Si no puede contar de manera confiable con los navegadores para admitir algo, no tiene puntos en común. La especificación está escrita por los propios proveedores de navegadores. Si no lo ponen allí, no confíe en él o estará escribiendo varias líneas de marcado como lo ha hecho. Esto no es 1998 de nuevo.
Rob
1
No sé si te diste cuenta, pero Internet Explorer, Chrome, Safari y Opera admiten "zoom". esta es la prueba de que "zoom" no es específico del proveedor. solo FireFox se diferencia. así que repito mi pregunta. ¿Cuál es la solución limpia con la propiedad CSS compatible? mi respuesta es la mejor respuesta hasta que alguien encuentre una solución estándar adecuada.
Emir Akaydın
5

Otra solución es utilizar:

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

No se valida porque el srcatributo es obligatorio, pero funciona (excepto en cualquier versión de IE porque srcsetno es compatible).

benface
fuente
2

De hecho, esto es posible, y descubrí cómo por accidente mientras diseñaba mi primer sitio de diseño receptivo a gran 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%; }

El overflow: hidden le da al contenedor alto y ancho, a pesar del contenido flotante, sin usar el truco clearfix. Luego puede colocar su contenido usando márgenes. Incluso puede hacer que el contenedor div sea un bloque en línea.

Mate
fuente
2

Este es un hilo muy antiguo, pero lo encontré mientras buscaba una solución simple para mostrar la captura de pantalla retina (alta resolución) en una pantalla de resolución estándar.

Por tanto, existe una única solución HTML para navegadores modernos:

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

Esto le dice al navegador que la imagen tiene el doble de dimensión del tamaño de visualización previsto. Los valores son proporcionales y no es necesario que reflejen el tamaño real de la imagen. También se pueden usar 2w 1px para lograr el mismo efecto. El atributo src solo lo utilizan los navegadores heredados.

El buen efecto de esto es que muestra el mismo tamaño en retina o pantalla estándar, encogiéndose en esta última.

Max_B
fuente
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 solución usa js y jquery y cambia el tamaño basándose solo en las propiedades de la imagen y no en el padre. Puede cambiar el tamaño de una sola imagen o de un grupo usando parámetros de clase e identificación.

para obtener más información, vaya aquí: https://gist.github.com/jennyvallon/eca68dc78c3f257c5df5

Jenny Vallon
fuente
0

Este es un enfoque no difícil:

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

then in css:
div {
    position: absolute;
}

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

En realidad, la mayoría de las respuestas aquí no escalan la imagen al ancho de sí misma .

Necesitamos tener un ancho y alto de auto en el imgelemento mismo para que podamos comenzar con su tamaño original.

Después de eso, un elemento contenedor puede escalar la imagen por nosotros.

Ejemplo de HTML simple:

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

Y aquí están las reglas de CSS. Yo uso un contenedor absoluto en este 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;
}

Podría modificar el posicionamiento de la imagen con reglas como transform: translate(0%, -50%);.

Floris
fuente
-1

Creo que tienes razón, simplemente no es posible con CSS puro hasta donde yo sé (no entre navegadores, quiero decir).

Editar:

Ok, no me gustó mucho mi respuesta, así que me desconcerté un poco. Podría haber encontrado una idea interesante que podría ayudar ... tal vez ES posible después de todo (aunque no es la cosa más bonita):

Editar: probado y funcionando en Chrome, FF e IE 8 y 9. . No funciona en IE7.

Ejemplo de jsFiddle aquí

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
fuente
su ejemplo cambia el tamaño de la imagen no proporcionalmente
Vladimir Starkov
Su método hace posible reducir la imagen a través del cambio de tamaño de la ventana
Vladimir Starkov
es porque está usando inline-block, por eso el ancho #img_wrapdepende no solo del ancho interno del html, sino también del ancho del contenedor de contexto.
Vladimir Starkov
Por lo que puedo decir, esa pantalla: ninguna imagen no hace nada y se puede eliminar. ¿O me estoy perdiendo algo?
temblor