Как сделать так, чтобы поле ввода текста занимало всю оставшуюся ширину в родительском блоке?

Как добиться следующего:

┌────────────────────parent────────────────────┐
│ label [text-box                   ] [button] │
│ paragraph                                    │
└──────────────────────────────────────────────┘
  • label выровнено по левому краю
  • button выровнено по правому краю
  • text-box занимает всю оставшуюся ширину внутри родителя
  • paragraph выровнено по левому краю, также должно быть выровнено по левому краю с label

И label, и button должны максимально соответствовать свойствам шрифта, определенным в другом месте. parent выравнивается по центру окна и, естественно, может иметь произвольную ширину.

Пожалуйста, порекомендуйте.


person user422039    schedule 28.04.2011    source источник


Ответы (6)


Обновлено [октябрь 2016 г.]: версия Flexbox...

form {
  display: flex;
}
form input[type="text"] {
  flex: 1;
}
<form>
  <label>Name</label>
  <input type="text" />
  <button>Submit</button>
</form>
<p>Lorem ipsum...</p>

Исходный ответ [апрель 2011 г.]: версия CSS без таблиц (поведения таблицы)...

<div id="parent">
    <div id="inner">
        <label>Name</label>
        <span><input id="text" type="text" /></span>
        <input id="submit" type="button" value="Submit" />
    </div>
    <p>some paragraph text</p>
</div>

CSS...

#inner {
    display: table;
    width: 100%;
}
label {
    display: table-cell;
}
span {
    display: table-cell;
    width: 100%;
    padding: 0px 10px;
}
#text {
    width: 100%;
}
#submit {
    display: table-cell;
}

Демонстрация: http://jsfiddle.net/wdm954/626B2/4/

person wdm    schedule 28.04.2011
comment
Это выглядит красиво, пока родительский блок не задал экстремальную ширину. Растяните его, и между текстом метки и полем ввода текста будет большая дыра. Сожмите его, и текст с узлами метки и кнопки рухнет. Это суть проблемы, с которой я борюсь. - person user422039; 29.04.2011
comment
Круто, спасибо, теперь работает полностью независимо от ширины родителя - person user422039; 03.05.2011
comment
да, это круто, но не будет работать в IE7, потому что не поддерживает display: table-cell; - person jasin_89; 17.12.2012
comment
вот решение для работы в IE7: stackoverflow.com/questions/5219175/width-100-padding - person jasin_89; 17.12.2012

Мне не нравится первый ответ с версией «без таблицы», которая фактически использует ячейку таблицы. Ни второй ответ, который использует фактические таблицы. Ни третий ответ, который использует жестко закодированную ширину. Вот решение с использованием flex. Это намного проще:

#parent {
  display: flex;
}
input {
  flex: 1;
}
<div id="parent">
  <label>Name</label>
  <input type="text" />
  <button>Button</button>
</div>
<div>paragraph</div>

person asdjfiasd    schedule 07.07.2015
comment
Обратите внимание, что flex не работает в браузерах Android 4.2, что не позволяет создавать кроссплатформенные приложения Cordova. Flex очень упрощает вещи, и мне это очень нравится, но для совместимости еще один или два года нам придется использовать вместо них числа с плавающей запятой. - person Brian Cannard; 01.03.2017

Используйте таблицы. :D Я знаю, что люди склонны ненавидеть столы, но в этой ситуации они сработают...

<div id="parent">
    <table style="width:100%">
        <tr>
            <td>label</td>
            <td style="width:100%">
                <input type="text" style="width:100%">
            </td>
            <td>
                <button>clickme</button>
            </td>
        </tr>
    </table>
</div>
person Thomas Shields    schedule 28.04.2011
comment
Теперь мне любопытно, как это работает, потому что это работает (без предопределенной ширины, даже в процентах) - person user422039; 29.04.2011
comment
потому что определение ячейки таблицы должно продолжаться до тех пор, пока она не достигнет следующей ячейки или конца строки или таблицы. Вам не нужно его указывать. - person Thomas Shields; 29.04.2011
comment
сделать все как можно проще, но не проще, сказал Эйнштейн. Это аргумент в пользу решения вашей таблицы. Оккам тоже согласился бы, и бритва прочь болтливое решение div. Одни верят в непорочное зачатие, другие в отказ от столов. Должен иметь веру. Просто должен. - person mathheadinclouds; 30.04.2013
comment
Он работает без таблиц, когда вы помещаете кнопку перед полем ввода и назначаете ей float: right и заключаете поле ввода внутрь диапазона с помощью display: block и overflow: hidden. Без магии: <div style="width:100%"><button style="float:right">clickme 2</button><button style="float:right">clickme 1</button><label style="float:left">label</label><span style="display:block;overflow:hidden"><input type="text" style="width:100%"/></span></div>. Основная идея заключается в том, что все правые кнопки указаны в обратном порядке. - person Brian Cannard; 01.03.2017

