How to dynamically resize HTML element according to it's sibling size using CSS only?

10,044

I would suggest using the table and table-row values of the display property for this.

The image-wrapper and text elements are both table rows, and so expand to fill the total area of the table. The image-wrapper is set to height 100%, so it consumes the left over space.

The image element is nested within the image-wrapper and is set to width/height 100%, so it takes on the same dimensions as its parent.

Here is a fiddle: http://jsfiddle.net/8S6Kf/1/

HTML

<div class="parent">
    <div class="image-wrapper">
        <img class="image" src="http://placehold.it/250x250&amp;text=2" />
    </div>

    <div class="text">
        A line of text.
    </div>
</div>

CSS

.parent {
    display: table;
    height: 250px;
    width: 250px;
}

.image-wrapper {
    display: table-row;
    height: 100%;
}

.image {
    width: 100%;
    height: 100%;
}

.text {
    display: table-row;
}

Update

This doesn't work on FF/IE. For this particular problem, you can replace the actual image with a div and use the background-image property. Note you also have to make the image a table-cell; or else ie won't render the table.

Here is an example that does not stretch the image.

http://jsfiddle.net/8S6Kf/7/

HTML

<div class="image"></div>

CSS

.image {
    display: table-cell;
    height: 100%;
    width: auto;

    background-image: url(http://placehold.it/250x250&amp);
    background-size: 100% 100%;
}

If you want to preserve the dimensions of the image, you can alternatively use these background properties:

background-size: contain;
background-repeat: no-repeat;
Share:
10,044
Paker
Author by

Paker

12344412213214124123231241243123

Updated on June 04, 2022

Comments

  • Paker
    Paker about 2 years

    I have container with a fixed height. Inside it there are two children: image and text of arbitrary length below it. I want the text to take the height it needs and the image to auto-adjust to the remaining space.

    Here is a start code I have:

    http://jsfiddle.net/LLsT8/1/

    <div id="parent">
    <div>
        <img src="http://placehold.it/250x250&amp;text=2" />
    </div>
    <div>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut </div>
    </div>
    

    Here is the JavaScript solution, but I'm wondering whether it can be CSS-only.

    http://jsfiddle.net/LLsT8/2/

    Update: bfuoco's solution is very close to what I need, but it doesn't work in Firefox.

    http://jsfiddle.net/8S6Kf/1/

  • Paker
    Paker about 11 years
    Looks exactly what I wanted! Thanks a lot. jsfiddle.net/8S6Kf/3 (only changed the image width to adjust) Of course, tables are not intended for layouts, but half a loaf is better than no bread.
  • Marc Audet
    Marc Audet about 11 years
    Using table display types is extremely useful. In the bad old days, tables (<table>) were used to lay out entire pages which is no longer best practice now that browsers have come of age with good CSS support. Changing the display type to table, table-cell and so on is quite okay since it is using modern CSS features to the fullest. It is indeed, a good way of separating content from display.
  • bfuoco
    bfuoco about 11 years
    The original problem with using tables for layout was that the <table> tag was being used for a purpose different than its semantic meaning. That is, it was supposed to represent "tabulated data" but was being used for presentation. Since a div tag doesn't have a semantic meaning, this is okay for me. I read it as "generic block element that looks like a table." I know what you mean though, I would prefer something more elegant, like a height: fill.
  • bfuoco
    bfuoco about 11 years
    I think it has to do with the image breaking the table row; I've posted a different solution using background-size above. If anyone has other ideas I'd be curious.