Ввод с отображением: блок не является блоком, почему бы и нет?


153

Почему display:block;width:auto;мой ввод текста не ведет себя как div и заполняет ширину контейнера?

У меня сложилось впечатление, что div - это просто элемент блока с автоматической шириной. В следующем коде не должны ли div и input иметь одинаковые размеры?

Как мне получить данные для заполнения ширины? Ширина 100% не будет работать, потому что вход имеет отступы и границу (конечная ширина 1 пиксель + 5 пикселей + 100% + 5 пикселей + 1 пиксель). Фиксированная ширина не вариант, и я ищу что-то более гибкое.

Я бы предпочел прямой ответ обходному пути. Это похоже на причуду CSS, и понимание этого может быть полезно позже.

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
    <head>
        <title>width:auto</title>

        <style>
        div, input {
            border: 1px solid red;
            height: 5px;
            padding: 5px;
        }
        input, form {
            display: block;
            width: auto;
        }
        </style>
    </head>

    <body>
        <div></div>
        <form>
            <input type="text" name="foo" />
        </form>
    </body>
</html>

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

Хорошо, это действительно странно! Я обнаружил, что решение состоит в том, чтобы просто добавить max-width:100%к входу с width:100%;padding:5px;. Однако это поднимает еще больше вопросов (которые я задам в отдельном вопросе), но кажется, что width использует обычную блочную модель CSS, а max-width использует граничную модель Internet Explorer. Как странно.

Хорошо, эта последняя ошибка в Firefox 3. Internet Explorer 8 и Safari 4 ограничивают максимальную ширину до 100% + отступ + граница, что и предписано в спецификации. Наконец, Internet Explorer понял что-то правильно.

Боже мой, это потрясающе! В процессе игры с этим, и с большой помощью почтенных гуру Дина Эдвардса и Эрика Арвидссона , мне удалось собрать воедино три отдельных решения, чтобы создать кросс-браузерную ширину 100% для элементов с произвольными отступами и границами. Смотрите ответ ниже. Это решение не требует какой-либо дополнительной разметки HTML, только класс (или селектор) и необязательное поведение для устаревшего Internet Explorer.


Точная
копия

7
@SleepyCod это не точная копия. Этот вопрос касается проблемы inputэлементов, которые явно не соответствуют спецификации CSS 2.1, в то время как вопрос, на который вы ссылаетесь, задает вопрос, как, кстати, предотвратить переполнение блоков, которое происходит в рамках спецификации CSS 2.1. И вопросы, и их решения пересекаются, но называть их точными дубликатами просто неправильно.
атп

Ответы:


130

Посмотрите, что я придумала, решение, использующее относительно неизвестный box-sizing:border-boxстиль из CSS 3. Это допускает «истинную» 100% ширину любого элемента независимо от заполнения и / или границ этих элементов.

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html;charset=utf-8">

        <title>Cross-browser CSS box-sizing:border-box</title>

        <style type="text/css">
            form {display:block; margin:0; padding:0; width:50%; border:1px solid green; overflow:visible}
            div, input {display:block; border:1px solid red; padding:5px; width:100%; font:normal 12px Arial}

            /* The voodoo starts here */
            .bb {
                box-sizing: border-box; /* CSS 3 rec */
                -moz-box-sizing: border-box; /* Firefox 2 */
                -ms-box-sizing: border-box; /* Internet Explorer 8 */
                -webkit-box-sizing: border-box; /* Safari 3 */
                -khtml-box-sizing: border-box; /* Konqueror */
            }
        </style>

        <!-- The voodoo gets scary. Force Internet Explorer 6 and Internet Explorer 7 to support Internet Explorer 5's box model -->
        <!--[if lt IE 8]><style>.bb {behavior:url("boxsizing.htc");}</style><![endif]-->
    </head>

    <body>
        <form name="foo" action="#">
            <div class="bb">div</div>
            <input class="bb" size="20" name="bar" value="field">
        </form>
    </body>
</html>

Это решение поддерживает Internet Explorer 6 и Internet Explorer 7 посредством поведения, написанного Эриком Арвидссоном с некоторыми изменениями от Дина Эдвардса для поддержки процента и других непиксельных значений ширины.

Рабочий пример
поведения (boxsizing.htc)


Это выглядит как удивительное решение, но не работает в IE8 (блоки div и field недостаточно широки). Знаете ли вы, было ли обновление этого метода? Спасибо!
rocketmonkeys

2
Этот polyfill от Schepp обновляет полифилл IE6 / 7, чтобы обрабатывать больше крайних случаев и работать с IE8 в github: github.com/Schepp/box-sizing-polyfill
nicjohnson

Спасибо! Я не мог понять, почему <input type = text> и <input type = submit> были разной ширины, когда я установил их ширину 300 пикселей. Это решило это! Обратите внимание, что два года спустя вам все еще нужно использовать префикс -moz- для последней версии Firefox. caniuse.com/#feat=css3-boxsizing
Даррен Кук,

4
К сожалению, этот подход не может быть использован для устранения div-оболочки, если вам также нужно добавить поля (потому что поля не работают правильно для любого элемента, если вы используете width: 100%)
SystemParadox

