byCoder
byCoder

Reputation: 9184

Make div expand to occupy available height of parent container

I have this code:

html:

<div class="tile">
    <h3>short</h3>
    <div class="content">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>
</div>

<div class="tile">
    <h3>longLongLong longLongLong longLongLong</h3>
    <div class="content">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>
</div>

css:

.tile{
    height: 300px;
    width: 200px;
    background: #cecece;
    float: left;
    margin: 0 10px 0 0;
}

.tile h3{
    min-height: 20px;
    max-height: 61px;
    display: inline-block;
    overflow: hidden;
}

.tile .content{
    height: 162px;
    overflow: hidden;
    margin: 0 10px;
}

fiddle:

http://jsfiddle.net/v8Lhxk2v/

and I get this layout

enter image description here

but I need to get something like next image, without using js.

Can that be solved?

enter image description here

Upvotes: 12

Views: 985

Answers (9)

Michael Benjamin
Michael Benjamin

Reputation: 371231

Solving this problem is pretty simple with flexbox.

By creating a column flex container the flex items stack vertically. You can then apply flex: 1 to the text box (.content) which makes it expand the full available height of the container.

HTML

<div id="container"><!-- container to align .tile boxes in flexbox row; 
                         (this flexbox is optional) -->
    <div class="tile">
        <h3>short</h3>
        <div class="content">Lorem ipsum dolor sit amet ... </div>
    </div>

    <div class="tile">
        <h3>longLongLong longLongLong longLongLong</h3>
        <div class="content">Lorem ipsum dolor sit amet ... </div>
    </div>

</div><!-- end #container -->

CSS

#container {
    display: flex; /* establish flex container; 
                      aligns flex items (child elements) in a row by default; */        
}   

.tile {
    display: flex; /* establish (nested) flex container */
    flex-direction: column; /* override default row alignment */
    height: 300px;
    width: 200px;
    background: #cecece;
    /* float: left; */
    margin: 0 10px 0 0;
}

.tile h3 {
    min-height: 20px;
    max-height: 61px;
    /* display: inline-block; */
    overflow: hidden;
}

.tile .content {
    flex: 1; /* tells flex item to use all available vertical space in container */
    height: 162px;
    overflow: hidden;
    margin: 0 10px 40px 10px; /* added bottom margin for spacing from container edge */
}

DEMO

Note that flexbox is supported by all major browsers, except IE 8 & 9. Some recent browser versions, such as Safari 8 and IE10, require vendor prefixes. For a quick way to add all the prefixes you need, use Autoprefixer. More browser compatibility details in this answer.


Using Ellipsis (...)

If you want to apply ellipsis to a single line of text, CSS makes that somewhat easy with the text-overflow property. It's still a bit tricky (due to all the requirements), but text-overflow makes it possible and reliable.

If, however, you want to use ellipsis on multi-line text – as would be the case here – then don't expect to have any fun. CSS doesn't provide a single property for doing this, and the workarounds are hit and miss. For details and methods see my answer here: Applying Ellipsis to Multiline Text

Upvotes: 5

Alvaro Men&#233;ndez
Alvaro Men&#233;ndez

Reputation: 9012

I would try another aproach. Using jquery you can calculate on window load the height of the highest h3 and then, apply that height to all your h3 inside your tiles.

I know you asked for a pure css solution, so it's ok if I don't get any credit, but I think this answer may be usefull for other users with the same problem so that's why I wrote it.

Something like this:

var maxHeight = -1;
$('.tile h3').each(function() {
    if ($(this).height() > maxHeight)
        maxHeight = $(this).height();
});
$('.tile h3').each(function() {
    $(this).height(maxHeight);
});

