homepage Welcome to WebmasterWorld Guest from 54.211.7.174
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Become a Pro Member

Visit PubCon.com
Home / Forums Index / Code, Content, and Presentation / CSS
Forum Library, Charter, Moderator: open

CSS Forum

    
Positioning a DIV at the bottom of a parent DIV
Joff




msg:3600671
 3:58 pm on Mar 14, 2008 (gmt 0)

I've got a DIV which holds the main content of the page, so can vary in height. The DIV also has a background image which I've positioned at the bottom right corner.

When text reaches the the image, it obviously flows across it, so I've thought about positioning an empty DIV of the same height as the background, to force text to wrap around it.

Is this possible and if so, any pointers as to where to start? I've experimented with the position attribute in CSS but without knowing the height of the main content DIV, I can't work out where the top of my blocking DIV will be.

 

fside




msg:3600718
 4:34 pm on Mar 14, 2008 (gmt 0)

What is a 'blocking DIV'? You can set z-index of a fixed position element so that the text goes 'under'. If you want text wrapping around an image, why not just place an image there, instead of using a no-repeat background (I assume you're using)?

Joff




msg:3600767
 5:15 pm on Mar 14, 2008 (gmt 0)

I just made up the term 'blocking DIV' as I didn't know how else to describe it :) And yes, I've got the image set as a no-repeat bg.

I don't want the text to go under/over the image, I want it to flow around it. Would an image placed at the end of the text sit right though? Surely it would only work when the text flows right to the end of the container? I should have mentioned, the container has a min-height too.

I'll give your suggestion a whirl though, so cheers for the reply.

Joff




msg:3600786
 5:28 pm on Mar 14, 2008 (gmt 0)

fside - no that's not going to work (at least not how I'm trying it). The floated image won't sit in the lower right corner unless it's inserted right at the end of any text, and then it will still be subject to the padding on the container instead of sitting flush with the edge.

If the image is inserted anywhere else in the text, then the image appears too high.

MarkFilipak




msg:3601091
 10:40 pm on Mar 14, 2008 (gmt 0)

I think this is what you want (but please read notes below, first).
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<style type="text/css">
#content{position:relative; width:45em; border:solid black 1px; padding:1em}
#imgMask{float:right}
#img{position:absolute;right:0;bottom:0}
#imgMask,#img{width:7.5em;height:7.5em}
</style>
</head>
<body>
<div id="content">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Praesent aliquam, justo convallis luctus
rutrum, erat nulla fermentum diam, at nonummy quam ante ac quam.

<img id='imgMask' src='pixel.gif'/>

Maecenas urna purus, fermentum id,
molestie in, commodo porttitor, felis. Nam blandit quam ut lacus. Quisque ornare risus quis ligula.
Phasellus tristique purus a augue condimentum adipiscing. Aenean sagittis. Etiam leo pede, rhoncus
venenatis, tristique in, vulputate at, odio. Donec et ipsum et sapien vehicula nonummy. Suspendisse
potenti. Fusce varius urna id quam. Sed neque mi, varius eget, tincidunt nec, suscipit id, libero.
In eget purus. Vestibulum ut nisl. Donec eu mi sed turpis feugiat feugiat. Integer turpis arcu,
pellentesque eget, cursus et, fermentum ut, sapien. Fusce metus mi, eleifend sollicitudin, molestie
id, varius et, nibh. Donec nec libero.
<img id='img' src=''/>
</div>
</body>
</html>

Notes: Do layout in 'em', not 'px'. Have pixel.gif ready. It is a 1px, blank gif. Set the src attribute of #img to your image URL. Change {width:...;height:...} as needed. Then load the page in your browser. Position #imgMask by trial and error -- pick a word-space in the middle of a text line so that, at different text sizes, the float will be less than 1/2 line off -- play with moving #imgMask around and you'll understand. Since the page is laid out in 'em', whatever text & text size the visitor is using will be OK.

[edited by: SuzyUK at 12:31 pm (utc) on Mar. 16, 2008]
[edit reason] minimised sidescroll [/edit]

fside




msg:3601154
 12:47 am on Mar 15, 2008 (gmt 0)

I get it. You're wondering about 'sandbag' divisions (or 'text wrappers', or whatever you'd call them). You can position the image just fine with background (or position:absolute). But you get no text-wrapping as a result.

