¿Cómo puedo ajustar el texto alrededor de un div inferior derecho?

Resuelto CodingWithSpike asked hace 15 años • 9 respuestas

Cada vez que intento hacer algo aparentemente simple en CSS, no funciona.

Tengo un div de contenido que contiene una imagen de 460x160. Todo lo que quiero hacer es colocar la imagen en la esquina inferior derecha y rodearla con mi texto.

<div id="contents">
    <img src="..." />
    text text text text text text ...
</div>

Entonces quiero que se vea así:

------------------
| text text text |
| text text text |
| text text -----|
| text text |    |
------------------

Hacerlo con una imagen arriba a la izquierda o arriba a la derecha es pan comido:

#contents img { float:right; }

------------------
| text text |    |
| text text -----|
| text text text |
| text text text |
------------------

Ahora, ¿cómo empujo eso hasta el fondo? Los mejores que se me han ocurrido hasta ahora son:

#contents img { float:right; margin-top: 90%} // really needs to be 100%-160px

------------------
| text text      |
| text text      |
| text text -----|
| text text |    |
------------------

En este caso el texto no se imprime en el margen, por lo que hay un espacio en blanco encima de la imagen.

#contents { position:relative; }
#contents img { position:absolute; right:0; bottom:0; }

-or-

// move the img tag under the text in the html and:
#contents img { float:right; margin-top:-160; }

------------------
| text text text |
| text text text |
| text text -----|
| text text | te |
------------------

En este caso, el texto se imprime encima o debajo de la imagen.

Entonces... ¿cómo puedo lograr esto?

CodingWithSpike avatar Feb 01 '09 06:02 CodingWithSpike
Aceptado

Seguro que parece que se lo han preguntado antes (2003) , y antes (2002) , o antes (2005).

El último enlace en realidad sugiere una solución basada en JavaScript , pero para una solución fija (es decir, no fluida).

Sin embargo, es consistente con otros consejos encontrados.

La única forma de hacerlo es colocar el elemento flotante en algún lugar en el medio del texto. Es imposible que quede perfecto todo el tiempo.

O este :

Consiste en hacer flotar un elemento "empujador" vertical (como img, pero probablemente sea más inteligente usar un div vacío), luego hacer flotar el objeto deseado debajo de él, usando la propiedad clear. El principal problema con este método es que todavía tienes que saber cuántas líneas de texto hay. Sin embargo, hace las cosas MUCHO más fáciles y definitivamente podría codificarse con javascript, solo necesita cambiar la altura del "empujador" a la altura del contenedor menos la altura del flotador (suponiendo que su contenedor no sea fijo/altura mínima) .

De todos modos, como se comenta en este hilo , no hay una solución fácil...


Cletus menciona en los comentarios este hilo de 2003 , que afirma una vez más el hecho de que no se puede lograr fácilmente.
Sin embargo, sí hace referencia a este artículo de Eric Meyer , que se acerca al efecto que desea lograr.

Al comprender cómo se relacionan entre sí los flotadores y el flujo normal, y comprender cómo se puede utilizar la limpieza para manipular el flujo normal alrededor de los flotadores, los autores pueden emplear los flotadores como una herramienta de diseño muy poderosa.
Debido a que los flotantes no fueron diseñados originalmente para usarse en diseño, es posible que sean necesarios algunos trucos para que se comporten según lo previsto. Esto puede involucrar elementos flotantes que contienen flotadores, elementos de "borrado" o una combinación de ambos.


Sin embargo, Chadwick Meyer sugiere en su respuesta una solución basada en el :beforeselector CSS (variación de la respuesta de Leonard ). Funciona aquí .


Actualización de abril de 2021: Temani Afif sugiere en su respuesta usar Flexbox combinado con una forma exterior.
Pero consulte la compatibilidad con versiones anteriores de Flexbox , aunque su compatibilidad con todos los navegadores es bastante buena.

VonC avatar Feb 01 '2009 00:02 VonC

Usar flexbox combinado con un truco de forma exterior ahora es posible con unas pocas líneas de código.

.wrapper {
  display: flex; /* this is needed for the height:100% */
}

.box {
  text-align: justify;
  font-size: 20px;
}

