CSS absolute position within container div?
December 2, 2014 3:55 PM   Subscribe

Hi web nerds. I'm a n00b having trouble with some CSS positioning stuff and it's driving me nuts. I'm trying to arrange multiple divs within a container div and nothing seems to work right. Details inside.

Here's a fiddle of the basic problem.

A server-side script on my site generates table and image pairs, each in its own div. Each pair of divs is nested in a container div.

My problem is to arrange the two smaller divs within the container div using CSS. Basically, I want the 2nd nested div to come before the 1st within each container. (There may be a way to create the html in the proper order, but for right now I'd like to try to solve this with CSS).

Now, if I knew how big each table and image were going to be, I could define the container as the proper size, set the container to position:relative and place the nested divs using position:absolute. This is how all the tutorials say to do it, and it works fine.

The problem I have is that the tables have a variable number of columns, so I want the container div to automatically size itself to be big enough to hold both the table and image. However, as soon as I set the nested divs to be position:absolute, the container div seems to ignore them when determining its own height. This leaves the container too small for the table and image to fit inside, leading to chaos.

To put in in terms of the fiddle example, I want the 2 green boxes to be big enough to hold a pair of red and blue boxes without knowing ahead of time how big the red and blue boxes will be.

Is this at all possible?
posted by no regrets, coyote to Computers & Internet (9 answers total) 4 users marked this as a favorite
This seems like something that could be solved with flexbox. What browsers do you need to support?
posted by sea change at 4:06 PM on December 2, 2014

Thanks for pointing me towards flexbox, that looks helpful. The site is just for personal use, but I'd like it to work on Chrome/Firefox/Android browser.
posted by no regrets, coyote at 4:16 PM on December 2, 2014

Looks like you're in luck.
posted by sea change at 4:25 PM on December 2, 2014

The following replacement CSS will work:
.cont {position:relative; background: green; height:200px}
.div1 {background:red; position:absolute; bottom:0px; height: 20px;}
.div2 {background:blue; position:absolute; top:0px; height: 20px}
h1 {padding-top: 20px;}

I've specified a height for the container, which makes things easier; as an alternative, you can specify padding on .cont like so padding: 1em 0 2em 0; and it looks pretty good.

I should point out that this approach is brittle if you're concerned about responsive layouts.

Another slightly weird approach that should be browser safe is use CSS to force the elements to display as table headers and footers.
posted by adamrice at 5:01 PM on December 2, 2014

Yeah, the problem really is that .div2 contains a table that could be anywhere from 2 to 50 rows, so I'm trying to find a way to do it without having to define a height for .cont beforehand. I'm coming around to the fact that this won't be as simple as I expected, and I may just change my plan for the layout of the page.

I'll play around with the table header/footer trick and see if it works. Thanks!
posted by no regrets, coyote at 5:12 PM on December 2, 2014

Yeah, as you've discovered, absolute divs are laid "on top" of their containing box, and thus don't affect its size. Though flexbox sounds like a viable hack if you're not too worried about supporting 100% of browsers, the "right" answer is, in my opinion, to find a way to put the divs in the right order in the html in the first place.
posted by drjimmy11 at 5:16 PM on December 2, 2014 [2 favorites]

This will work:

.cont {position:relative; top:200px; left:100px; background: green;}
.div1 {background:red; margin-top:40px;}
.div2 {background:blue; position:absolute; top:30px;}

Rely on the regular positioning for the table, but give it a big top margin to leave space for the absolutely positioned image.

Edit: I just realized you don't know how large the image is.
posted by a dangerous ruin at 5:49 PM on December 2, 2014

Here's my jsfiddle using CSS:

.cont {position:relative; top:10px; left:100px; background: green; display: inline-block}
.div1 {background:red; display:table-footer-group}
.div2 {background:blue; display:table-header-group}
posted by nightwood at 7:06 PM on December 2, 2014 [1 favorite]

I think that might do it nightwood! Thanks everyone for your help!
posted by no regrets, coyote at 9:13 AM on December 3, 2014

« Older Licensing for inflight entertainment   |   No/Low Starch Diet - Food "Substitutes" and Brands... Newer »
This thread is closed to new comments.