Текстовое поле ввода HTML с шириной 100% переполняет ячейки таблицы

106

Кто-нибудь знает, почему элементы ввода шириной 100% выходят за границу ячеек таблицы.

В простом примере ниже поле ввода выходит за границу ячеек таблицы, результат ужасен. Это было протестировано, и это происходит точно так же в Firefox, IE7 и Safari.

Имеет ли это смысл для вас? Я что-то упускаю, знаете ли вы о возможном решении?

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">    
<html><head>    
   <meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> <!-- don't use closing slash in meta tag, it breaks HTML4.01 transitional -->
   <title>Test input text in table</title>
   <style type="text/css">      
      table {border-top: 1px solid #ff0000; border-left: 1px solid #ff0000;}
      table td {border-right: 1px solid #00ff00; border-bottom: 1px solid #00ff00;}
      input[type="text"] {width: 100%;} /* removing this would make input not to go over cells border, but they would be too short, I want them to fit cells size */
   </style>    
</head><body>

<table cellpadding="0" cellspacing="0">
   <tr>
      <td><p>column one hello babe babe babe</p></td>
      <td><p>column two hello babe more</p></td>
      <td><p>column three hello babe more and more</p></td>
   </tr>
   <tr>
      <td><input type="text" value="test"></td>
      <td><input type="text" value="test"></td>
      <td><input type="text" value="test"></td>
   </tr>
</table>

</body></html>
Марко Демайо
источник
1
Я бы посоветовал, если вы просто используете таблицу для представления входных данных, вы можете переключиться на использование a formс labels и inputs внутри ulили ol. который, по крайней мере, немного более семантичен. Конечно, вам следует использовать form, даже если вы все-таки придерживаетесь table.
Дэвид требует восстановить Монику

Ответы:

216

Вы можете использовать box-sizingсвойство CSS3 для включения внешнего отступа и границы:

input[type="text"] {
     width: 100%; 
     box-sizing: border-box;
     -webkit-box-sizing:border-box;
     -moz-box-sizing: border-box;
}
pricco
источник
1
К сожалению, IE 7 неправильно определяет размер коробки. Попробуйте следующее в IE 7 ... css3.info/preview/box-sizing или увидеть css-tricks.com/box-sizing
AnthonyVO
@AnthonyVO: правда, единственный обходной путь для IE7 - добавить для него определенный CSS с использованием условных комментариев IE <!--[if lt IE 8]>иinput[type="text"] {width:95%}
Марко Демайо
24

Значение ширины не учитывает границы или отступы:

http://www.htmldog.com/reference/cssproperties/width/

У вас будет 2 пикселя отступа с каждой стороны плюс 1 пиксель границы с каждой стороны.
100% + 2 * (2px + 1px) = 100% + 6px, что больше, чем 100% дочернего содержимого родительского td.

У вас есть возможность:

  • Либо настройка box-sizing: border-box;в соответствии с ответом @pricco ;
  • Или используйте 0 полей и отступов (избегая лишнего размера).
Рукава
источник
далее для ответа Sr pts вы можете установить отступ и границу на 0 пикселей, тогда 100% должны работать.
Mauro
Действительно, даже без установки каких-либо отступов для тд - очень хорошо добавлено.
ANeves 03
1
Кроме того, если заполнение создает проблему, его можно использовать text-indentдля имитации заполнения перед передним краем текста и line-heightдля вертикального заполнения (хотя сохранение вертикального заполнения в любом случае не повлияет на ширину).
Дэвид говорит, что нужно восстановить Монику
14

Проблема с такими вещами width:95%;заключается в том, что они не выглядят правильно в широких гибких макетах (потому что 5% тогда могут быть как 30 пикселей).

Следующие решения мне очень подходят (протестированы в Firefox, IE 9, Safari):

<table style="background-color: blue; width: 100%;" cellpadding="0" cellspacing="0">
<tr>
    <td style="background-color: red;   padding: 3px;">
        <div style="margin-right: 3px;">
            <div style="padding-right: 3px;">
                <input type="text" style="width:100%;">
            </div>
        </div>
    </td>
    <td style="background-color: purple;   padding: 3px;">
        <div style="margin-right: 3px;">
            <div style="padding-right: 3px;">
                <input type="text" style="width:100%;">
            </div>
        </div>
    </td>
    <td style="background-color: green;   padding: 3px;">
        <div style="margin-right: 3px;">
            <div style="padding-right: 3px;">
                <input type="text" style="width:100%;">
            </div>
        </div>
    </td>
</tr>
</table>

(добавлены цвета, чтобы было легче заметить правильный отступ)

Хитрость заключается в том, чтобы обернуть ввод двумя div, внешний имеет поле 3px (что делает его на 3px меньше, чем td), внутренний имеет отступ 3px. Это делает ввод на 6 пикселей меньше td, с которого вы хотели начать.

Я не уверен в механике этого, но это работает.

В этом простом примере он также работает только с одним div с правым полем 6. Однако в случае моего веб-приложения работает только вышеуказанное решение.

<table style="background-color: blue; width: 100%;" cellpadding="0" cellspacing="0">
<tr>
    <td style="background-color: red;   padding: 3px;">
        <div style="margin-right: 6px;">
                <input type="text" style="width:100%;">
        </div>
    </td>
    <td style="background-color: purple;   padding: 3px;">
        <div style="margin-right: 6px;">
                <input type="text" style="width:100%;">
        </div>
    </td>
    <td style="background-color: green;   padding: 3px;">
        <div style="margin-right: 6px;">
                <input type="text" style="width:100%;">
        </div>
    </td>
</tr>
</table>
Андреас
источник
Это работает (проголосовало +1). Как ни странно, я вставил какой-то текст перед каждым <input> и добавил "white-space: nowrap", чтобы они оставались в одной строке, тогда три <inputs> переполнили ячейки таблицы, если я удалил все "white-space: nowrap" снова работает. Странно.
Хосе Мануэль Абарка Родригес
8

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

<table>
  <tr>
    <td><div style="overflow:hidden"><input style="width:100%" type="text" name="name" value="hello world" /></div></td>
  </tr>
</table>

DIV, обертывающий INPUT, не имеет ни заполнения, ни границы. Это решение. DIV будет расширяться до размера своего контейнера, но также будет учитывать границу и отступы. Теперь у INPUT не будет проблем с расширением до размера своего контейнера, так как он не имеет границ и площадок. Также обратите внимание, что переполнение DIV скрыто. Кажется, что по умолчанию элементы могут выпасть за пределы своего контейнера с переполнением по умолчанию visible. Это просто гарантирует, что ввод остается внутри своего контейнера и не пытается проткнуть его.

Я тестировал это в Chrome и Fire Fox. Оба, кажется, уважают это решение.

ОБНОВЛЕНИЕ : поскольку я только что получил случайное отрицательное голосование, я хотел бы сказать, что лучший способ справиться с переполнением - использовать атрибут CSS3 box-sizing, как описано pricco:

.myinput {
    -moz-box-sizing: border-box;
    -webkit-box-sizing: border-box;
    -ms-box-sizing: border-box;
    -o-box-sizing: border-box;
    box-sizing: border-box;
}

Кажется, что это довольно хорошо поддерживается основными браузерами и не является «взломанным», как трюк с переполнением. Однако при таком подходе в текущих браузерах возникают некоторые незначительные проблемы (см. Http://caniuse.com/#search=box-sizing Известные проблемы).

Дэвид Петерсон
источник
3
Краткое примечание: overflow: hidden;содержимое по-прежнему «высовывается» за пределы поля точно таким же образом, но оно усекается, а не отображается, поэтому оно не перекрывает другой контент.
ANeves
2

Я знаю, что этому вопросу 3 года, но проблема все еще сохраняется для текущих браузеров, и люди все еще приходят сюда. Решение на данный момент - calc () :

input {
    width: calc(100% - 12px); /* IE 9,10 , Chrome, Firefox */
    width: -webkit-calc(100% - 12px); /*For safari 6.0*/
}

Он поддерживается большинством современных браузеров.

троян
источник
1

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

Оберните ввод другим элементом, например, div. Затем примените стиль, который вы хотите для ввода, к этому div-оболочке. Например:

<div class="input-wrapper">
 <input type="text" />
</div>

.input-wrapper {
    border-raius:5px;
    padding:10px;
}
.input-wrapper input[type=text] {
    width:100%;
    font-size:16px;
}

Дайте .input-wrapper заполнение с закругленными углами и т.д., все, что вы хотите для своего ввода, затем укажите ширину ввода 100%. Ваш ввод красиво дополнен рамкой и т. Д., Но без раздражающего переполнения!

аллодиум
источник
1

Я исправил эту проблему, начиная с ответа @ hallodom. Все мои входные данные содержались внутри li, поэтому все, что мне нужно было сделать, это установить li overflow: hidden, чтобы удалить это избыточное переполнение ввода.

.ie7 form li {
  width:100%;
  overflow:hidden;
}

.ie7 input {
  width:100%;
}
чет
источник
1

вместо этой маржинальной борьбы просто сделай

input{
    width:100%;
    background:transparent !important;
}

таким образом граница ячейки видна, и вы можете контролировать цвет фона строки

Bortunac
источник
0

Выньте "http://www.w3.org/TR/html4/loose.dtd" из объявления DOCTYPE, и это решит вашу проблему.

Ура! :)

Люциан
источник
Вы имеете в виду использование http://www.w3.org/TR/html4/strict.dtdStrict? исх. w3.org/QA/2002/04/valid-dtd-list.html В любом случае это не вариант, потому что изменение DOCTYPE сейчас, вероятно, повлияет на отображение многих других материалов на веб-страницах.
Marco Demaio
0

С помощью Javascript вы можете получить точную ширину содержащего TD, а затем назначить ее непосредственно входному элементу.

Ниже приведен необработанный javascript, но jQuery сделает его чище ...

var inputs = document.getElementsByTagName('input');
for (var i = 0; i < inputs.length; i++)
{
    var el = inputs[i];
    if (el.style.width == '100%')
    {
        var pEl = el.parentNode;  // Assumes the parent node is the TD...
        el.style.width = pEl.offsetWidth;
    }
}

Проблемы с этим решением:

1) Если у вас есть входные данные, содержащиеся в другом элементе, таком как SPAN, вам понадобится цикл и найти TD, потому что такие элементы, как SPAN, будут обертывать вход и отображать его размер, а не ограничиваться размером TD.

2) Если у вас есть отступы или поля, добавленные на разных уровнях, возможно, вам придется явно вычесть это из [pEl.offsetWidth]. В зависимости от вашей структуры HTML, которая может быть рассчитана.