Ultimately, you're wondering about 'float:bottom', were there such a thing. That is, float:right would work, here, if the last paragraph were right at the bottom of the div and the image were nested in that last paragraph. But if there's empty space at the bottom, because of min-height, the wrapping won't match the image, which is always right at the bottom (as a no-repeat background or as an absolutely positioned IMG, neither of which cause text wrapping). Rather you need a 'sandbag', and also the IMG itself. The 'sandbag' will push the IMG down, to suit.

Also a general question, it's even more complicated if you wish to swap images of different sizes. The 'sandbag' would also have to change size. So it provides that flexibility.

The question has been asked many times before, in other words, and here in the past. It's a common question. The following was hinted at in one reply that I saw. It suggests to me, at any rate, that you have to turn to scripting to dynamically adjust a 'sandbag' div that pushes down the IMG right to the bottom. Like this:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<HTML>

<head>

<style>

#outer {
width: 98%;
position: relative;
min-height: 500px;
background:#ffa;
padding: 1%;
}

#outer IMG {
float: right;
background: #fc4;
clear: right;
margin-left: 1%;
margin-right: -1%;
}

#bag1 {
float: right;
width: 1px;
height: 100px;
}

</style>
</head>

<body>

<div id="outer"><div id="bag1"></div>
<img src="image.jpg" height="100" width="100">

<p>
After we arrived at McLaury's ranch, there was a man by the name of Frank Patterson. He made some kind of a compromise with Captain Hurst. Captain Hurst come to us boys and told us he had made this compromise, and by so doing, he would get his mules back. We insisted on following them up. Hurst prevailed on us to go back to Tombstone, and so we came back. Hurst told us two or three weeks afterwards, that they would not give up the mules to him after we left, saying that they only wanted to get us away, that they could stand the soldiers off. Captain Hurst cautioned me and my brothers, Virgil and Morgan, to look out for those men, as they had made some threats against our lives.
</p><p>
About one month after we had followed up those mules. I met Frank and Tom McLaury in Charleston. They tried to pick a fuss out of me down there, and told me if I ever followed them up again as close as I did before, they would kill me. Shortly after the time Bud Philpot was killed by the men who tried to rob the Benson stage, as a detective [working for Wells, Fargo & Co.] I helped trace the matter up, and I was satisfied that three men, named Billy Leonard, Harry Head, and James Crane were in that robbery. I knew that Leonard, Head and Crane were friends and associates of the Clan tons and McLaurys and often stopped at their ranches.
</p><p>

It was generally understood among officers and those who have information about criminals, that Ike Clanton was sort of chief among the cowboys that the Clantons and McLaurys were cattle thieves and generally in the secret of the stage robbery, and that the Clanton and McLaury ranches were meeting places and places of shelter for the gang.
</p>
</div>

</body>
</html>

In the window.onresize handler (or if you swap images, then from there, too), you'd calculate the height of the outer div, subtract the image height, and assign the difference as the height of bag#1. The image should then always been flush bottom, right, and text should wrap if it gets anywhere near.

fside




msg:3601158
 12:59 am on Mar 15, 2008 (gmt 0)

> moving #imgMask around <

I don't think you can accomplish float:bottom with CSS, as it stands. It should be part of the spec. If not that, then including a text wrap option for absolute or fixed elements. Your 'sandbag', your #imgMask floats right, but you can't establish absolute bottom. As I said in my message above, I think it requires one or two lines of script to adjust the height of one 'sandbag' to push down the IMG (which is floated to the right, in this case).

MarkFilipak




msg:3601162
 1:05 am on Mar 15, 2008 (gmt 0)

fside, You have the right idea. If you clip-copy my offering and look at it in a browser, you will find that #imgMask is positioned in the text of #content so that it is at the bottom and exactly behind #img. This trick doesn't work unless the sizes are specified in 'em'.

[edited by: MarkFilipak at 1:06 am (utc) on Mar. 15, 2008]

Joff




msg:3601376
 11:22 am on Mar 15, 2008 (gmt 0)

Mark, that example works great, thanks.

fside, sorry I did mean 'sandbag' and I've even used that term in the past too! :¦

fside




msg:3601394
 12:07 pm on Mar 15, 2008 (gmt 0)

> Mark, that example works great <

