Question

NOTE: This is only an issue in IE.

How can a force the textarea to vertically fill the table-cell div? I have applied height: 100% to all the parent elements, but the textarea still maintains its default height.

Screenshot: Example from my test site

Example of my problem: JSFiddle

Example code:

HTML

<div class="table">
    <div class="row">
        <div class="col col-sm">
            <div class="thumbnail">Thumbnail</div>
        </div>
        <div class="col col-lg">
            <textarea>Text area</textarea>
        </div>
    </div>
</div>

CSS

* {
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
}

.table {
    display: table;
    width: 100%;
    height: 100%;
}
.row {
    display: table-row;
    height: 100%;
}
.col {
    display: table-cell;
    border: 1px dashed #FF0000;
    padding: 5px;
    vertical-align: top;
    height: 100%;
}
.col-sm {
    width: 30%;
}
.col-lg {
    width: 70%;
}
.thumbnail {
    height: 150px;
    width: 200px;
    border: 1px solid #CCC;
}

textarea {
    width: 100%;
    height: 100%;
}
Was it helpful?

Solution

According to this article, you'll see that what you're looking to do is impossible using a table-cell construction. Here's a fiddle demonstrating what happens when you remove all the height CSS. Spoiler alert: nothing happens, because none of your height tags have a value.

http://jsfiddle.net/py4gs/14/

Height/width CSS percentages are based off the closest parent with a defined height or width, excluding display: table* elements. In your case above, no such element exists, so none of the height tags have an effect.

I have encased your code in a body tag which has a defined width even though it is still relatively positioned. This is achieved by using an absolute positioning:

body {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
}

Fiddle: http://jsfiddle.net/py4gs/12/

As you can see, the textarea fills the container now. This is because your table has a height and all the other elements compute their height off of the table height.

Unfortunately, this solution is probably suboptimal for you, since it wouldn't work for multiple rows. There is no CSS-only solution for propagating the CSS computed height as the CSS actual height of a sibling in IE. You will need a height attribute defined on a parent and you can then propagate that down to the child.

There are options though. If it is absolutely necessary that the textarea be the same size of the thumbnail element, and the thumbnail height is indeed variable, then you can hook into a render event on your page (such as $(document).ready()) to grab the computed height and set this as the actual height:

$(document).ready(function() {
    // avoid layout thrashing! read then write!
    var heights = $('row').map(function(row) { return $(row).height(); });
    $('row').each(function(i, el) { 
        $(el).height(heights[i]);
    });
});

However, I'm a fan of non-jquery solutions. Therfore, I think the best solution might be to reconsider your layout. Use what you know about the thumbnail element to set the row height in advance or scale your thumbnail element. For example, if you are embedding a YouTube video as your thumbnail, you can scale the max-height of the iframe to 100% and manually set the row height to, say, 200px. If instead you are embedding an image, you could use CSS to scale the max-height and max-width of your image, which will respect aspect ratio (but is relatively computationally intensive), or you could preprocess your images and scale them to a desired height.

OTHER TIPS

Unfortunately looks like IE doesn't support the CSS resize property, and thus cannot resize the textarea vertically. Might have to use a shim, like the answer here:

https://stackoverflow.com/a/9763121/2612012

EDIT this may or may not work, but you can try this:

$(document).ready(function() {
    $('textarea').parent().resize(function() {
        var $t = $(this);
        $t.find('textarea').height($t.height());
    }).resize();
});

jsfiddle

.col {
    display: table-cell;
    border: 1px dashed #FF0000;
    padding: 5px;
    vertical-align: top;
    height:10px;
}

or you can give fixed height to the parent container (.table) which will automatically give full height to its children if set 100%

jsfiddle

.table { display: table; width: 100%; height: 150px; }

jsfiddle

      <div class="col col-lg">
      <div contenteditable='true' class='contenteditable'>Text area</div>
      </div>

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

.contenteditable p{margin-top:0px; margin-bottom:0px;}

Since the size of the textarea is a percentage of the page (which changes responsively), I have coupled jQuery and the HTML rows attribute to create a temporary hack. The ratio is calculated based on what I know about the page size and percentages.

$(window).resize(function(){
   var padding = 82;
   var ratio = 0.009;
   var rows = Math.floor(($('.main-container').width()-padding)*ratio);
   $('.text-area').attr('rows',rows);
}).resize();

For those who may not want to use the great but as yet not fully supported css table properties, You can also do this. Should be browser-friendly, but I only tested in FireFox, IE and SlimJet. Multiple rows work fine. I set the text area at 90% for demonstration.

(Not sure what the goal is here - perhaps multiple images on the left and one big textarea - but this should work for that also.)

jsfiddle: https://jsfiddle.net/RationalRabbit/wpsqx8kh/7/

HTML:

<body>
   <div class="table">
      <div class="row">
         <div class="col col-sm">
             <div class="thumbnail">Thumbnail</div>
         </div>
         <div class="col col-lg">
             <textarea>Text area</textarea>
         </div>
      </div>
      <div class="row">
         <div class="col col-sm">
             <div class="thumbnail">Thumbnail 2</div>
         </div>
         <div class="col col-lg">
             <textarea>Text area 2</textarea>
         </div>
      </div>
   </div>
</body>

CSS:

  * {
     -webkit-box-sizing:border-box;
     -moz-box-sizing:border-box;
     box-sizing:border-box;
  }
  .table {
     width:500px;
     height:100%px;
     border:1px dashed blue;
  }
  .row {
     height:200px;
  }
  .col {
     float:left;
     border:1px dashed #FF0000;
     padding:5px;
     vertical-align:top;
     height:100%;
  }
  .col-sm {
     width:30%;
  }
  .col-lg {
     width:70%;
     height:90%;
  }
  .thumbnail {
     height:150px;
     width:100%;
     border:1px solid green;
  }
  textarea {
     height:100%;
     width:100%;
  }

The easiest solution for me was to do it like this:

td{
   position:relative;
}
textarea{
   position:absolute;
   top:0;
   bottom:0;
   left:0;
   right:0;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top