Как я могу сделать TextArea шириной 100% без переполнения, когда заполнение присутствует в CSS?

у меня есть следующий фрагмент CSS и HTML.

textarea
{
  border:1px solid #999999;
  width:100%;
  margin:5px 0;
  padding:3px;
}
<div style="display: block;" id="rulesformitem" class="formitem">
  <label for="rules" id="ruleslabel">Rules:</label>
  <textarea cols="2" rows="10" id="rules"/>
</div>

проблема в том, что текстовая область оказывается на 8px шире (2px для границы + 6px для заполнения), чем родительская. Есть ли способ продолжать использовать границу и заполнение, но ограничить общий размер textarea к ширине родителя?

14 ответов


почему бы и нет? Забудьте хаки и просто сделайте это с помощью CSS?

тот, который я часто использую:

.boxsizingBorder {
    -webkit-box-sizing: border-box;
       -moz-box-sizing: border-box;
            box-sizing: border-box;
}

поддержка браузера здесь.


ответ на многие проблемы форматирования CSS, кажется, "добавить другой

!"

Итак, в этом духе, вы пытались добавить оболочку div, к которой применяется граница/заполнение, а затем поместить текстовую область 100% ширины внутри этого? Что-то вроде (непроверенных):

textarea
{
  width:100%;
}
.textwrapper
{
  border:1px solid #999999;
  margin:5px 0;
  padding:3px;
}
<div style="display: block;" id="rulesformitem" class="formitem">
  <label for="rules" id="ruleslabel">Rules:</label>
  <div class="textwrapper"><textarea cols="2" rows="10" id="rules"/></div>
</div>

рассмотрим окончательный вывод, отображаемый пользователю того, что мы хотим достичь: мягкий textarea как с границей и отступом, какие характеристики, что при нажатии они передают фокус на наш textarea, и преимущество автоматической 100% ширины, типичной для элементов блока.

лучшим подходом, на мой взгляд, является использование низкоуровневых решений, насколько это возможно, для достижения максимальной поддержки браузеров. В этом случае единственный HTML может работать нормально, избегая использования Javascript (который в любом случае мы все любим).

тег LABEL приходит в нашу помощь, потому что имеет такое поведение и может содержать входные элементы, к которым он должен обращаться. Его стиль по умолчанию является одним из встроенных элементов, поэтому, придавая метке стиль отображения блока, мы можем воспользоваться автоматической шириной 100%, включая заполнение и границы, в то время как внутренняя текстовая область не имеет границы, без заполнения и 100% ширины.

взглянув на специфику W3C другие преимущества, которые мы можем заметить:

  • атрибут "для" не требуется: когда тег метки содержит целевой вход, он автоматически фокусирует дочерний вход при нажатии;
  • если внешняя метка для textarea уже разработана, конфликтов не возникает, так как данный вход может иметь одну или несколько меток.

посмотреть W3C в особенности для получения более подробной информации.

простой пример:


<html>
<head>
<style type="text/css">
.container { width: 400px; border: 3px solid #f7c; }
.textareaContainer {
    display: block;
    border: 3px solid #38c;
    padding: 10px;
}
textarea { width: 100%; margin: 0; padding: 0; border-width: 0; }
</style>
</head>

<body> <div class="container"> I am the container <label class="textareaContainer"> <textarea name="text">I am the padded textarea with a styled border...</textarea> </label> </div> </body> </html>

обивка и граница .элементы textareaContainer-это те, которые мы хотим предоставить textarea. Попробуйте отредактировать их так, как вы хотите. Я дал большую и видимую прокладку и границы.textareaContainer элемент, чтобы вы могли видеть их поведение при нажатии.


Если вы не слишком беспокоитесь о ширине заполнения,это решение фактически сохранит заполнение в процентах..

textarea
{
    border:1px solid #999999;
    width:98%;
    margin:5px 0;
    padding:1%;
}

не идеально, но вы получите некоторые отступы и ширина добавляет до 100%, так что все хорошо


я наткнулся на другое решение здесь это так просто: добавьте заполнение-прямо в контейнер textarea. Это сохраняет поля, границы и отступы в текстовом поле, что позволяет избежать проблемы, на которую указал Бек о фокусе, выделенном chrome и safari вокруг текстового поля.

заполнение контейнера-право должно быть суммой эффективного поля, границы и заполнения с обеих сторон textarea, а также любого заполнения, которое вы можете в противном случае контейнер. Итак, для случая в исходном вопросе:

textarea{
    border:1px solid #999999;
    width:100%;
    margin:5px 0;
    padding:3px;
}
.textareacontainer{
    padding-right: 8px; /* 1 + 3 + 3 + 1 */
}

<div class="textareacontainer">
    <textarea></textarea>
</div>

этот код работает для меня с IE8 и Firefox

<td>
    <textarea style="width:100%" rows=3 name="abc">Modify width:% accordingly</textarea>
</td>

вы можете использовать свойство box-sizing, оно поддерживается всеми основными совместимыми со стандартом браузерами и IE8+. Однако вам все равно понадобится обходной путь для IE7. Подробнее здесь.


нет, вы не можете сделать это с помощью CSS. Именно по этой причине Microsoft изначально представила другой, и, возможно, более практичный модель. Модель коробки которая окончательно выиграла, делает ее inpractical смешать проценты и блоки.

Я не думаю, что с вами нормально выражать ширину заполнения и границы в процентах от родителя.


Если вы накладываете и смещаете его так:

textarea
{
    border:1px solid #999999;
    width:100%;
    padding: 7px 0 7px 7px; 
    position:relative; left:-8px; /* 1px border, too */
}

правая сторона текстового поля идеально совпадает с правой стороной контейнера,и текст внутри текстового поля на одной линии с текстом в контейнере... и левая сторона текстового поля немного "торчит". иногда красивше.


использовать свойство размера коробки:

-moz-box-sizing:border-box; 
-webkit-box-sizing:border-box; 
box-sizing:border-box;

что поможет


для людей, которые используют Bootstrap, textarea.form-control также может привести к проблемам с размером textarea. Chrome и Firefox, похоже, используют разные высоты со следующим загрузочным CSS:

textarea.form-conrtol{
    height:auto;
}

Как насчет отрицательных полей?

textarea {
    border:1px solid #999999;
    width:100%;
    margin:5px -4px; /* 4px = border+padding on one side */
    padding:3px;
}

Я часто исправляю эту проблему с calc(). Вы просто даете textarea ширину 100% и определенное количество заполнения, но вы должны вычесть общее левое и правое заполнение ширины 100%, которую вы дали textarea:

textarea {
    border: 0px;
    width: calc(100% -10px);
    padding: 5px; 
}

или если вы хотите дать textarea границу:

textarea {
    border: 1px;
    width: calc(100% -12px); /* plus the total left and right border */
    padding: 5px; 
}

* {
    box-sizing: border-box;
}

.container {
    border-radius: 5px;
    background-color: #f2f2f2;
    padding: 20px;
}

/* Clear floats after the columns */
.row:after {
    content: "";
    display: table;
    clear: both;
}

input[type=text], select, textarea{
    width: 100%;
    padding: 12px;
    border: 1px solid #ccc;
    border-radius: 4px;
    box-sizing: border-box;
    resize: vertical;
}
<div class="container">
  <div class="row">
    <label for="name">Name</label>
    <input type="text" id="name" name="name" placeholder="Your name..">
  </div>
  <div class="row">
    <label for="country">Country</label>
    <select id="country" name="country">
      <option value="australia">UK</option>
      <option value="canada">USA</option>
      <option value="usa">RU</option>
    </select>
  </div>    
  <div class="row">
    <label for="subject">Subject</label>
    <textarea id="subject" name="subject" placeholder="Write something.." style="height:200px"></textarea>
  </div>
</div>