28

I know there are a few questions about similar topics but they mostly amount to floating the div/image. I need to have the image (and div) positioned absolutely (off to the right) but I simply want the text flow around it. It works if I float the div but then I can't position it where I want. As it is the text just flows behind the picture.

<div class="post">
    <div class="picture">
        <a href="/user/1" title="View user profile.">
            <img src="http://www.neatktp.com/sites/default/files/photos/BlankPortrait.jpg" alt="neatktp&#039;s picture" title="neatktp&#039;s picture"  />
        </a>
    </div>
    <span class='print-link'></span> 
    <p>BlahBlahBlahBlahBlahBlahBlahBlahBlahBlahBlahBlahBlahBlahBlah.</p>
    <p>BlahBlahBlahBlahBlahBlahBlahBlahBlahBlahBlahBlahBlahBlahBlah.</p>
</div>

Is an example of the HTML

With the CSS being:

.picture img {
    background: #fff;
    border: 1px #ddd solid;
    padding: 2px;
    float: right;
}
    
.post .picture {
    display: block;
    height: auto;
    position: absolute;
    right: -10px;
    top: -10px;
    width: auto;
}

.post {
    border: 1px solid #FFF;
    border-bottom: 1px solid #e8ebec;
    padding: 37px 22px 11px;
    position: relative;
    z-index: 4;
}

It's a Drupal theme so none of this code is mine, it's just that it's not fully working when it comes to putting a picture there.

Adrià Vilanova
  • 384
  • 4
  • 20
Paul Murphy
  • 283
  • 1
  • 3
  • 6

10 Answers10

30

I know this is an older question but I came across it looking to do what I believe you were trying to. I've made a solution using the :before CSS selector, so it's not great with ie6-7 but everywhere else you should be good.

Basically, putting my image in a div I can then add a long thing float block before hand to bump it down and the text wraps merrily around it!

img {
  float:right;  
  clear:both;
  width: 50% ;
  margin: 30px -50px 10px 10px ;
}
.rightimage:before {
  content: '' ;
  display:block;
  float: right;
  height: 200px;

}

You can check it out here:

http://codepen.io/atomworks/pen/algcz

Leonard
  • 648
  • 6
  • 19
  • 1
    I just quickly tested this in the latest versions of Chrome, FF, Safari and it works exactly as expected! I knew it'd have to be a div solution like this, but you took ALL of the guess work out of it so far. Trying to put two right anchored images, by the way, produces unexpected results so far... – Cyprus106 Nov 22 '14 at 19:59
  • This is the best answer. I spent hours looking for this until I figured it out independently. I wish that I'd found this answer first. – Justin Putney May 08 '15 at 00:47
  • 1
    If I'm not mistaken, doesn't this do just the same as float:right? theres no absolute positioning in this solution – Sean_A91 Apr 27 '16 at 14:57
  • Yes, it's an alternative to the absolute positioning method that allows text to wrap around it which absolute would not do. – Leonard Apr 28 '16 at 11:33
  • Downvoted because that's just normal floating behaviour and doesn't answer the question. – wortwart Jul 20 '16 at 10:02
  • Yes it is normal floating behaviour with the addition of the trick of using a pseudo selector to affect it's vertical positioning. It doesn't answer how to do it with absolute, that is correct, but it does address being able to position the container even though it is not as flexible in terms of layout. That said for most design uses a left or right align with the text flowing around it would be the choice. Did you also choose to down vote the selected answer suggesting to revisit floats for similar reasons? – Leonard Jul 21 '16 at 02:27
  • 1
    Upvoted as it is a good alternative to position: absolute, and allows essentially what the original question is asking for. – Joundill Jul 25 '16 at 01:16
  • Much appreciated, glad people are getting some use from it! – Leonard Jul 25 '16 at 04:34
  • Where is position absolute in your example? – Alex G Nov 01 '16 at 20:47
  • @AlexG Please see previous comments. TL;DR - It's not there. – Leonard Nov 04 '16 at 08:33
  • 1
    This is brilliant, and works perfectly. Yes, it's just normal floating behavior, but so what? It has the desired effect with minimum fooling around, and is instantly readable in the source css. – aholub Jan 30 '18 at 22:37
  • How on Earth did you figure this out!? This works exactly as expected, though I didn't realize at first that both elements needed the same class AND you also had to style the img element before putting a pseudo element on the class that has to be on both the parent container and image. Mind = Blown. Would give you a handful of my karma if I could. – HaulinOats Sep 27 '18 at 18:37
  • This is pure genius. And I can confirm it works in 2022 with a floated element using shape-outside, positioned at the bottom of the text using the height of the :before element. Sweet! – maguijo Apr 21 '22 at 19:00
6

Absolute positioning takes the element out of the normal document flow, and therefore it does not interact with the other elements. Perhaps you should revist how to position it using float instead, and ask about it here on Stack Overflow if you get stuck :)

akamike
  • 2,148
  • 13
  • 16
  • 1
    Thanks might have to take you up on that if using negative margins don't work out for me. – Paul Murphy Dec 16 '09 at 20:52
  • 6
    Just a comment: I find it terrible that there is no way to cause text to flow around a positioned object because in many cases there is no way to position objects at extreme positions depending on screen size when the containing div is packed with a lot of objects, other than by using position:absolute. In that case, implementing java queries seems to be the only option... That is a shortfall in css3 in my opinion... – Damian Green Nov 25 '15 at 05:27
