How to place an absolute element inside a equal-height column? A little nightmare

Here’s what I can’t do by any means, using only CSS:

Columns should have equal heights. And, on a given column, a absolute positioned element should be present relative to that column:

The HTML:

<div class="wrapper">
    <div class="column">
        <img src="http://www.english3.com/wp-content/uploads/2013/05/DFI-Logo-300px-X-200px.png"/>
    </div>
    <div class="column info">
        <p>Some text here yeah :).</p>
        <p>Some text here yeah :)</p>
        <a class="link" href="#">I should be absolute.</a>
    </div>
</div>

THE CSS:

.wrapper {
    overflow: hidden;
}
.column {
    float: left;
    background-color:red;
    width:50%;
    /*padding-bottom:900px;
    margin-bottom: -900px;*/
}

.column img {
  max-width:100%;
 }

.info {
    position:relative;
    background-color: blue;
}

.link {
    clear:left;
    display: block;
    position: absolute;
    bottom: 3%;
    color: yellow;
}

Fiddle to play:

http://jsfiddle.net/BuuFv/71/

TRIES AND FRUSTRATIONS:

Display table for equal heights is NOT an option because if has issues on latest FF. And regardless the tries on given height: 100%; as suggested here:

Doesn’t seem to do the trick.

Or using a relative container, doesn’t seem to make the trick either.

As far as I can see, Table cell will always give us a know firefox position absolute inside a relative container issue/bug.

Using huge padding and margin values on columns will NOT work either, because the absolute position element will not work properly.

Faux Columns will not work either, because we wish to have an image on one of the columns.

Here’s an image of the intended result:

Any help, please?

Hi,

I would use display:table-cell for the equal height columns (ie8+) and then use the wrapper as the position:relative element so that you can place an absolute element at the bottom of the column.

e.g.


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Untitled Document</title>
<style>
.wrapper {
	overflow: hidden;
	position:relative;
	min-width:625px
}
.inner {
	display:table;
	width:100%;
}
.column {
	display:table-cell;
	background-color:red;
	width:50%;
	vertical-align:top;
}
.column img {
	max-width:100%;
	display:block
}
.info {
	background:blue;
	padding-bottom:25px;
}
.link {
	display: block;
	position: absolute;
	left:50%;
	bottom: 3%;
	color: yellow;
}
</style>
</head>

<body>
<div class="wrapper">
		<div class="inner">
				<div class="column"> <img src="http://www.english3.com/wp-content/uploads/2013/05/DFI-Logo-300px-X-200px.png"/> </div>
				<div class="column info">
						<p>Some text here yeah :).</p>
						<p>Some text here yeah :)</p>
						<a class="link" href="#">I should be absolute.</a> </div>
		</div>
</div>
</body>
</html>


You will need a min-width though to stop the absolute element moving on the left column at small widths.

I confess I tried that approach earlier. But the absolute element was always near the top, instead of the bottom. However, since you have posted the appropriate code, I will give it a try later today, and see what I get this time.

Thanks a lot for your reply. I really feel I’m seeing the doctor, each time I came with css problems here. :stuck_out_tongue: :slight_smile:

Remember the parent needs to be an element that is not display:table because position:relative on a display:table element does not create a stacking context for absolutely place children as there is no concept for that in a table.

Thanks a lot for your reply. I really feel I’m seeing the doctor, each time I came with css problems here. :stuck_out_tongue: :slight_smile:

lol :slight_smile:

  1. This need is required only for FF. Is this correct?

The all point of having max-width on images on this case, is to allow some responsiveness when the viewport shrinks.
The image doesn’t adjust according to it’s container on FF, while doing so on Chrome and Safari.


.inner {
    position: relative; 
    width: 100%;
}

The .inner has a width: 100% and each column, a width: 50%.
I was expecting that, when we resize the browser window, the 2 columns would always “fill-in” completely the .inner container.
That doesn’t seem to be the case, when we try to stretch the browser window:
http://jsfiddle.net/BuuFv/94/

Please advice.

HI,

.inner needs to be display:table with a width of 100% otherwise the cells will be shrink to fit. The wrapper needs position:relative not .inner.

Even though the wrapper is 100% the display:table-cells take no notice of that because they construct an anonymous display:table element to hold the cells because you didn’t provide one and therefore becomes shrink to fit. If you supply the display:table parent then you can set it to 100% wide and stop the shrink to fit.