3) Если размер столбцов таблицы изменяется динамически, то изменение размера одного элемента приведет к перекомпоновке таблицы в некоторых браузерах, и вы можете получить ступенчатый эффект, поскольку вы последовательно «исправляете» размеры ввода. Решение состоит в том, чтобы назначить столбцу определенную ширину в процентах или в пикселях ИЛИ собрать новые значения ширины и установить их после. См. Код ниже ..

var inputs = document.getElementsByTagName('input');
var newSizes = [];
for (var i = 0; i < inputs.length; i++)
{
    var el = inputs[i];
    if (el.style.width == '100%')
    {
        var pEl = el.parentNode;  // Assumes the parent node is the TD...
        newSizes.push( { el: el, width: pEl.offsetWidth });
    }
}

// Set the sizes AFTER to avoid stepping...
for (var i = 0; i < newSizes.length; i++)
{
    newSizes[i].el.style.width = newSizes[i].width;
}
AnthonyVO
источник
0

Решил проблему, подав заявку box-sizing:border-box; к самим ячейкам таблицы, помимо того, что делает то же самое с вводом и оболочкой.

Vanco
источник
0

Я решил проблему с помощью этого

tr td input[type=text] {
  width: 100%;
  box-sizing: border-box;
  -webkit-box-sizing:border-box;
  -moz-box-sizing: border-box;
  background:transparent !important;
  border: 0px;
}
Кевин Мухват
источник
-1

Я обычно устанавливаю ширину ввода 99%, чтобы исправить это:

input {
    width: 99%;
}

Вы также можете удалить стили по умолчанию, но это сделает менее очевидным, что это текстовое поле. Однако я все равно покажу код для этого:

input {
    width: 100%;
    border-width: 0;
    margin: 0;
    padding: 0;
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
}

Ad @ m

Кирб
источник
-2

Проблема заключается в border-widthэлементе ввода. Вскоре попробуйте установить margin-leftдля элемента ввода значение -2px.

table input {
  margin-left: -2px;
}
Бурек Пекарич
источник
не думаю. это просто сдвигает поле влево и разрушает левое поле
cc young