.float {
  float: right; /* shape-outside only apply to float elements */
  height: 100%; /* take all the height */
  margin-left: 15px;
  /* push the image to the bottom */
  display: flex;
  align-items: flex-end;
  /**/
  shape-outside: inset(calc(100% - 100px) 0 0); /* make the text flow on the top free space*/
}
<div class="wrapper">
  <div class="box">
    <div class="float"><img src="https://picsum.photos/id/1069/100/100"></div>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam in dui quis orci ultricies aliquet nec sed enim. Mauris id rutrum nulla, et ornare leo. Donec aliquet malesuada tellus, eu laoreet lectus tincidunt ut. Quisque lacus magna, interdum eu urna
    ac, aliquet gravida orci. Pellentesque gravida urna sit amet nulla suscipit, at venenatis lorem dignissim. Morbi quis nunc eu velit condimentum ornare. Curabitur finibus tincidunt ullamcorper. Pellentesque tincidunt et odio vitae tempus. Praesent
    ac erat ut eros venenatis pulvinar. Pellentesque eu dapibus dui. Ut semper sed enim ut vestibulum. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce vitae elit eget velit porttitor consequat nec sed turpis. Proin libero nisl, egestas
    hendrerit vulputate et, lobortis non nulla. Aenean dui libero, dictum vel nibh eget, tristique egestas enim.
  </div>
</div>
Expandir fragmento

Aquí hay un artículo que escribí sobre este tema con más ejemplos: https://css-tricks.com/float-an-element-to-the-bottom-corner/


Otra versión con menos código y sin contenedor para la imagen:

.wrapper {
  display: flex; /* this is needed for the height:100% */
}

.box {
  text-align: justify;
  font-size: 20px;
}

img {
  float: right; /* shape-outside only apply to float elements */
  height: 100%; /* take all the height */
  width: 100px;
  margin-left: 15px;
  /* push the image to the bottom */
  object-fit: contain;
  object-position: bottom;
  /**/
  shape-outside: inset(calc(100% - 100px) 0 0); /* make the text flow on the top free space*/
}
<div class="wrapper">
  <div class="box">
    <img src="https://picsum.photos/id/1069/100/100">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam in dui quis orci ultricies aliquet nec sed enim. Mauris id rutrum nulla, et ornare leo. Donec aliquet malesuada tellus, eu laoreet lectus tincidunt ut. Quisque lacus magna, interdum eu urna
    ac, aliquet gravida orci. Pellentesque gravida urna sit amet nulla suscipit, at venenatis lorem dignissim. Morbi quis nunc eu velit condimentum ornare. Curabitur finibus tincidunt ullamcorper. Pellentesque tincidunt et odio vitae tempus. Praesent
    ac erat ut eros venenatis pulvinar. Pellentesque eu dapibus dui. Ut semper sed enim ut vestibulum. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce vitae elit eget velit porttitor consequat nec sed turpis. Proin libero nisl, egestas
    hendrerit vulputate et, lobortis non nulla. Aenean dui libero, dictum vel nibh eget, tristique egestas enim.
  </div>
</div>
Expandir fragmento

Temani Afif avatar Apr 20 '2021 14:04 Temani Afif

Bueno... esta es una publicación bastante antigua, pero luché y me salí con la mía con una pequeña solución. Necesitaba tener una imagen alineada a la derecha y exactamente a 170 píxeles desde la parte superior. Y necesita que el texto fluya en la parte superior, izquierda e inferior de la imagen. Entonces, lo que hice fue crear uno de 0 px de ancho, con 170 px de alto y flotar a la derecha. Entonces la imagen flotaría y se aclararía a la derecha y ¡listo!

<!-- I used CSS, but inline will serve well here -->
<div style="float: right; width: 0px; height: 170px"></div>
<div style="float: right; clear: right"><img src="..." /></div>
text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text
text text text text text text
Expandir fragmento

Funcionó bastante bien :)

Mauricio Morales avatar Aug 23 '2011 22:08 Mauricio Morales

La solución más simple que encontré es envolver img dentro de un elemento div y luego usar los valores padding-top y margin-bottom para alinearlo.

Este es mi CSS

.contentDiv  .bottomRight img{
  height: 130px;
  float:right;
  padding-top: 60px;
  margin-bottom: -10px;
  }

y aquí está el HTML

<div class="contentDiv">
 <h1>If you are seeing this and reading it, then all is working well.</h1>
 <div class="bottomRight">
    <img class="bottomRight" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==">
 </div>
</div>

La razón por la que el relleno y el margen funcionaron para mí es porque los uso dentro del elemento principal "contentDiv" para ajustar automáticamente la altura del div según el contenido. No estoy seguro si es de alguna utilidad.

Galimbek Sagidenov avatar Jan 07 '2015 09:01 Galimbek Sagidenov