No the min-width is needed for all browsers.

The problem is that #wrapper is auto width (effectively 100% for this example) and as the window closes #wrapper gets smaller and smaller. At some point the two table cells suddenly stop contracting because their contents can’t wrap any more. However, this is of no consequence to #wrapper which just gets smaller and smaller because that’s how css works. #wrapper is now smaller than the two table cells so the position:absolute of left:50% no longer matches the non stretch cells. Therefore you need to put a min-width on the wrapper that matches the smallest that your table cells can compress. There is no other way around this without resorting to something like flexbox.

Not sure if it’s important but, here’s the big picture:

I’m trying to accomplish a responsive version for mobile devices.
Hence, the need of flexible images and so forth.
On the desktop, I have 3 columns like this:
. . . . . . . . . . . . . . . . . . .
. . img . . img . . img . .
. . . . . . . . . . . . . . . . . . .
. . txt . . . txt . . txt . .
. . . . . . . . . . . . . . . . . . . .

On the mobile I (wish) to have 1 column like this:
. . . . . . . . . . . . . . . . .
. . img . . content . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . img . . content . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . img . . content . .
. . . . . . . . . . . . . . . . .

My bad. I coded wrong. :frowning:

Hm… Your explanation makes sense. However, I’ve tested in Chrome and Safari , both Mac OS X version, and it seems to behave:
the absolute element stays on the right column.
http://jsfiddle.net/BuuFv/98/

Can you confirm this, or am I missing some obvious points?

Regardless those assumptions however:
It seems that, at least for FF, we need to have min-width declared.
As far as I can see, that wouldn’t be a problem, if FF, at least, behaves on shrinking and expanding that image according to it’s container. If that happened, we could, perhaps, declare a narrow min-width and allow some flexibility there.
However, that doesn’t happen: the image doesn’t shrink nor expands according to it’s container (using max-width, never width or height because that will give us image distortion).

Any clue why?

The full code:


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Test case 104</title>
<style type="text/css">
    .wrapper {
    overflow: hidden;
    position: relative;
}

.inner {
    width: 100%;
    display: table;
}

.column {
    display: table-cell;
    width: 50%;
    vertical-align: top;
    background-color:red;
}

.column img {
  max-width:100%;  
  display: block;
 }

.info {
    background-color: blue;
    padding-bottom: 25px;
}

.link {
    display: block;
    position: absolute;
    left: 50%;
    bottom: 3%;
    color: yellow;
}
</style>
</head>
    <body>
<div class="wrapper">
    <div class="inner">
         <div class="column">
            <img src="http://www.english3.com/wp-content/uploads/2013/05/DFI-Logo-300px-X-200px.png"/>
        </div>
        <div class="column info">
            <p>Some text here yeah :).</p>
            <p>Some text here yeah :)</p>
            <p>Some text here yeah :)</p>
            <a class="link" href="#">I should be absolute.</a>
        </div>
   </div>
</div>
</body>
</html>

Hi,

Add table-layout:fixed and that should allow the image to scale in Firefox and avoid the need for the min-width.


.inner {
	width: 100%;
	display: table;
	[B]table-layout:fixed;[/B]
}


That seems to work pretty nice. And you thought that gem of solution, just like that? Without even an introduction sound like:
DAN DAN DAN DAN DAN: TCHARÃ!
– solution here –

:slight_smile:
I’m completely astonished by your knowledge toward those matters, and also frustrated that I couldn’t found the solution myself, despite being playing with css for some years now. Oh well… :stuck_out_tongue:

Besides being a IE8+ solution, what’s the catch of using table-layout:fixed; instead of min-width?
That we need to always declare width on the columns ?

omg, I can’t believe this works! :D:D:D

The table-layout:fixed is generally better for tables as it assumes that the cells will be more or less fixed width and does the table in one pass as opposed to table-layout:auto tables which take two passes. However there are variations in browsers (as you have seen) so sometimes you have to switch between the two to see which gives the best effect. The table-layout fixed algorithm made Firefox recognise the max-width in the cell and this let the image shrink.

Table-cells (html and css) are complicated structures in that they don’t always obey what you tell them and things like height and width may be ignored in order to layout the table in rows and columns properly. For equal height columns display:table-cell is great but it can be awkward to have space between columns though and you have to fiddle abut with border-spacing.

Flexbox addresses many of these issues and in a couple of years when browser support is better a lot of these old techniques will be redundant.