As you can see in this JSFIDDLE (notice I removed the fixed max-heightyou added to the header and add a third tilewith a "very long text" so you can check the exmaple better.

Upvotes: 4

Salvatore Orlando
Salvatore Orlando

Reputation: 48

you can resolve by the flexbox Flexible Box Layout Module:

.tile{
   ...
   /* add the following line */
   display: flex;
   flex-direction: column;
   justify-content: space-between;
   ...
}

http://jsfiddle.net/57yLgxsx/

This example works on Chrome you can check for the browser compability on caniuse.com and then add the correct prefixes.

It depends on who you want to ensure compatibility ( last 2 vorsion of all browser, mobile or desktop or both ).

keep in mind that there are two versions of flexbox, the "old" and the "new". What I wrote above is the new.

This link can clarify some ideas https://css-tricks.com/snippets/css/a-guide-to-flexbox/

Upvotes: 0

Ahosan Karim Asik
Ahosan Karim Asik

Reputation: 3299

Try this use extra div with wrap. h3 & div.content tag are wrapped by extra div and some css to be change as following:

.tile > div {
  height: calc(100% - 20px);
  margin: 10px;
  overflow: hidden;
  line-height: 22px!important;
}
.tile {
  height: 300px;
  width: 200px;
  background: #cecece;
  float: left;
  margin: 0 10px 0 0;
}
.tile h3 {
  min-height: 20px;
  display: inline-block;
  overflow: hidden;
  margin: 5px 0;
}
.tile .content {
  margin: 0;
}
<div class="tile">
  <div>
    <h3>short</h3>
    <div class="content">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
      dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>
  </div>
</div>

<div class="tile">
  <div>
    <h3>longLongLong longLongLong longLongLong</h3>
    <div class="content">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
      dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>
  </div>
</div>

Upvotes: 2

GDY
GDY

Reputation: 2941

How about a fixed height:

.tile h3 {
    height: 65px;
    display: inline-block;
    overflow: hidden;
}

Or accompanied by js (jQuery):

// Height handler
var headHeight = 0;

// Iterate throug all H3s an get highest
jQuery( 'h3' ).each( function() {

    // Get current height
    var currentHeight = jQuery( this ).height();

    // If higher as handler set as handler
    if( currentHeight > headHeight ) {
        headHeight = currentHeight;   
    }

} );

// Set the height of all H3s
jQuery( 'h3' ).css( 'height', headHeight );

This would be a pretty robust solution ...

Upvotes: 0

Rotan075
Rotan075

Reputation: 2615

I would say try to position the content absolute to the bottom of the tile. In that case you can set the space where the content should end. Still you need to add an extra class to your content with the smaller title to be it larger than the other tile with the larger title.

Your HTML would be:

<div class="tile">
    <h3>short</h3>
    <!-- Added an extra class to the div -->
    <div class="content small">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>
</div>

Within your CSS I changed this:

.tile .content{
    height: 162px;
    background-color:grey;
    overflow: hidden;
    margin: 0 10px;
    position: absolute;
    bottom:30px;
}
.tile .small{height:216px;}

And then you get this result: JSFIDDLE

Let me know if this is a solution that works for you.

Upvotes: 5

David Stanč&#237;k
David Stanč&#237;k

Reputation: 350

Well, pretty easy... make <div class="move"></div> and put your h3 into it like:<div class="move"><h3>Short</h3></div> now style that move div like so:

.move{height:100px;}

it workd, you are done :)

PS: make it with both of your h3s :)

well, there is a code:

css:

.tile{
    height: 300px;
    width: 200px;
    background: #cecece;
    float: left;
    margin: 0 10px 0 0;
}

.tile h3{
    min-height: 20px;
    max-height: 61px;
    display: inline-block;
    overflow: hidden;
}

.tile .content{
    height: 162px;
    overflow: hidden;
    margin: 0 10px;
}

.move{height:100px;}

html:

<div class="tile">
    <div class="move">
    <h3>short</h3>
        </div>
    <div class="content">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>
</div>

<div class="tile">
    <div class="move">
    <h3>longLongLong longLongLong longLongLong</h3>
        </div>
    <div class="content">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>
</div>

Upvotes: 4

caramba
caramba

Reputation: 22480

Look at this

http://jsfiddle.net/v8Lhxk2v/4/

playing with border-bottom and overflow:hidden on the parent element.

.tile{
    height: 300px;
    width: 200px;
    background: #cecece;
    float: left;
    margin: 0 10px 0 0;
    border-bottom: 22px solid #cecece;
    overflow: hidden;
}

.tile h3{
    min-height: 25px;
    max-height: 61px;
    display: inline-block;
    overflow: hidden;
}

.tile .content{
    margin: 0 10px;
}

Upvotes: 7

Bill Criswell
Bill Criswell

Reputation: 32921

Depending on browser support you can use flex.

The container would need:

display: flex;
flex-flow: column;

Here's a quick demo with example markup:

http://jsbin.com/xuwina/3/edit?html,css,output

Upvotes: 10

Related Questions