Una imagen ocupa un rectángulo, y el texto que la rodea respeta ese rectángulo. Las propiedades de este documento sirven para dos cosas distintas: decidir qué parte de la foto se ve y decidir por dónde pasa el texto. No son lo mismo y conviene no confundirlas.
Cuando a una imagen se le fija un ancho y un alto que no coinciden con su proporción,
hay que decidir qué hacer con la diferencia. Eso es object-fit.
fillcovercontainla misma foto y la misma caja, con los tres valores
<div class="tira"> <figure> <img class="rellenar" src="IMG/retrato-rizado.jpg" alt="Retrato"> <figcaption>fill</figcaption> </figure> <figure> <img class="cubrir" src="IMG/retrato-rizado.jpg" alt="Retrato"> <figcaption>cover</figcaption> </figure> <figure> <img class="contener" src="IMG/retrato-rizado.jpg" alt="Retrato"> <figcaption>contain</figcaption> </figure> </div>
body {
font-family: Verdana, sans-serif;
font-size: .9rem;
line-height: 1.6;
}
.tira {
display: flex;
gap: 10px;
}
figure {
flex: 1;
margin: 0;
}
figcaption {
font-size: .8rem;
color: #555;
padding-top: .3rem;
}
/* la misma caja para las tres */
.tira img {
width: 100%;
height: 11rem;
background: #eee;
}
.rellenar { object-fit: fill; }
.cubrir { object-fit: cover; }
.contener { object-fit: contain; }
Hay una propiedad hermana, object-position, que decide qué parte se
conserva al recortar. Por defecto es el centro, y en un retrato eso puede cortar la
cabeza: object-position: top lo arregla.
En lugar de dar un alto en píxeles, se le da a la caja una proporción y el alto sale del ancho. Así la caja sigue siendo fluida.
Se escribe con dos números separados por una barra: 1 / 1 es cuadrada,
16 / 9 apaisada, 3 / 4 vertical.
tres proporciones, todas con cover
<div class="tira"> <figure> <img class="cuadrada" src="IMG/naturaleza-abetos.jpg" alt="Bosque"> <figcaption>1 / 1</figcaption> </figure> <figure> <img class="apaisada" src="IMG/naturaleza-abetos.jpg" alt="Bosque"> <figcaption>16 / 9</figcaption> </figure> <figure> <img class="vertical" src="IMG/naturaleza-abetos.jpg" alt="Bosque"> <figcaption>3 / 4</figcaption> </figure> </div>
body {
font-family: Verdana, sans-serif;
font-size: .9rem;
line-height: 1.6;
}
.tira {
display: flex;
gap: 10px;
align-items: flex-start;
}
figure { flex: 1; margin: 0; }
figcaption { font-size: .8rem; color: #555; padding-top: .3rem; }
.tira img {
width: 100%; /* el ancho lo pone la columna */
object-fit: cover; /* y la foto llena la caja sin deformarse */
}
.cuadrada { aspect-ratio: 1 / 1; }
.apaisada { aspect-ratio: 16 / 9; }
.vertical { aspect-ratio: 3 / 4; }
Estrecha la ventana: las tres encogen y conservan su forma. Ese es el motivo de
usar aspect-ratio en vez de una altura escrita.
Redondea las esquinas. Admite una medida para las cuatro, o cuatro medidas, y con
50% convierte un cuadrado en círculo y un rectángulo en elipse.
cuatro formas con la misma propiedad
<div class="tira"> <figure> <img class="r1" src="IMG/retrato-contraluz.jpg" alt="Retrato"> <figcaption>12px</figcaption> </figure> <figure> <img class="r2" src="IMG/retrato-contraluz.jpg" alt="Retrato"> <figcaption>50%</figcaption> </figure> <figure> <img class="r3" src="IMG/retrato-contraluz.jpg" alt="Retrato"> <figcaption>una esquina</figcaption> </figure> <figure> <img class="r4" src="IMG/retrato-contraluz.jpg" alt="Retrato"> <figcaption>hoja</figcaption> </figure> </div>
body {
font-family: Verdana, sans-serif;
font-size: .9rem;
line-height: 1.6;
}
.tira { display: flex; gap: 10px; }
figure { flex: 1; margin: 0; }
figcaption { font-size: .8rem; color: #555; padding-top: .3rem; }
.tira img {
width: 100%;
aspect-ratio: 1 / 1;
object-fit: cover;
}
.r1 { border-radius: 12px; }
.r2 { border-radius: 50%; } /* en una caja cuadrada, un círculo */
.r3 { border-radius: 40% 0 0 0; } /* arriba-izquierda, arriba-derecha,
abajo-derecha, abajo-izquierda */
.r4 { border-radius: 50% 0 50% 0; }
border-radius solo redondea. clip-path recorta con la forma que
se quiera: un círculo, un polígono de los lados que haga falta, una elipse.
circle(50%)circle(50% at 30% 40%).ellipse(40% 50%)polygon(...)0% 0% es la
esquina de arriba a la izquierda y 100% 100% la de abajo a la derecha. El
último se une con el primero.inset(10% round 1rem)Lo que queda fuera del recorte no se dibuja, pero la caja sigue ocupando el mismo sitio. Para el resto de la página, la imagen sigue siendo un rectángulo. De eso se encarga la propiedad siguiente.
círculo, triángulo, rombo y una forma libre
<div class="tira"> <figure> <img class="c1" src="IMG/ciudad-amanecer.jpg" alt="Ciudad"> <figcaption>circle</figcaption> </figure> <figure> <img class="c2" src="IMG/ciudad-amanecer.jpg" alt="Ciudad"> <figcaption>triángulo</figcaption> </figure> <figure> <img class="c3" src="IMG/ciudad-amanecer.jpg" alt="Ciudad"> <figcaption>rombo</figcaption> </figure> <figure> <img class="c4" src="IMG/ciudad-amanecer.jpg" alt="Ciudad"> <figcaption>libre</figcaption> </figure> </div>
body {
font-family: Verdana, sans-serif;
font-size: .9rem;
line-height: 1.6;
}
.tira { display: flex; gap: 10px; }
figure { flex: 1; margin: 0; }
figcaption { font-size: .8rem; color: #555; padding-top: .3rem; }
.tira img {
width: 100%;
aspect-ratio: 1 / 1;
object-fit: cover;
}
.c1 { clip-path: circle(50%); }
.c2 { clip-path: polygon(50% 0%, 100% 100%, 0% 100%); }
.c3 { clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%); }
.c4 { clip-path: polygon(20% 0%, 100% 0%, 100% 75%, 75% 100%, 0% 100%, 0% 25%); }
Escribir un polígono a mano resulta laborioso. Existen editores visuales que generan la declaración arrastrando los vértices; se localizan buscando «clip-path maker».
Esta es la que de verdad cambia la maqueta. clip-path recorta lo que se ve;
shape-outside dice por dónde tiene que pasar el texto de al
lado.
Tiene dos condiciones, y las dos son obligatorias:
float: left o float: right.
Sin float no hace absolutamente nada.el texto rodea el círculo
<img class="redonda" src="IMG/bn-caballo.jpg" alt="Caballo">
<p>Una fotografía ocupa un rectángulo. Casi siempre eso basta, pero hay composiciones en las que el rectángulo estorba: un retrato en un listado de personas, una pieza que tiene que encajar con otras, un texto que debería acompañar a la imagen en vez de quedarse a su lado. CSS permite recortar la caja y, además, decirle al texto por dónde tiene que pasar.</p>
<p>El recorte no cambia el archivo ni el tamaño que ocupa la imagen en la página: solo decide qué parte de ella se dibuja. Lo que queda fuera sigue ahí, invisible, igual que el trozo de foto que se sale de un marco.</p>
body {
font-family: Verdana, sans-serif;
font-size: .9rem;
line-height: 1.6;
}
.redonda {
float: left; /* obligatorio */
width: 12rem; /* con sus medidas */
aspect-ratio: 1 / 1;
object-fit: cover;
margin: 0 1.2rem 1rem 0;
clip-path: circle(50%); /* lo que se ve */
shape-outside: circle(50%); /* por dónde pasa el texto */
}
Las dos propiedades llevan el mismo valor, y esa es la forma normal
de usarlas: una recorta la imagen y la otra hace que el texto siga ese mismo contorno. Si
solo se pone clip-path, la foto se ve redonda pero el texto sigue trazando un
cuadrado alrededor.
Hay un ajuste útil, shape-margin, que separa el texto del contorno. El
margin normal solo separa del rectángulo.
un polígono, con el texto siguiendo la diagonal
<img class="cuna" src="IMG/naturaleza-valle.jpg" alt="Valle">
<p>Una fotografía ocupa un rectángulo. Casi siempre eso basta, pero hay composiciones en las que el rectángulo estorba: un retrato en un listado de personas, una pieza que tiene que encajar con otras, un texto que debería acompañar a la imagen en vez de quedarse a su lado. CSS permite recortar la caja y, además, decirle al texto por dónde tiene que pasar.</p>
<p>El recorte no cambia el archivo ni el tamaño que ocupa la imagen en la página: solo decide qué parte de ella se dibuja. Lo que queda fuera sigue ahí, invisible, igual que el trozo de foto que se sale de un marco.</p>
body {
font-family: Verdana, sans-serif;
font-size: .9rem;
line-height: 1.6;
}
.cuna {
float: right;
width: 14rem;
aspect-ratio: 3 / 4;
object-fit: cover;
margin-left: 1rem;
clip-path: polygon(100% 0%, 100% 100%, 0% 100%);
shape-outside: polygon(100% 0%, 100% 100%, 0% 100%);
shape-margin: 1rem; /* separa el texto del contorno, no del rectángulo */
}
Las anteriores cortan en seco: un píxel se ve o no se ve. mask-image permite
que la imagen se vaya desvaneciendo, porque usa una segunda imagen como
plantilla de opacidad: donde la plantilla es opaca, la foto se ve; donde es transparente,
desaparece; y donde hay medio tono, se ve a medias.
Lo habitual es usar un degradado como plantilla, que no es un archivo sino algo que CSS sabe dibujar.
desvanecido por abajo y en círculo
<div class="tira"> <figure> <img class="m1" src="IMG/naturaleza-arroyo.jpg" alt="Arroyo"> <figcaption>hacia abajo</figcaption> </figure> <figure> <img class="m2" src="IMG/naturaleza-arroyo.jpg" alt="Arroyo"> <figcaption>en círculo</figcaption> </figure> <figure> <img class="m3" src="IMG/naturaleza-arroyo.jpg" alt="Arroyo"> <figcaption>por los dos lados</figcaption> </figure> </div>
body {
font-family: Verdana, sans-serif;
font-size: .9rem;
line-height: 1.6;
}
.tira { display: flex; gap: 10px; }
figure { flex: 1; margin: 0; }
figcaption { font-size: .8rem; color: #555; padding-top: .3rem; }
.tira img {
width: 100%;
aspect-ratio: 1 / 1;
object-fit: cover;
}
/* negro = se ve ; transparente = no se ve */
.m1 { mask-image: linear-gradient(to bottom, black 55%, transparent); }
.m2 { mask-image: radial-gradient(circle, black 45%, transparent 70%); }
.m3 { mask-image: linear-gradient(to right,
transparent, black 25%, black 75%, transparent); }
El color del degradado es indiferente: solo cuenta su opacidad. Se declara
black por convención.
En navegadores antiguos puede hacer falta repetir la declaración con el prefijo
-webkit-mask-image.
| Lo que quiero | La propiedad |
|---|---|
| Que la foto llene una caja sin deformarse | object-fit: cover |
| Que la caja tenga una forma fija y se adapte al ancho | aspect-ratio |
| Esquinas redondeadas o un círculo | border-radius |
| Cualquier otra forma | clip-path |
| Que el texto rodee esa forma | shape-outside con float |
| Que el borde se desvanezca en vez de cortarse | mask-image |
clip-path cambia lo que se ve;
shape-outside cambia por dónde pasa el texto. Para que
las dos cosas coincidan hay que escribirlas las dos, con el mismo valor.shape-outside sin float no hace nada.alt: la forma es decoración, el
contenido es la foto.Las fotos son de Pexels, con licencia libre: se pueden usar y modificar sin pagar y sin citar la fuente. Citarla no es obligatorio, pero es lo correcto, y aquí sirve además de ejemplo de cómo se hace.
naturaleza-arroyo.jpg — Arroyo de montaña en un bosque de Trentino. Foto de Pluto91 Operatic, ficha en Pexels.naturaleza-abetos.jpg — Arroyo entre abetos bajo un cielo nublado. Foto de Snapwire, ficha en Pexels.naturaleza-valle.jpg — Valle con niebla al amanecer. Foto de Johannes Plenio, ficha en Pexels.retrato-contraluz.jpg — Retrato de mujer a contraluz. Foto de Asep Awaludin, ficha en Pexels.retrato-rizado.jpg — Primer plano de mujer con pelo rizado. Foto de Eric Quinones, ficha en Pexels.bn-caballo.jpg — Caballo en blanco y negro. Foto de Ruhul Amin Akash, ficha en Pexels.ciudad-amanecer.jpg — Rascacielos de Ciudad de México al amanecer. Foto de Yuriko Salazar Luna, ficha en Pexels.