¿Cómo establecer el ancho y alto de una imagen sin estirarla?

87

Si tengo:

#logo {
    width: 400px;
    height: 200px;
}

entonces

<img id="logo" src="logo.jpg"/>

se estirará para llenar ese espacio. Quiero que la imagen tenga el mismo tamaño, pero que ocupe tanto espacio en el DOM. ¿Tengo que agregar un encapsulado <div>o <span>? Odio agregar marcas para diseñar.

Paul Tarjan
fuente
Si todavía está en Stack Overflow, ¿desea considerar actualizar la respuesta?
Mikemaccana

Respuestas:

116

Sí, necesitas un div encapsulado:

<div id="logo"><img src="logo.jpg"></div>

con algo como:

#logo { height: 100px; width: 200px; overflow: hidden; }

Otras soluciones (relleno, margen) son más tediosas (en el sentido de que debe calcular el valor correcto en función de las dimensiones de la imagen) pero tampoco permiten que el contenedor sea más pequeño que la imagen.

Además, lo anterior se puede adaptar mucho más fácilmente para diferentes diseños. Por ejemplo, si desea la imagen en la parte inferior derecha:

#logo { position: relative; height: 100px; width: 200px; }
#logo img { position: absolute; right: 0; bottom: 0; }
cletus
fuente
5
Puede reemplazar la etiqueta <div> con <figure>: agrega semántica y puede darle un título (<figcaption>), si es necesario. developer.mozilla.org/en-US/docs/Web/HTML/Element/figure
Mateus Leon
Además, si es para uso de marca, en la presentación del sitio web, use <h1> (si es un índice) o <p> (si es otro), aplicando los atributos title y alt a <img>, para que pueda agregar un marcado compatible con SEO . También son elementos de nivel de bloque, como div, y pueden ser envoltorios para la funcionalidad de su cultivo.
Mateus Leon
3
No tenía idea de que Cletus fuera un desarrollador web. Increíble
Piyin
61

2017 respuesta

El ajuste de objetos CSS funciona en todos los navegadores actuales. Permite que el imgelemento sea más grande sin estirar la imagen.

Puede agregar object-fit: cover;a su CSS.

Dante
fuente
2
Probablemente debería mencionar en qué navegadores funciona.
Nathan Tuggy
2
Consulte este enlace para ver la compatibilidad del navegador: caniuse.com/#search=object-fit
Alexee
28

Cargue la imagen como fondo para un div.

En vez de:

<img id='logo' src='picture.jpg'>

hacer

<div id='logo' style='background:url(picture.jpg)'></div>

Todos los navegadores recortarán la parte de la imagen que no encaja.
Esto tiene varias ventajas sobre envolverlo en un elemento cuyo desbordamiento está oculto:

  1. Sin marcado adicional. El div simplemente reemplaza el img.
  2. Centre o establezca fácilmente la imagen en otro desplazamiento. p.ej.url(pic) center top;
  3. Repite la imagen cuando sea lo suficientemente pequeña. (OK, no sé por qué querrías eso)
  4. Establezca un color bg en la misma declaración, aplique fácilmente la misma imagen a varios elementos y todo lo que se aplique a las imágenes bg.

Actualización: esta respuesta es anterior al ajuste de objeto; ahora probablemente debería usar object-fit / object-position.

Sigue siendo útil para navegadores más antiguos, para propiedades adicionales (como repetición de fondo) y para casos extremos (por ejemplo, errores de solución de Chrome con flexbox y posición de objeto y problemas de FF (¿antes?) Con grid + autoheight + object- encajar. Los divs de envoltura en grid / flexbox a menudo dan ... resultados poco intuitivos).

SamGoody
fuente
4
Aquellos que dieron un -1 deberían explicarlo en beneficio de otros usuarios. Personalmente, lo he hecho con excelentes resultados, incluso en IE6 y Safari en iOS.
SamGoody
Solo quería agregar: este es generalmente un buen enfoque. La gente incluso especifica las coordenadas de posición de fondo para las hojas de sprites de imágenes como optimización. Sin embargo, una diferencia es que no tiene el controlador de eventos de error que tiene <img>
badunk
También agregué una clase al div con estos contenidos:background-repeat:no-repeat !important; float:left; width:100px; height:100px;
Nils
2
Algunos navegadores de forma predeterminada no imprimirán imágenes de fondo, por lo que puede que este no sea un buen enfoque si desea permitir que los usuarios impriman esa página.
Bennett McElwee
5
Esto no es semánticamente correcto. Si esto es útil, ¿por qué HTML5 está colocando más etiquetas relacionadas con la imagen, para optimizar la semántica, con figcaption, picture? Use la etiqueta img como fue diseñada y deje de reemplazar todo con <div> s.
Mateus Leon
23

Ajuste de objeto CSS3

No estoy seguro de hasta qué punto ha sido implementado por webkit, IE y firefox. Pero Opera funciona como magia

object-fitfunciona con contenido SVG, pero también se puede lograr el mismo efecto configurando el preserveAspectRatio=""atributo en el propio SVG.

img {
  height: 100px;
  width: 100px;
  -o-object-fit: contain;
}

La demostración de Chris Mills está aquí http://dev.opera.com/articles/view/css3-object-fit-object-position/

el cangrejo
fuente
2
1+ Esto es realmente genial. Lástima que el soporte sea limitado. Parece que Chrome 32 es el primero en admitirlo sin prefijos de proveedores.
Josh Crozier
Esto es fantástico, funciona como un encanto. Solo agregando una sola propiedad se solucionó todo. Solo lo necesitaba para Chrome y funciona. Y sí, sin prefijo de proveedor. Gracias.
whyAto8
9
#logo {
    width: 400px;
    height: 200px;

    /*Scale down will take the necessary specified space that is 400px x 200px without stretching the image*/
    object-fit:scale-down;
}
Manoj Selvin
fuente
7

Haz un div y dale una clase. Luego coloque una imagen en él.

<div class="mydiv">

<img src="location/of/your/image" ></img>

</div>

Establece el tamaño de tu div y hazlo relativo.

    .mydiv {
        position: relative;
        height:300px;
        width: 100%;
        overflow: hidden;
    }

luego estiliza tu imagen

img {
    width: 100%;
    height: auto;
    overflow: hidden;
}

Espero que ayude

Sabba Keynejad
fuente
2

Puede utilizar lo siguiente:

.width100 {
  max-width: 100px;
  height: 100px;
  width: auto;
  border: solid red;
}
<img src="https://www.gravatar.com/avatar/dc48e9b92e4210d7a3131b3ef46eb8b1?s=512&d=identicon&r=PG" class="width100" />

PurTahan
fuente
1

¿Tengo que agregar un <div> o <span> encapsulado?

Creo que lo haces. Lo único que me viene a la mente es el padding, pero para eso tendrías que conocer de antemano las dimensiones de la imagen.

Pekka
fuente
0

puede intentar configurar el relleno en lugar de la altura / ancho.

Bendito Yahu
fuente
0

En lo que puedo pensar es en estirar el ancho o el alto y dejar que cambie de tamaño en relación de aspecto. Habrá algunos espacios en blanco a los lados. Algo parecido a cómo una pantalla ancha muestra una resolución de 1024x768.

mauris
fuente
0

Si usar flexbox es una opción válida para usted (no es necesario que admita navegadores antiguos), verifique mi otra respuesta aquí (que posiblemente sea un duplicado de esta):

Básicamente, necesitaría envolver su etiqueta img en un div y su css se vería así:

.img__container {
    display: flex;
    padding: 15px 12px;
    box-sizing: border-box;
    width: 400px; height: 200px;

    img {
        margin: auto;
        max-width: 100%;
        max-height: 100%;
    }
}
rafaelbiten
fuente
-1

Esta es una pregunta bastante antigua, pero he tenido exactamente el mismo problema molesto en el que todo funcionó bien para Chrome / Edge (con propiedad de ajuste de objeto) pero la misma propiedad css no funcionó en IE11 (ya que no es compatible con IE11), terminé usando el elemento "figura" HTML5 que resolvió todos mis problemas.

Personalmente, no utilicé la etiqueta DIV externa ya que eso no ayudó en absoluto en mi caso, así que evité la DIV externa y simplemente la reemplacé con el elemento 'figura'.

El siguiente código obliga a la imagen a reducirse / reducirse de forma agradable (sin cambiar la relación de aspecto original).

<figure class="figure-class">
  <img class="image-class" src="{{photoURL}}" />
</figure>

y clases css:

.image-class {
    border: 6px solid #E8E8E8;
    max-width: 189px;
    max-height: 189px;
}

.figure-class {
    width: 189px;
    height: 189px;
}
nakul2013
fuente