Wejście z wyświetlaczem: blok nie jest blokiem, dlaczego nie?


153

Dlaczego display:block;width:auto;mój tekst nie zachowuje się jak element DIV i nie wypełnia szerokości kontenera?

Miałem wrażenie, że div to po prostu element blokowy z automatyczną szerokością. Czy w poniższym kodzie div i wejście nie powinny mieć identycznych wymiarów?

Jak uzyskać dane wejściowe, aby wypełnić szerokość? 100% szerokości nie będzie działać, ponieważ dane wejściowe mają wypełnienie i obramowanie (co daje końcową szerokość 1 piksela + 5 pikseli + 100% + 5 pikseli + 1 piksel). Stałe szerokości nie wchodzą w grę, a ja szukam czegoś bardziej elastycznego.

Wolałbym bezpośrednią odpowiedź na obejście. Wygląda to na dziwactwo CSS i zrozumienie tego może być przydatne później.

<!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>

Powinienem zaznaczyć, że mogę już to zrobić dzięki obejściom opakowania. Oprócz tego pieprzenia się z semantyką strony i relacjami selektorów CSS, próbuję zrozumieć naturę problemu i czy można go rozwiązać, zmieniając naturę samego WEJŚCIA.

Ok, to jest NAPRAWDĘ dziwne! Odkryłem, że rozwiązaniem jest po prostu dodanie max-width:100%do danych wejściowych za pomocą width:100%;padding:5px;. Jednak powoduje to jeszcze więcej pytań (które zadam w osobnym pytaniu), ale wydaje się, że width korzysta z normalnego modelu CSS box, a max-width korzysta z modelu border-box przeglądarki Internet Explorer. Jakie to dziwne.

Ok, ten ostatni wydaje się być błędem w Firefoksie 3. Internet Explorer 8 i Safari 4 ograniczają maksymalną szerokość do 100% + dopełnienie + obramowanie, co mówi specyfikacja. Wreszcie Internet Explorer ma coś w porządku.

O mój Boże, to jest niesamowite! W trakcie zabawy i przy dużej pomocy czcigodnych guru, Deana Edwardsa i Erika Arvidssona , udało mi się złożyć razem trzy oddzielne rozwiązania, aby stworzyć prawdziwą 100% szerokość między przeglądarkami na elementach z dowolnym wypełnieniem i obramowaniami. Zobacz odpowiedź poniżej. To rozwiązanie nie wymaga żadnych dodatkowych znaczników HTML, wystarczy klasa (lub selektor) i opcjonalne zachowanie dla starszej wersji programu Internet Explorer.



7
@SleepyCod to nie jest dokładny duplikat. To pytanie dotyczy problemu inputelementów, które najwyraźniej nie są zgodne ze specyfikacją CSS 2.1, podczas gdy pytanie, do którego utworzyłeś łącze, dotyczy tego, jak zapobiec przepełnieniu pól, które, nawiasem mówiąc, występuje idealnie w granicach specyfikacji CSS 2.1. Zarówno pytania, jak i ich rozwiązania pokrywają się, ale nazywanie ich dokładnymi duplikatami jest po prostu błędne.
rano

Odpowiedzi:


130

Sprawdź, co wymyśliłem, rozwiązanie wykorzystujące stosunkowo nieznany box-sizing:border-boxstyl z CSS 3. Pozwala to na „prawdziwą” 100% szerokość dowolnego elementu, niezależnie od wypełnienia i / lub obramowania tych elementów.

<!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>

To rozwiązanie obsługuje przeglądarki Internet Explorer 6 i Internet Explorer 7 za pomocą zachowania napisanego przez Erika Arvidssona z kilkoma poprawkami od Deana Edwardsa, aby obsługiwać procentową i inną szerokość niepikselową.

Roboczy przykład
zachowania (boxsizing.htc)


Wygląda to na niesamowite rozwiązanie, ale nie działa w IE8 (pola div i field nie są wystarczająco szerokie). Czy wiesz, czy była jakaś aktualizacja tej metody? Dzięki!
rocketmonkeys

2
To wypełnienie autorstwa Scheppa aktualizuje wypełniacz IE6 / 7, aby obsłużyć więcej przypadków skrajnych i pracować z IE8 na github: github.com/Schepp/box-sizing-polyfill
nicjohnson