4

When you position a div absolutely, you're effectively taking it out of the document flow, so the other elements will act as if it's not there.

To get around this, you can instead use margins:

.myDivparent
{
   float: left;
   background: #f00;
}

.myDivhascontent
{
   margin-left: 10px; /*right, bottom, top, whichever you need*/
}

Hopefully that will do the trick :)

lucasnadalutti
  • 5,818
  • 1
  • 28
  • 48
Kyle
  • 65,599
  • 28
  • 144
  • 152
  • in my situation, using joomla it's hard to edit the slideshow module thanks Kyle :) – FDI Jan 20 '11 at 15:09
4

As mentioned by @Kyle Sevenoaks, you are taking absolute positioned content out of the document flow.

As far as I can see, the only way to have the parent div wrap the absolute positioned contents, is to use javascript to set the width and height on each change.

jeroen
  • 91,079
  • 21
  • 114
  • 132
  • thank jeroen, how can I find the hieght of the element does not have a style height on it ? – FDI Jan 20 '11 at 15:14
  • @FDI I use jQuery for my slide-shows and it would be something like `var height = $("slide_show_element").height();`. That gets the calculated height of you inner element and you can apply that to the outer / floated element: `$("floated_element").height(height);` – jeroen Jan 20 '11 at 15:29
3

I think the best option is to add an additional div after the float content, but still inside the parent to clear previous styles.

<div class="clear"></div>

And CSS:

.clear
{clear:both;}
Chris G
  • 431
  • 1
  • 7
  • 8
3

In my opinon, the "Absolute" trait is poorly named, because its position is actually relative to the first parent whos position is not static

<div class="floated">
 <div style="position: relative;">
  <div class="AbsoluteContent">
    stuff
  </div>
 </div>
</div>
Matt
  • 3,778
  • 2
  • 28
  • 32
  • If you want a specific code answer, you have to post some of the code you are working with – Matt Jan 20 '11 at 15:17
  • 1
    your idea very clear I changed the code as you describe and did not work,did you test it ? please let me know if you want to see my code very thanks Matt – FDI Jan 20 '11 at 15:29
3

I needed a similar solution to float a pullout quote (not an image) which would have variable length text inside. The pullout quote needed to be inserted into the HTML at the top (outside the flow of the text) and float down into the content with text that wraps around it. Modifying Leonard's answer above, there is a really simple way to do this!

See Codepen for Working Example: https://codepen.io/chadwickmeyer/pen/gqqqNE

CSS

/* This creates a space to insert the pullout content into the flow of the text that follows */
.pulloutContainer:before {
  content: '' ;
  display:block;
  float: right;
  /* The height is essentially a "margin-top" to push the pullout Container down page */
  height: 200px;
}

.pulloutContainer q {
  float:left;  
  clear:both;
  /* This can be a set width or percent, if you want a pullout that floats left or right or full full width */
  width: 30%;
  /* Add padding as you see fit */
  padding: 50px 20px;
}

HTML

<div id="container">

  <div class="pulloutContainer">
      <!-- Pullout Container Automatically Adjusts Size -->
      <q>Lorem ipsum dolor sit amet, consectetur adipiscing elit Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet, consectetur adipiscing elit Lorem ipsum dolor sit amet.</q>
    </div>

    <div class="content">
       <h1>Sed Aucteor Neque</h1>
       <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam in dui mauris. Vivamus hendrerit arcu sed erat molestie vehicula. Sed auctor neque eu tellus rhoncus ut eleifend nibh porttitor. Ut in nulla enim. Phasellus molestie magna non est.</

      ...INSERT MORE TEXT HERE...

  </div>
</div>
Chadwick Meyer
  • 7,041
  • 7
  • 44
  • 65
1

Absolute positioning does not let you wrap text. You have to use float and position using margin or padding.

  • Ah was hoping this would not be the case as applying I thought negative margin could cause problems in other browsers. Thanks for the the reply. – Paul Murphy Dec 16 '09 at 20:52
0

Here's a trick that might work for some:

if you have a container packed with a lot of objects, and you want that positioned object to appear up high in certain cases, and down lower in other cases (various screen sizes for example), then just intersperse copies of the object multiple times in your html, either inline(-block), or with float, and then display:none the items you dont want to see according to the conditions you need.

Here is a JSFiddle to show exactly what I mean: JSFiddle of right positioning high and low

Note: I added color only for effect. Except for the class names, the subject-1 and subject-2 divs are otherwise exact copies of each other.

Damian Green
  • 633
  • 2
  • 8
  • 13
0

There is an easy fix to this problem. It's using white-space: nowrap;

<div style="position:relative">
 <div style="position: absolute;top: 100%; left:0;">
  <div style="white-space:nowrap; width: 100%;">
    stuff
  </div>
 </div>
</div>

For example I was making a dropdown menu for a navigation so the setup I was using is

<ul class="submenu" style="position:absolute; z-index:99;">
   <li style="width:100%; display:block;">
      <a href="#" style="display: block;width: 100%;white-space: nowrap;">Dropdown link here</a>
   </li>
<ul>

Image Examples

Without Nowrap enabled

With Nowrap enabled

Also if you still can't figure it out check out the dropdowns on bootstrap templates which you can google. Then find out how they work because they are using position absolute and getting the text to take up 100% width without wrapping the text.

Community
  • 1
  • 1