Joff, I don't think the 'mask' actually hits the bottom, does it? It is dependent on being placed at a certain position in the text. Your original problem description was that you didn't know what the text would be, that you didn't know the height of the div, and that you didn't know how far up from the bottom of the div the text would stop, remember? Set to a min-height of 500px, say, and suddenly you have the absolute or background image bottom right, but the 'sandbag' floating way up above, 'wrapping' the text when it shouldn't. What I suggested is using a 'sandbag' to basically push down the image you want, pretty much precisely. But again, it does require one or two lines of script. That's all.

SuzyUK




msg:3601400
 12:14 pm on Mar 15, 2008 (gmt 0)

sorry I'm not seeing how the example will work, well at least for more than one page as you would still have to precisely "pick" the position to insert the pixel image each time?

<added>snap fside!</added>

perhaps I'm not understanding what you're after here Joff?.. have you multiple pages with the same background image in the bottom right corner that you want to leave clear on lots of pages or is it just one page

[edited by: SuzyUK at 12:15 pm (utc) on Mar. 15, 2008]

Joff




msg:3601403
 12:17 pm on Mar 15, 2008 (gmt 0)

No it doesn't. The mask is positioned offset to the image to create a padding effect and yes it means I need to cater for each page individually so not 100% ideal, although it does work.

I see what you mean with your sandbag idea of pushing the image down - I'll have a play with the code you've suggested too :)

Joff




msg:3601413
 12:29 pm on Mar 15, 2008 (gmt 0)

fside - on narrow width pages, the image isn't positioned to the bottom-right corner, so the text in your example not only flows around the image as desired, but then continues underneath it.

Hi Suzy,
Multiple pages with the same image in the bottom-right that needs to remain free of text.

fside




msg:3601826
 3:56 am on Mar 16, 2008 (gmt 0)

> narrow width pages <

It should work. I'll look it over again and post the whole thing.

MarkFilipak




msg:3601830
 4:20 am on Mar 16, 2008 (gmt 0)

fside wrote:
> It should work. Again, the script would...
If the page has script, yeah, you can do almost anything. For example, I have a script that takes HTML plus an independent image and lays the HTML into a 2-column layout, with column balancing, and then positions the independent image over 2 floating divs so that the image appears to be across the gutter between the 2 columns and the text flows to either side. It works wonderfully, but it's got a ton of javascript in addition to the CSS -- the CSS acts as parameter input for the javascript. For what Joff wants to do, I don't think script is required.

Edit: added following.

> It should be part of the spec.
IMHO, the shortcoming of the CSS spec is that, instead of specifying browser behavior, it tries to specify ways to manipulate browsers. For example, wouldn't it just be simpler to have a style property that says, "For elements that have z-index less than the z-index of a particular element, in-line content shall flow around the particular element" instead of having things called "floats"?

[edited by: MarkFilipak at 4:29 am (utc) on Mar. 16, 2008]

fside




msg:3602007
 11:09 am on Mar 16, 2008 (gmt 0)

> instead of having things called "floats" <

I don't mind the, float. It's supposed to wrap on a float. As I said in my first message, this is hardly the first time this exact problem/question has been asked, even in this forum. You can see it being asked in 2006, 2005, etc. The problem with float is that to float it to a precise bottom, where the text is 'touching' the bottom, can affect the height of that container itself; just the very act of moving the floated object up and down.

But it should still be possible if this were done instead at the app level, instead of requiring 'sandbag' type hacks. Those can break. I had to take back my saying the hack I used was 'precise'. It was close, but could be up a bit or down a bit. The only way to really get it to work would be to have control over the 'flow' which eventually gets painted. The app logic could look for 'sandbags' even as an array of vertical points for example. It could look for the rectangle/box of any object. So the app could fix the element at the bottom, just as done with absolute, now. But it's something that would have to be done at the level where the line breaks are being placed in the text, by the app. I would like to see float: bottom, for that reason. It would touch the bottom of the element to the bottom of the containing element, taking margin and padding into consideration as with other floats.

Or I suppose, as an alternative, don't do anything with float, but simply add a text-wrap-shape property for any element, absolutely positioned or not. Unfortunately that opens the 'worm-can' for how to allow for all geometric shapes, open or closed, other than rectangle. I suggested a y-array, above, using any allowed units, maybe one array for left, one for right, or both, and note that the typical 'sandbag' hack would be an open shape, even as here. But if there were text-processors or graphics programs that could read the transparency in a gif or png, and adjust flow for padding or margin accordingly, then why can't a browser? The current text-wrap applies only to text inside an object, not that wrapping outside.

