Автоматическое масштабирование высоты текстовой области

Я пытаюсь отобразить двойной столбец макета. В левом столбце есть изображение, которое может отображаться как 30% или доступная ширина, но не более 300 пикселей. В правом столбце есть описание, которое охватывает остальную часть ширины браузера.

Я не знаю априори, как долго описание, и я хочу ограничить высоту поля описания, поэтому я использую textarea включить прокрутку при необходимости.

Это мой текущий код HTML:

<div class="tile-panel">
    <div class="tile-preview-panel">
        <img class="tile-img" src="{{ thumbnail_url }}">
    </div>
    <div class="tile-desc-panel">
        <textarea readonly class="form-control tile-description"> {{ desc }} </textarea>
    </div>
</div>

И мой CSS:

.tile-panel {
      width: 100%;
      overflow: auto;
}
.tile-preview-panel {
      width: 30%;
      float:left;
      max-width: 300px;
}
.tile-desc-panel {
      overflow: hidden;
}
.tile-img {
      width: 100%;
}
.tile-description {
      resize: none;
      background-color:inherit !important;
      width: 100%;
}
.tile-description[readonly] {
      cursor: default; !important;
}

Единственный оставшийся бит - это высота textarea, Я хочу, чтобы она всегда была высотой панели предпросмотра плитки, независимо от ширины браузера. Это достижимо с чистым CSS?

3 ответа

Решение

Вот начало, это с использованием вашей существующей текстовой области,

.tile-panel {
  display: table;
  width: 100%;
}
.tile-preview-panel {
  display: table-cell;
  width: 30%;
}
.tile-desc-panel {
  display: table-cell;
  position: relative;
}
.tile-img {
  width: 100%;
}
.tile-description {
  resize: none;
  background-color:inherit !important;
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  left: 0;
  top: 0;
  position: absolute;
  }
.tile-description[readonly] {
  cursor: default; !important;
}

@media (min-width: 1000px){
  .tile-preview-panel {
    width: 300px;
  }
}
<div class="tile-panel">
    <div class="tile-preview-panel">
        <img class="tile-img" src="http://lorempixel.com/300/300/sports/1/">
    </div>
    <div class="tile-desc-panel">
        <textarea readonly class="form-control tile-description"> {{ desc }} </textarea>
    </div>
</div>

и вот версия с использованием div вместо этого, чтобы вы могли больше стиля текста, использовать ссылки и т. д.

.tile-panel {
  display: table;
  width: 100%;
}
.tile-preview-panel {
  display: table-cell;
  width: 30%;
  padding-right: 5px;
}
.tile-desc-panel {
  display: table-cell;
  position: relative;
  background-color: #ddd;
  border: 1px solid #999;
}
.tile-img {
  width: 100%;
  vertical-align: top;
}
.tile-description {
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  position: absolute;
  overflow: auto;
  padding-left: 10px;
}

@media (min-width: 1000px) {
  .tile-preview-panel {
    width: 300px;
  }
}
<div class="tile-panel">
  <div class="tile-preview-panel"><img class="tile-img" src="http://lorempixel.com/300/300/nature/5/"></div>
  <div class="tile-desc-panel">
    <div class="tile-description">
      Lorem ipsum dolor sit amet, consectetur adipiscing 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. Lorem ipsum dolor sit amet, consectetur adipiscing 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>

Также flex можно использовать, хотя он имеет немного меньшую поддержку браузера.

.container {
  display: flex;
  width: 100%;
}
.pic {
  flex: 0 0 20%;
  max-width: 200px;
  padding-right: 10px;
}
.text {
  flex: 1;
  position: relative;
  overflow: auto;
  background-color: #ddd;
  border: 1px solid #999;
}
.pic img {
  width: 100%;
  vertical-align: top;
}
.text div {
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  position: absolute;
  padding-left: 10px;
}
<div class="container">
  <div class="pic">
  <img src="http://lorempixel.com/300/300/nature/1/">
  </div>
  <div class="text">
    <div class="tile-description">
      Lorem ipsum dolor sit amet, consectetur adipiscing 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. Lorem ipsum dolor sit amet, consectetur adipiscing 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>

Другой вариант использования javascript, предложенный @user1899614, но с ES6 и методом getBoundingClientRect():

const makeDimensionsEqual = (someTextareaSelector, someParentElementSelector) => {

  document.querySelectorAll(someTextareaSelector)[0].style.height = 
    document.querySelectorAll(someParentElementSelector)[0]
    .getBoundingClientRect().height + "px"

}

const someTextareaSelector = '...' 
const someParentElementSelector = '...'
makeDimensionsEqual(someTextareaSelector, someParentElementSelector)

Я бы использовал javascript для этого

положить это в голову

<script>

function sameheight(){
var divHeight = document.getElementById('DIV ID YOU WANT TO GET HEIGHT OF').style.height;
document.getElementById('DIV ID YOU WANT THE SAME SIZE').style.height = divHeight;
}
</script>

И надень свое тело

<body onload="sameheight()">

Это должно работать:

.tile-panel {
    width: 100%;
    position: relative;
}
.tile-preview-panel {
    position: relative; 
    width: 74%;
}
.tile-desc-panel {
    position: absolute; 
    top: 0;
    right:0;
    bottom:0; 
    margin-left: 1.5%; 
    width: 24.5%; 
    height: 100%; 
    background: #232323; 
    overflow: hidden;
}
.tile-img {
      width: 100%;
}
.tile-description {
      resize: none;
      background-color:inherit !important;
      width: 100%;
}
.tile-description[readonly] {
      cursor: default; !important;
}

textarea {
  border: none;
  }
<div class="tile-panel">
    <div class="tile-preview-panel">
        <img class="tile-img" src="http://placehold.it/640x260">
    </div>
    <div class="tile-desc-panel">
        <textarea readonly class="form-control tile-description"> {{ desc }} </textarea>
    </div>
</div>

Другие вопросы по тегам