6
Это не решает проблему, хотя. Да, это работает, если вы используете, width:100%но это не так, если вы используете width:auto, см. Здесь: jsfiddle.net/hGuzE
nimrod

8

Причина этого заключается в том, что размер текстового ввода определяется его атрибутом размера. добавить размер = "50" внутри тега <input>. Затем измените его на size = "100" - понимаете, о чем я?

Я подозреваю, что есть лучшее решение, но единственное, что приходит на ум, - это то, что я нашел по вопросу «Скрытые возможности HTML» в SO: используйте редактируемый контент div вместо ввода. Передача пользовательского ввода во вложенную форму (если это то, что вам нужно) может быть немного сложнее.

Скрытые возможности HTML


8
Мне любопытно узнать, как люди CSS оправдывают это. Если ширина может переопределить размер явно с пикселями / процентом, я не понимаю, почему это должно продолжать соблюдать это, когда элемент является блоком.
SpliFF

1
Однако то же самое происходит buttonи с тем, у кого нет sizeатрибута?
Занона

1
Вопрос, который больше фокусируется на части «почему стандарт подобен этому», например, такой ответ: stackoverflow.com/questions/4567988/… Самое главное утверждение - это то, что он inputзаменен.
Сиро Сантилли 郝海东 冠状 病 六四 事件 法轮功

7

Лучше всего обернуть входные данные в div с вашей границей, полями и т. Д., И иметь вход внутри с шириной 100% и без рамки, без полей и т. Д.

Например,

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
    <head>
        <title>width:auto</title>

        <style>
            div {
                border: 1px solid red;
                padding: 5px;
            }
            input, form {
                display: block;
                width: 100%;
            }
        </style>
    </head>

    <body>
        <form>
            <div><input type="text" name="foo" /></div>
        </form>
    </body>
</html>

1
Да, это сработает, но это скорее обходной путь, чем ответ. я пытаюсь установить, почему ввод, кажется, игнорирует поведение блока.
SpliFF

2
Джонатан, пожалуйста, прости мою кажущуюся грубость, но я пришел сюда в поисках правильного ответа (tm), а также с удовольствием прочитал ту часть, где @SpliFF специально упоминает, что он предпочел бы «прямой ответ на обходной путь, но вы все равно добавляете еще один избыточный». (как, повторялось много раз и в SO, и в других местах в Интернете) ответ, казалось бы, игнорируя контракт вопроса. Могу ли я спросить вас - почему? Заранее спасибо.
am

1

Вы можете подделать это, как это:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
    <head>
        <title>width:auto</title>

        <style>
        div, #inputWrapper {
            border: 1px solid red;
        }
        #topDiv {
            padding: 5px;
            height: 5px;
        }
        form {
            display: block;
        }
        #inputWrapper {
            overflow: hidden;
            height: 15px;
        }
        input {
            display: block;
            width: 100%;
            border-style: none;
            padding-left: 5px;
            padding-right: 5px;
            height: 15px;
        }
        </style>
    </head>

    <body>
        <div id="topDiv"></div>
        <form>
          <div id="inputWrapper">
            <input type="text" name="foo" />
          </div>
        </form>
    </body>
</html>

1
В прошлом я использовал ложный подход, но, если честно, мне это надоело. В итоге я получаю все виды запаздывающих хаков, например, использую ширину 99% для получения входных данных и выбора для соответствия. Я действительно хочу, чтобы способ обрабатывал ввод как div, и я надеялся, что просто что-то пропустил.
SpliFF

2
также ваш ввод будет переполнен inputWrapper, потому что он все еще имеет ширину: 100% с внутренним заполнением.
SpliFF

1

Попробуй это:

form { padding-right: 12px; overflow: visible; }
input { display: block; width: 100%; }

1
Вы пропустили отступы ввода и границы. Я собирался сказать, что ты не прав, пока не понял, что ты делаешь. Теперь я понимаю, что Меркуро пытался сделать (его код все еще не верен, но концепция была почти у цели). Правый отступ меняет значение 100% на 12 пикселей (граница плюс отступ ввода). Недостаток этого подхода заключается в том, что все остальные дочерние элементы формы также подвержены влиянию заполнения и должны также компенсировать это.
SpliFF

1

Также вы можете подделать это, как это:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
    <head>
        <title>width:auto</title>

        <style>

            .container {
                width:90%;
            }

            .container div{
                border: 1px solid red;
                padding: 5px;
                font-size:12px;
                width:100%;
            }

            input{
                  width:100%;
                border: 1px solid red;
                font-size:12px;
                padding: 5px;
            }

            form {

                margin:0px;
                padding:0px;
            }

        </style>
    </head>

    <body>
        <div class="container">
            <div>
                asdasd
            </div>
            <form action="">
                <input type="text" name="foo" />
            </form>
        </div>
    </body>
</html>

1
с той же вероятностью, что и выше, у вас есть внутренние отступы на 100% ширины. Это переполнится.
SpliFF

Вы можете сделать это с помощью JavaScript
AlexC

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.