I could understand any reluctance, though. Such shapes are not - a box. Thus, where's ones box model?

[edited by: SuzyUK at 12:29 pm (utc) on Mar. 16, 2008]
[edit reason] no personal URI's please, see charter [/edit]

fside




msg:3602069
 1:46 pm on Mar 16, 2008 (gmt 0)

I said I'd put up a revised hack, here. I simply stuck the image using background, as was originally done in the OP. And I added a second 'bag' over it, as was the initial instinct in the OP. So.

I noticed that, for some reason, the script cuts out in IE 6 if widening the window. Whether timeout, setinterval, onresize, it just seems to stop working when going from thinner to wider. I don't know why. Seems to work in FF and Opera. The complaint might still be with the 'jumping'. It's not that it actually jumps back and forth now. I added a check for "prev" offset. But which of those offsets chosen might be either too high or too low. That happens when the second bag, the 'wrap-around' bag is just inbetween wrapping a new line or removing a line, and when of course the text is right along the bottom margin.

I don't see any way around that, short of even more code actually adjusting the bag2 height, and still meet the OP's original spec, as it were - don't know height, width, image or what the text will be. So this hack works most of the time. But sometimes the text will seem to collide with the image at those window widths where it used to 'bounce'. In just those relatively few cases, the 'wrap-around bag' is positioned a bit too low (in others, a bit too high where too much text wraps at the top).


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<HTML>

<head>

<style>

html #body {
padding: 0px;
margin: 0px;
}

#outer {
position: relative;
background:#ffa;
padding: 10px;
background: #ffc url('image_on.gif') no-repeat bottom right;
}

#bag1 {
float: right;
width: 2px;
height: 100px;
}

#bag2 {
float: right;
clear: right;
width: 110px;
height: 125px;
margin-right: -10px;
}

</style>
</head>

<body id="mbody">

<div id="outer"><div id="bag1">&#160;</div><div id="bag2">&#160;</div>

<p>
After we arrived at McLaury's ranch, there was a man by the name of Frank Patterson. He made some kind of a compromise with Captain Hurst. Captain Hurst come to us boys and told us he had made this compromise, and by so doing, he would get his mules back. We insisted on following them up. Hurst prevailed on us to go back to Tombstone, and so we came back. Hurst told us two or three weeks afterwards, that they would not give up the mules to him after we left, saying that they only wanted to get us away, that they could stand the soldiers off. Captain Hurst cautioned me and my brothers, Virgil and Morgan, to look out for those men, as they had made some threats against our lives.
</p><p>
About one month after we had followed up those mules. I met Frank and Tom McLaury in Charleston. They tried to pick a fuss out of me down there, and told me if I ever followed them up again as close as I did before, they would kill me. Shortly after the time Bud Philpot was killed by the men who tried to rob the Benson stage, as a detective [working for Wells, Fargo & Co.] I helped trace the matter up, and I was satisfied that three men, named Billy Leonard, Harry Head, and James Crane were in that robbery. I knew that Leonard, Head and Crane were friends and associates of the Clan tons and McLaurys and often stopped at their ranches.
</p><p>

It was generally understood among officers and those who have information about criminals, that Ike Clanton was sort of chief among the cowboys that the Clantons and McLaurys were cattle thieves and generally in the secret of the stage robbery, and that the Clanton and McLaury ranches were meeting places and places of shelter for the gang.
</p>

</div>

<script>
var prev=-1, adj;
var oOuter = document.getElementById("outer");
var oBag = document.getElementById("bag1");
var Bag2Ht = document.getElementById("bag2").offsetHeight;

/* assuming img1 can be changed in some other function not shown */
function fixImgBr (){
adj = oOuter.offsetHeight -Bag2Ht;
if (prev !==adj) oBag.style.height = adj +"px";
prev= oOuter.offsetHeight -Bag2Ht;
}
setInterval(fixImgBr,100);
</script>

</body>
</html>

Joff




msg:3605065
 9:29 am on Mar 19, 2008 (gmt 0)

fside, that works wonderfully, thanks.

Whilst the script method isn't for everyone it does the job for me.

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / CSS
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved