Введення з дисплеєм: блок не є блоком, чому б і ні?


153

Чому display:block;width:auto;моє введення тексту не поводиться як div і не заповнює ширину контейнера?

У мене було враження, що div - це просто блок-елемент із автоматичною шириною. У наведеному нижче коді не повинні роздільник і вхід мати однакові розміри?

Як мені отримати вхід для заповнення ширини? 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, я намагаюся зрозуміти суть проблеми та чи її можна подолати, змінивши природу самого ВХОДУ.

Гаразд, це ДУЖЕ дивно! Я виявив, що рішення полягає в тому, щоб просто додати max-width:100%до вхідного сигналу width:100%;padding:5px;. Однак це викликає ще більше питань (про які я запитаю в окремому запитанні), але, схоже, ширина використовує звичайну модель CSS-коробки, а максимальна ширина використовує модель межі 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. Як питання, так і їх рішення перетинаються, але називати їх точними дублікатами просто неправильно.
amn

Відповіді:


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
Цей поліфункція від Schepp оновлює поліелектричну заправку IE6 / 7 для обробки більшої кількості крайових справ та роботи з IE8 над github: github.com/Schepp/box-sizing-polyfill
nicjohnson

Дякую! Я не міг розібратися, чому <input type = text> і <type type = submit> були різної ширини, коли я встановив би їх обох шириною 300px. Це вирішило це! Зауважте, що через два роки вам все одно потрібно використовувати префікс -moz- для останньої версії Firefox. caniuse.com/#feat=css3-boxsizing
Даррен Кук

4
На жаль, цей підхід не може бути використаний для усунення оболонки div, якщо вам також потрібно додати поля (оскільки поля не працюють правильно на жодному елементі, якщо ви використовуєте ширину: 100%)
SystemParadox

6
Однак це не вирішує проблеми. Так , це працює , якщо ви використовуєте , width:100%але це не робить , якщо ви використовуєте width:auto, дивіться тут: jsfiddle.net/hGuzE
Німрод

8

Причиною цього є те, що розмір введення тексту визначається атрибутом розміру. Додати розмір = "50" всередині тегу <input>. Потім змініть його на size = "100" - зрозумійте, що я маю на увазі?

Я підозрюю, що є краще рішення, але єдине, що мені спадає на думку, - це те, що я знайшов у питанні про "Приховані особливості HTML" на SO: Використовуйте вміст для редагування вмісту замість введення. Передача даних користувача до форми, що додається (якщо це потрібно), може бути дещо хитрою.

Приховані функції HTML


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

1
Однак те ж саме відбувається і з тим, buttonу кого немає sizeатрибута?
zanona

1
Питання, яке зосереджується більше на частині "чому такий стандарт подібний", як така відповідь: stackoverflow.com/questions/4567988/… Найголовніша заява полягає в тому, що це тому input, що це замінений елемент.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

7

Ваша найкраща ставка - обернути вхід у діві з вашою межею, полями тощо і мати вхід всередину шириною 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 і в інших місцях в Інтернеті) відповідь, здавалося б , що не звертаючи уваги на контракт питання Можу чи я запитати вас -. ? чому . Спасибо заранее -Curiously твоє.
атп

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% для отримання входів і вибору для відповідності. Мені дуже хочеться, щоб до тракту, як до діва, ставився, і я сподівався, що я просто щось не помітив.
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.