Единственный способ, которым я знаю, как добиться этого или подобного, - это иметь «текстовое поле» в качестве блочного элемента, который автоматически заполнит всю ширину родителя, а затем применит отступ слева и справа, равный общей ширине контейнеры слева и справа. Затем сделайте так, чтобы для элементов «метка» и «кнопка» была задана позиция как относительная, и перемещайте их туда, где они должны быть (плавать: слева, плавать: справа).

Что-то вроде,

HTML:

<div id="parent">
    <div id="label">label</div>
    <div id="button">button</div>
    <div id="text-box">
        text<br />
        text<br />
        text<br />
        text<br />
        text
    </div>
</div>

CSS:

div#label
{
    position: relative;
    float: left;
    width: 200px;
    background: #F00;
}

div#button
{
    position: relative;
    float: right;
    width: 120px;
    background: #0F0;
}

div#text-box
{
    padding-left: 200px;
    padding-right: 120px;
    background: #00F;
}

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

person Marty    schedule 28.04.2011
comment
К сожалению, блок кнопки всплывает над блоком текстового поля, перекрывая его содержимое (попробуйте: непрозрачность: 0,75). Кроме того, ознакомьтесь с моим комментарием к ответу wdm о хрупкости ширины в процентах. - person user422039; 29.04.2011
comment
Вы можете избежать схлопывания левого и правого элементов, задав телу минимальную ширину. Я не уверен, что вы имеете в виду под дырой между текстом метки и текстовым вводом. Мое решение гарантирует, что содержимое текстового поля всегда привязан к правой стороне элемента ввода. - person Marty; 29.04.2011
comment
Элементы метки и кнопки перекрывают область текстового поля. Но содержимое в этой области никогда не будет позади или внизу из-за примененного отступа. - person Marty; 29.04.2011
comment
Он работает без таблиц, когда вы помещаете кнопку перед полем ввода и назначаете ей float: right и заключаете поле ввода внутрь диапазона с помощью display: block и overflow: hidden. Без магии: <div style="width:100%"><button style="float:right">clickme 2</button><button style="float:right">clickme 1</button><label style="float:left">label</label><span style="display:block;overflow:hidden"><input type="text" style="width:100%"/></span></div>. Основная идея заключается в том, что все правые кнопки указаны в обратном порядке. - person Brian Cannard; 01.03.2017

Не забывайте, вы можете использовать calc(). Предположим, что общая ширина, используемая label и button, составляет 100 пикселей (включая поля), тогда ширина равна:

.text-box {    
  width: calc(100% - 100px);
}

Если вы думаете, что он не поддерживает многие браузеры, вы действительно ошибаетесь. Сейчас очень многое поддерживает. Время изменилось

person Aminah Nuraini    schedule 02.07.2016
comment
Ух ты! Похоже, это поддерживается довольно давно, даже в IE9. Я удивлен, что больше этого не вижу. - person SouthShoreAK; 18.07.2016

Без flex и таблиц работает, если назначить float: right и поставить кнопку (или несколько кнопок в обратном порядке) перед полем ввода.

Затем поместите метку с помощью float: left, задайте поле ввода 100 % ширины и оберните его внутри span с помощью display: block. и overflow: hidden.

Никакой магии:

<div style="width:100%">
  <button style="float:right">clickme 2</button>
  <button style="float:right">clickme 1</button>
  <label style="float:left">label</label>
  <span style="display:block;overflow:hidden">
    <input type="text" style="width:100%"/>
  </span>
</div>

Основная идея заключается в том, что все правые кнопки указываются перед полем ввода в обратном порядке.

person Brian Cannard    schedule 01.03.2017
comment
Для тех, кому нужна метка для передачи кликов и нажатий в поле ввода и его переноса, padding-right: 100% и margin-right: -100% — единственное решение в этом случае. Но будет обнаружено, что он рисует кнопки, которые нельзя нажимать. Мне нравится совет stackoverflow.com/a/4408709/84661. Полное решение находится здесь: codepen.io/avesus/pen/VpaPWK - person Brian Cannard; 03.03.2017