Reputation: 3093
I want to position an image container next to a text box having the image always match the height of the text:
<- 50% -> <- 50% ->
+----------------------+ +----------------------+
| Lorem ipsum dolor si | | some |
| t amet, consectetuer | | image |
| adipiscingelit. Aene | | |
| an commodoligula ege | | |
| t dolor. | | |
+----------------------+ +----------------------+
vs
+------------+ +------------+
| Lorem ipsu | | some |
| m dolor si | | image |
| t amet, co | | |
| nsectetuer | | | Reduce
| adipiscing | | |<-- browser
| elit. Aene | | | width
| an commodo | | |
| ligula ege | | |
| t dolor. | | |
+------------+ +------------+
To achieve this I wrap both containers in a div
and display the image as a background-image:
<div class="outerTable">
<div>Lorem ipsum dolor sit amet, consectetuer</div>
<div class="image">
<div></div>
</div>
</div>
with the following style:
.outerTable {
width: 100%;
display: table;
}
.outerTable > div {
display: table-cell;
border: 10px solid transparent;
background-clip: padding-box;
position: relative;
background-color: #fff;
padding: 2%;
width: 50%;
}
.image {
background-color: #fff;
}
.image > div {
background-image: url(http://lorempixel.com/500/300/abstract/4);
background-size: cover;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
padding: 6%;
background-clip: content-box;
background-position: 0 0;
}
A working example can be found here: http://jsfiddle.net/KxFUL/
This works well in Chrome, Safari and Opera. But in FireFox the image covers the whole page and in IE11 the image is not shown at all…
Am I missing something – wrong concept altogether? Any ideas? Any different solutions?
Upvotes: 5
Views: 1550
Reputation: 5743
You "can't" do absolute positioning in a table cell, in relation to the table cell (don't ask me why, I didn't invent this stupid CSS specification). In any case, .image should have position:relative for position:absolute to work.
I guess Chrome is nice and ignores standards, or something like that.
Upvotes: 0
Reputation: 8338
My solution is a slightly long winded one, but it's just changing the CSS really to achieve what I think you want.
So first I've tried to use padding instead of transparent borders, and the first padding I set was on the .outer-table
itself. Of course, that table is 100% width, so you'll need to add the box-sizing fix as suggested by Paul Irish:
*, *:before, *:after {
-moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box;
}
Then, I set a padding right on the .col-66
to create that even spacing (margin can't be used on display: table-cell
).
The finally I set your background image on the .image
rather than on an empty container inside that, which means no need for absolute positioning.
New CSS here:
/* apply a natural box layout model to all elements */
*, *:before, *:after {
-moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box;
}
body {
background-image: url(http://bradjasper.com/subtle-patterns-bookmarklet/patterns/concrete_wall.png);
background-repeat: repeat repeat;
}
.outerTable {
width: 100%;
display: table;
padding: 10px;
}
.outerTable > div {
display: table-cell;
}
.col-33 {
width: 33.333%
}
.col-66 {
width: 66.666%;
padding-right: 20px;
}
.content {
padding: 3.4%;
background-clip: padding-box;
margin-bottom: 20px;
background-color: #fff;
}
.content:last-child {
margin-bottom: 0;
}
.image {
background-image: url(http://lorempixel.com/500/300/abstract/4);
background-size: cover;
border: 10px white solid;
background-position: 0 0;
}
And a fiddle to finish it off.
Upvotes: 1
Reputation: 1083
the problem is that you set display:table-cell for .image div, then put inside it a absolute positioned element, table-cell can't contain absolute element, as the element in it takes the cordinates for positioning NOT from its parent (although its parent is relative), but from the table (or display:table)
Upvotes: 0
Reputation: 1902
Here is what you could do if you so desire. Remove the where you have a background image being set to. I get you are trying to tie that into the image having a border. But you can get that to work with a css drop shadow set to inset.
http://jsfiddle.net/cornelas/KxFUL/4/
.outerTable > div {
display: table-cell;
border: 10px solid transparent;
background-clip: padding-box;
position: relative;
background-size: cover;
background-color: #fff;
padding: 2%;
width: 50%;
}
.image {
background-color: #fff;
background-image: url(http://lorempixel.com/500/300/abstract/4);
}
Here is the code to add your border back as well
.image {
background-color: #fff;
background-image: url(http://lorempixel.com/500/300/abstract/4);
-webkit-box-shadow:0 0 0 13px #FFFFFF inset;
box-shadow:inset 0px 0px 0px 13px #ffffff;
}
Update fiddle http://jsfiddle.net/cornelas/KxFUL/6/
Upvotes: 1
Reputation: 5490
Table-cell elements aren't really meant to have position: relative;
set on them (I believe it won't work if you try to set it on actual table cell <td>
s, though I could be wrong).
Because you are using CSS tables, most of the modern browsers have allowed you to set it on them, but Firefox seems to be sticking to the idea of table-cells not allowing it.
You can get around this a few ways, but it will depend on what else you have going on.
For example, you can wrap an additional <div>
around the content inside of the table-cell element, and then set it to be position: relative;
instead. The downside of this is you will need to give it a set height, which won't work if you need the height to flow with content.
You could also do it with javascript/jQuery.
This article has a good run-down of that, so I won't bother explaining the process in detail, as he does it so much better:
http://css-tricks.com/absolutely-position-element-within-a-table-cell/
Note that he is using it on actual table elements, so you'll need to make some changes. Essentially, it's the same process as I listed above with the extra div, it just sets the height dynamically with the JS. You could adapt it to change the height on window resize to make it responsive, etc...
Lastly, (in terms of my suggestions, I'm sure there are more options not listed here) - and my preferred suggestion, you could use display: inline-block;
to build your two-column layout, rather than display: table-cell;
. This way would avoid the whole pitfall all-together, and will also cut down the amount of html elements you need to get the effect.
Here's a good read on that:
http://designshack.net/articles/css/whats-the-deal-with-display-inline-block/
Upvotes: 0