Izak
Izak

Reputation: 317

Parent div fixed height, second child variable height, first child fills the rest

It's hard to explain what I want so i drew a picture.

Paint masterpiece

So basically the first div (the outer div) has fixed height. The third div - blue - contains some text that I don't know the height of so the div should wrap around the text which means it has variable height. And the second div - green - (that should fill the rest of the height) contains an image which should either shrink to fit the div or simply align to the bottom if it's smaller. The problem I encounter is that the image simply doesn't want to shrink. It will always try to be full size and will push the text out of the div #1.

I tried solving it with a table approach but somehow table ignores the outer div fixed height. I'm fine with a flexbox solution althought I would like to avoid it to also support older browsers.

I would really like to solve this with css cause javascript will only complicate things and make it more laggy.

.outer{
  width: 100%; 
  height: 200px; 
  background-color: lightgray;
  padding: 20px;
}
<div class="outer">
	<div class="top">
		<img src="http://themeflush.com/minimalix/demo4/wp-content/uploads/2014/08/wallpapers-for-christian-background-tumblr-photography-vintage-images-tumblr-wallpapers.jpg">
	</div>
	<div class="bottom">
		<span>Title of the description<span>
		<p>This is a long description.</p>
	</div>
</div>

Upvotes: 3

Views: 1286

Answers (3)

itodd
itodd

Reputation: 2373

Here is a solution that uses display: table to maximise your browser support with no polyfills needed. However it uses a background image as opposed to an image..

.outer {
  box-sizing: border-box;
  display: table;
  width: 100%;
  height: 200px;
  background-color: lightgray;
  padding: 20px;
}

.top {
  background-size: contain;
  background-repeat: no-repeat;
  display: table-cell;
  height: 100%;
}

.bottom {
  display: table-row;
}
<div class="outer">
  <div class="top" style="background-image: url(http://themeflush.com/minimalix/demo4/wp-content/uploads/2014/08/wallpapers-for-christian-background-tumblr-photography-vintage-images-tumblr-wallpapers.jpg)">
  </div>
  <div class="bottom">
    <span>Title of the description</span>
		<p>This is a long description.</p>
	</div>
</div>

Upvotes: 1

Michael Benjamin
Michael Benjamin

Reputation: 371143

Here's a solution in pure CSS.

.outer {
  display: flex;
  flex-direction: column;
  height: 200px;
  background-color: lightgray;
  padding: 20px;
}

.top {
  flex: 1;
  display: flex;
}

.top > img {
  width: 100%;
  object-fit: contain;
  object-position: left;
}
<div class="outer">
  <div class="top">
    <img src="http://themeflush.com/minimalix/demo4/wp-content/uploads/2014/08/wallpapers-for-christian-background-tumblr-photography-vintage-images-tumblr-wallpapers.jpg">
  </div>
  <div class="bottom">
    <span>Title of the description</span>
    <p>This is a long description.</p>
  </div>
</div>

jsFiddle demo

Browser support: Flexbox is supported by all major browsers, except IE < 10. Some recent browser versions, such as Safari 8 and IE10, require vendor prefixes. For a quick way to add prefixes use Autoprefixer. More details in this answer.

References:

Upvotes: 1

Julio Feferman
Julio Feferman

Reputation: 2676

If I'm not mistaken, a pure css solution is unlikely although could look into css grid layout, which also has some compatibility issues. I don't understand why you say js is laggy. All modern browsers are extremely efficient at interpreting and processing the language and most websites and web-apps use javascript. So here is a solution using js calculations.

var img = document.getElementById("myImage");
var bottom = document.getElementById("bottom");
var myTop = document.getElementById("myTop");

var outerHeight = 200;
var remainingHeight = 200 - bottom.offsetHeight;

myTop.style.height = remainingHeight + "px";

if (img.offsetHeight >= remainingHeight) 
  img.style.height = remainingHeight + "px";
.outer{
  width: 100%; 
  height: 200px; 
  background-color: lightgray;
  padding: 20px;
}

.top {
  position:relative;
}

.top img {
  position:absolute;
  display:block;
  bottom:0px;
}
<div class="outer">
	<div id="myTop" class="top">
		<img id="myImage" src="http://themeflush.com/minimalix/demo4/wp-content/uploads/2014/08/wallpapers-for-christian-background-tumblr-photography-vintage-images-tumblr-wallpapers.jpg"/>
	</div>
	<div id="bottom" class="bottom">
		<span>Title of the description<span>
		<p>This is a long description.</p>
	</div>
</div>

Upvotes: 0

Related Questions