Dzięki! Nie mogłem zrozumieć, dlaczego <input type = text> i <input type = submit> miały różne szerokości, kiedy ustawiłem je na szerokość 300 pikseli. To rozwiązało problem! Zauważ, że dwa lata później nadal musisz używać przedrostka -moz- dla najnowszej wersji przeglądarki Firefox. caniuse.com/#feat=css3-boxsizing
Darren Cook

4
Niestety, takie podejście nie może być stosowany do usuwania div otoki jeśli trzeba także dodać marginesy (ponieważ marże NIE prawo działać na każdym elemencie jeśli używasz width: 100%)
SystemParadox

6
To jednak nie rozwiązuje problemu. Tak, działa, jeśli używasz, width:100%ale nie działa, jeśli używasz width:auto, zobacz tutaj: jsfiddle.net/hGuzE
nimrod

8

Dzieje się tak, ponieważ rozmiar tekstu wejściowego jest określany przez jego atrybut rozmiaru. dodaj size = "50" wewnątrz tagu <input>. Następnie zmień to na size = "100" - rozumiesz, co mam na myśli?

Podejrzewam, że istnieje lepsze rozwiązanie, ale jedyne, które przychodzi mi na myśl, to coś, co znalazłem w pytaniu „Ukryte funkcje HTML” na SO: Użyj edytowalnego elementu div zamiast danych wejściowych. Przekazywanie danych wejściowych użytkownika do otaczającego formularza (jeśli tego potrzebujesz) może być trochę trudne.

Ukryte funkcje HTML


8
Jestem ciekawy, jak usprawiedliwiają to ludzie z CSS. Jeśli szerokość może jawnie zastąpić rozmiar pikselami / procentami, nie rozumiem, dlaczego miałby nadal go honorować, gdy element jest blokiem.
SpliFF

1
Jednak to samo dzieje się z buttontym, który nie ma sizeatrybutu?
zanona

1
Pytanie, które koncentruje się bardziej na części „dlaczego jest taki standard”, jak ta odpowiedź: stackoverflow.com/questions/4567988/… Najważniejsze twierdzenie jest takie, że to dlatego, że inputjest wymieniony element.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

7

Najlepszym rozwiązaniem jest zawinięcie danych wejściowych w element div z obramowaniem, marginesami itp. I umieszczenie w środku danych o szerokości 100% i bez obramowania, bez marginesów itp.

Na przykład,

<!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
Tak, to zadziała, ale to raczej obejście niż odpowiedź. próbuję ustalić, dlaczego dane wejściowe wydają się ignorować zachowanie blokowe.
SpliFF

2
Jonathan, proszę wybacz mi moją pozorną niegrzeczność, ale przyszedłem tutaj, szukając właściwej (tm) odpowiedzi, a także z przyjemnością przeczytałem część, w której @SpliFF wyraźnie wspomina, że ​​wolałby „bezpośrednią odpowiedź na obejście, ale nadal dodajesz kolejną zbędną (jak w, powtarzana wielokrotnie zarówno w SO i gdzie indziej w Internecie) odpowiedź, pozornie ignorując umowę z pytaniem. Czy mogę zapytać - dlaczego? Z góry dziękuję.
amn

1

Możesz to udawać, na przykład:

<!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
W przeszłości stosowałem fałszywe podejście, ale szczerze mówiąc mam już tego dość. Skończyłem z różnego rodzaju opóźnionymi hackami, takimi jak używanie 99% szerokości do uzyskania danych wejściowych i selekcji do dopasowania. Naprawdę potrzebuję sposobu, aby traktować dane wejściowe jak div i miałem nadzieję, że właśnie coś przeoczyłem.
SpliFF

2
również twoje dane wejściowe przepełnią inputWrapper, ponieważ nadal ma szerokość: 100% z wewnętrznym wypełnieniem.
SpliFF

1

Spróbuj tego:

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

1
pominięto dopełnienie i obramowanie danych wejściowych. Już miałem powiedzieć, że się mylisz, dopóki nie zrozumiałem, co robisz. Teraz rozumiem, co próbował zrobić merkuro (jego kod jest nadal błędny, ale koncepcja była prawie gotowa). Dopełnienie w prawo zmienia znaczenie o 100% na 12 pikseli (obramowanie plus wypełnienie wejścia). Wadą tego podejścia jest jednak to, że wszystkie inne elementy podrzędne formy również podlegają wyściółce i również muszą to kompensować.
SpliFF

1

Możesz też to udawać, na przykład:

<!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
taki sam problem jak powyżej, masz wewnętrzne wypełnienie na 100% szerokości. To się przepełni.
SpliFF

możesz to zrobić za pomocą javascript
AlexC

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.