Floating an image to the bottom right with text wrapping around

Create a spacer element with float: right and height equal to the height of the content minus the height of the image. Then use float: right and clear: right on the image:

<div class="spacer"></div>
<img class="bottomRight" src="" />
<div class="content"></div>
.spacer {
    height: calc(100% - 200px);
    width: 0px;
    float: right;
}
.bottomRight {
    height: 200px;
    float: right;
    clear: right;
}

http://cssdesk.com/bLNWs

My demo uses fixed dimensions in the container element. Since that is rarely a realistic case, it probably makes more sense to use JavaScript to size the spacer. Call this function, passing a reference to the spacer element when the document is ready and during the window.onresize event.

function sizeSpacer(spacer) {
    spacer.style.height = 0;
    var container = spacer.parentNode;
    var img = spacer.nextElementSibling || spacer.nextSibling;
    var lastContentNode = container.children[container.children.length - 1];
    var h = Math.max(0, container.clientHeight - img.clientHeight);
    spacer.style.height = h + "px";
    while (h > 0 && img.getBoundingClientRect().bottom > lastContentNode.getBoundingClientRect().bottom) {
        spacer.style.height = --h + "px";
    }
    if (lastContentNode.getBoundingClientRect().bottom > img.getBoundingClientRect().bottom) {
        spacer.style.height = ++h + "px";
    }
}

This function works (see the demo), and can be reworked for jQuery or your library of choice. It's not meant to be plug-in quality code, but serves to illustrate the concept.

jsfiddle.net/gilly3/xLr7eacp

Edit: I created a jQuery plugin version (github | jsFiddle demo) that supports floating bottom left or bottom right. It also supports specifying which element to align the bottom with.

By the way, I didn't bother trying to support IE7.


Possible CSS Solution: (only tested in chrome)

It looks like this might work using CSS3's flex box properties and a combination of background-image properties. I was able to get it pretty close using only CSS. (It works but needs a little tweaking) Also, this may not be ideal cause I did have to change the markup a little bit to make this work. But its probably worth a shot if you are looking for a pure CSS solution.

Here is a Demo -> http://jsfiddle.net/ADSH2/

New Markup: (not to much different)

<section >
  <h2>Some Heading:</h2>
  <p>...</p>
  <p class="last">
     <span class="image"></span>
  </p>
</section>

CSS:

.last {
    display:inline-flex;
    flex-direction:row;
}
.image {
    padding:5px 0 0 5px;
    width:100%;
    background-image:url("http://dribbble.s3.amazonaws.com/users/200359/screenshots/758731/stackoverflow_logo.png");
    background-size:100%;
    background-repeat:no-repeat;
    background-position:bottom right;
}

Resources:

  1. http://css-tricks.com/snippets/css/a-guide-to-flexbox/
  2. http://dev.w3.org/csswg/css-flexbox-1/

I think the future way how to tackle this problem will be with CSS Exclusions.

CSS Exclusions extend the notion of content wrapping previously limited to floats. ... Elements layout their inline content in their content area and wrap around the exclusion areas in their associated wrapping context (--excerpts from the spec)

This msdn article also explains exclusions

...web authors can now wrap text so that it completely surrounds elements, thereby avoiding the traditional limitations of floats. Instead of limiting elements to floating either to the left or right relative to their position in the document flow, CSS Exclusions can be positioned at a specified distance from the top, bottom, left, or right sides of a containing block, while remaining part of the document flow.

Ironically, to date this only works in IE10 (look for wrap-flow:both here)

Check out this fiddle in IE10+

This is what the code looks like:

 <div class="container">
    <div class="exclusion">
        Exclusion positioned at bottom right hand side of text.
    </div>
    <div class="dummy_text">
        <p>text here</p>
    </div>
</div> 

CSS

.container {
    font-size: small;
    background: aqua;
    position: relative;
}

.exclusion {

    -ms-wrap-flow: both;
    -ms-wrap-margin: 10px;
    z-index: 1;
    position:absolute;
    right:0;
    bottom:0; /* try fiddling with this. For some reason bottom: -10px (or the like) works better here */
    width: 150px;
    height: 100px;
    background: url(http://placehold.it/150x100) no-repeat;
}

So as you can see - even though the exclusion is positioned absolutely - it still acts like a float - in this case: float bottom right.

Regarding browser support:

Check out this site which shows which properties are supported by the browsers (to date: only IE10+ supports wrap-flow:both )

PS: Latest updates concerning CSS exclusions (and other simlar modules like CSS regions and CSS Shapes) can be found at the Adobe Web Platform Team Blog

Tags:

Html

Css

Image