Una inmersión profunda en el ajuste de objetos y el tamaño de fondo en CSS

Publicado: 2022-03-10
Resumen rápido ↬ En este artículo, veremos cómo funcionan object-fit y background-size , cuándo podemos usarlos y por qué, junto con algunos casos de uso práctico y recomendaciones. Sumerjámonos.

No siempre podemos cargar imágenes de diferentes tamaños para un elemento HTML. Si usamos un ancho y una altura que no son proporcionales a la relación de aspecto de la imagen, la imagen puede comprimirse o estirarse. Eso no es bueno, y se puede resolver con object-fit para un elemento img o usando background-size .

Primero, definamos el problema. Considere la siguiente figura:

Una foto bonita y una imagen comprimida en comparación.
Una foto atractiva que se aprieta cuando se usa en un componente de tarjeta. (Vista previa grande)

¿Por qué está pasando esto?

Una imagen tendrá una relación de aspecto y el navegador llenará el cuadro contenedor con esa imagen. Si la relación de aspecto de la imagen es diferente al ancho y la altura especificados para ella, el resultado será una imagen comprimida o estirada.

Esto lo vemos en la siguiente figura:

Una foto bonita y una imagen estirada en comparación.
La relación de aspecto de la imagen es diferente a la del cuadro que la contiene, y la imagen se estira. (Vista previa grande)

La solución

No siempre necesitamos agregar una imagen de diferente tamaño cuando la relación de aspecto de la imagen no se alinea con el ancho y la altura del elemento contenedor. Antes de sumergirnos en las soluciones CSS, quiero mostrarte cómo solíamos hacer esto en las aplicaciones de edición de fotos:

Ejemplo de una imagen con los bordes superior e inferior recortados en una máscara
Primero, centraríamos la imagen verticalmente y luego recortaríamos una máscara. Esto conserva la relación de aspecto de la imagen y evita que se comprima. (Vista previa grande)

Ahora que entendemos cómo funciona eso, veamos cómo funciona esto en el navegador. ( Alerta de spoiler: ¡es más fácil! )

Ajuste object-fit CSS

La propiedad object-fit define cómo se debe cambiar el tamaño del contenido de un elemento reemplazado, como img o video , para que se ajuste a su contenedor. El valor predeterminado para object-fit es fill , lo que puede provocar que una imagen se comprima o estire.

Repasemos los posibles valores.

¡Más después del salto! Continúe leyendo a continuación ↓

Valores posibles para object-fit

object-fit: contain

En este caso, la imagen cambiará de tamaño para ajustarse a la relación de aspecto de su contenedor. Si la relación de aspecto de la imagen no coincide con la del contenedor, aparecerá en formato de pantalla ancha.

ajuste de objeto: contener
Al usar object-fit: contain , la imagen se colocará en formato letterbox o se redimensionará en consecuencia. (Vista previa grande)

object-fit: cover

Aquí, la imagen también se redimensionará para ajustarse a la relación de aspecto de su contenedor, y si la relación de aspecto de la imagen no coincide con la del contenedor, se recortará para que encaje.

ajuste de objeto: cubierta
Al usar object-fit: cover , la imagen se recortará para ajustarse o se redimensionará en consecuencia. (Vista previa grande)

object-fit: fill

Con esto, la imagen cambiará de tamaño para ajustarse a la relación de aspecto de su contenedor, y si la relación de aspecto de la imagen no coincide con la del contenedor, se comprimirá o estirará. No queremos eso.

ajuste de objeto: relleno
Al usar object-fit: fill , la imagen se comprimirá, estirará o cambiará de tamaño según corresponda. (Vista previa grande)

object-fit: none

En este caso, la imagen no se redimensionará en absoluto, ni se estirará ni se apretará. Funciona como el valor de la cover , pero no respeta la relación de aspecto de su contenedor.

ajuste de objeto: ninguno
Al usar object-fit: none , la imagen no cambiará de tamaño si sus dimensiones no son las mismas. (Vista previa grande)

Además de object-fit , también tenemos la propiedad object-position , que es responsable de posicionar una imagen dentro de su contenedor.

Valores posibles para object-position

La propiedad object-position funciona de manera similar a la propiedad background-position CSS:

posición del objeto centro, izquierda, derecha
La mayoría de las veces, se utiliza el valor predeterminado (es decir, `centro` o `50% 50%`). (Vista previa grande)

Las palabras clave top e bottom también funcionan cuando la relación de aspecto del cuadro contenedor es verticalmente más grande:

posición del objeto arriba y abajo
Comparando object-position: top (izquierda) y object-position: bottom (derecha). (Vista previa grande)

background-size CSS

Con background-size , la primera diferencia es que estamos tratando con el fondo, no con un elemento HTML ( img ).

Valores posibles para background-size

Los valores posibles para background-size son auto , contain y cover .

background-size: auto

Con auto , la imagen permanecerá en su tamaño predeterminado:

tamaño de fondo: automático
Tenga en cuenta que el tamaño predeterminado a veces puede resultar en una imagen borrosa (si es demasiado pequeña). (Vista previa grande)

background-size: cover

Aquí, la imagen cambiará de tamaño para que quepa en el contenedor. Si las relaciones de aspecto no son las mismas, la imagen se enmascarará para que encaje.

tamaño de fondo: portada
Cuando use background-size: cover , asegúrese de considerar las proporciones de una imagen. (Vista previa grande)

background-size: contain

En este caso, se cambiará el tamaño de la imagen para que quepa en el contenedor. Si las relaciones de aspecto están desactivadas, la imagen aparecerá en formato de pantalla ancha como se muestra en el siguiente ejemplo:

tamaño de fondo: contener
background-size: contain cambia el tamaño de la imagen para que quepa en el contenedor. (Vista previa grande)

En cuanto a background-position , es similar a cómo funciona object-position . La única diferencia es que la posición predeterminada de object-position es diferente a la de background-position .

Cuándo no usar object-fit o background-size

Si al elemento o a la imagen se le asigna una altura fija y tiene aplicado background-size: cover u object-fit: cover , habrá un punto en el que la imagen será demasiado ancha, por lo que se perderán detalles importantes que podrían afectar la forma el usuario percibe la imagen.

Considere el siguiente ejemplo en el que a la imagen se le da una altura fija:

 .card__thumb { height: 220px; }
Un ejemplo en el que una imagen es demasiado ancha porque tiene una altura fija y el contenedor de la tarjeta es demasiado ancho
La imagen que se muestra a la derecha es demasiado ancha porque tiene una altura fija mientras que el contenedor de la tarjeta es demasiado ancho. (Vista previa grande)

Si el contenedor de la tarjeta es demasiado ancho, dará como resultado lo que vemos a la derecha (una imagen demasiado ancha). Eso es porque no estamos especificando una relación de aspecto.

Solo hay una de dos soluciones para esto. El primero es usar el truco del relleno para crear una relación intrínseca.

 .card__thumb { position: relative; padding-bottom: 75%; height: 0; } .card__thumb img { position: absolute; left: 0; top: 0; width: 100%; height: 100%; object-fit: cover; }

La segunda solución es usar la nueva propiedad CSS aspect-ratio . Utilizándolo, podemos hacer lo siguiente:

 .card__thumb img { aspect-ratio: 4 / 3; }

Nota : Ya he escrito sobre la propiedad aspect-ratio en detalle en caso de que quieras aprender sobre ella: "Aprendamos sobre la relación de aspecto en CSS".

Casos de uso y ejemplos

Avatares de usuario

Un caso de uso perfecto para object-fit: cover son los avatares de los usuarios. La relación de aspecto permitida para un avatar suele ser cuadrada. Colocar una imagen en un contenedor cuadrado podría distorsionar la imagen.

Un avatar de usuario sin ajuste de objeto y con ajuste de objeto: portada
Una comparación de un avatar de usuario sin object-fit de object-fit: cover . (Vista previa grande)
 .c-avatar { object-fit: cover; }

Lista de logotipos

Listar los clientes de una empresa es importante. A menudo usaremos logotipos para este propósito. Debido a que los logotipos tendrán diferentes tamaños, necesitamos una forma de cambiar su tamaño sin distorsionarlos.

Afortunadamente, object-fit: contain es una buena solución para eso.

 .logo__img { width: 150px; height: 80px; object-fit: contain; }
Una lista de logotipos: Airbnb, Domino's Pizza, Apple Pay, Amazon
Usar object-fit: contain puede ayudarnos a cambiar el tamaño de los logotipos de los clientes sin distorsionarlos. (Vista previa grande)

Miniatura del artículo

Este es un caso de uso muy común. Es posible que el contenedor de la miniatura de un artículo no siempre tenga una imagen con la misma relación de aspecto. Este problema debería solucionarlo el sistema de gestión de contenido (CMS) en primer lugar, pero no siempre lo hace.

 .article__thumb { object-fit: cover; }
Miniatura del artículo
Ajuste de miniaturas de artículos con un poco de ayuda de object-fit: cover . (Vista previa grande)

Antecedentes del héroe

En este caso de uso, la decisión de utilizar un elemento img o un fondo CSS dependerá de lo siguiente:

  • ¿Es importante la imagen? Si CSS está deshabilitado por algún motivo, ¿querríamos que el usuario viera la imagen?
  • ¿O el propósito de la imagen es meramente decorativo?

Según nuestra respuesta, podemos decidir qué función usar. Si la imagen es importante :

Caso de uso con antecedentes de héroe
Supongamos que la imagen es importante, porque es un sitio web relacionado con la comida. (Vista previa grande)
 <section class="hero"> <img class="hero__thumb" src="thumb.jpg" alt="" /> </section>
 .hero { position: relative; } .hero__thumb { position: absolute; left: 0; top: 0; width: 100%; height: 100%; object-fit: cover; }

Si la imagen es decorativa , podemos ir con background-image :

 .hero { position: relative; background-image: linear-gradient(to top, #a34242, rgba(0,0,0,0), url("thumb.jpg"); background-repeat: no-repeat; background-size: cover; }

El CSS es más corto en este caso. Asegúrese de que cualquier texto colocado sobre la imagen sea legible y accesible.

Agregar un fondo a una imagen con object-fit: contain

¿Sabías que puedes agregar un color de fondo a img ? Nos beneficiaríamos de eso cuando también usemos object-fit: contain .

En el siguiente ejemplo, tenemos una cuadrícula de imágenes. Cuando las relaciones de aspecto de la imagen y el contenedor son diferentes, aparecerá el color de fondo.

 img { object-fit: contain; background-color: #def4fd; }
Agregar un color de fondo a una imagen con ajuste de objeto: contiene
Podemos usar object-fit: contain para agregar un color de fondo a una imagen. (Vista previa grande)

Elemento de vídeo

¿Alguna vez has necesitado un video como fondo? Si es así, entonces probablemente quería que ocupara todo el ancho y alto de su padre.

 .hero { position: relative; background-color: #def4fd; } .hero__video { position: aboslute; left: 0; top: 0; width: 100%; height: 100%; }
Una figura donde el video no cubre el fondo del héroe.
El valor object-fit predeterminado para el elemento de video es contain . Como puede ver aquí, el video no cubre el fondo del héroe, aunque tiene position: absolute , width: 100% y height: 100% . (Vista previa grande)

Para que cubra por completo el ancho y el alto de su padre, debemos anular el valor object-fit predeterminado:

 .hero__video { /* other styles */ object-fit: cover; }
Una figura donde el video cubre todo el ancho y el alto de su padre.
Ahora el video cubre todo el ancho y alto de su padre. (Vista previa grande)

Conclusión

Como hemos visto, tanto object-fit como background-size son muy útiles para manejar diferentes proporciones de imagen. No siempre tendremos control sobre la configuración de las dimensiones perfectas para cada imagen, y ahí es donde brillan estas dos características de CSS.

Un recordatorio amistoso sobre las implicaciones de accesibilidad de elegir entre un elemento img y un fondo CSS: si la imagen es puramente decorativa, elija un fondo CSS. De lo contrario, una img es más adecuada.

Espero que hayas encontrado útil este artículo. Gracias por leer.