Eingabe mit Anzeige: Block ist kein Block, warum nicht?

153

Warum verhält sich display:block;width:auto;meine Texteingabe nicht wie ein Div und füllt die Containerbreite aus?

Ich hatte den Eindruck, dass ein div einfach ein Blockelement mit automatischer Breite ist. Sollten im folgenden Code nicht div und der Eingang identische Abmessungen haben?

Wie bekomme ich die Eingabe, um die Breite zu füllen? 100% Breite funktioniert nicht, da die Eingabe einen Abstand und einen Rand hat (was eine endgültige Breite von 1 Pixel + 5 Pixel + 100% + 5 Pixel + 1 Pixel verursacht). Feste Breiten sind keine Option, und ich suche etwas Flexibleres.

Ich würde eine direkte Antwort auf eine Problemumgehung vorziehen. Dies scheint eine CSS-Eigenart zu sein, und das Verständnis kann später nützlich sein.

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

Ich sollte darauf hinweisen, dass ich dies bereits mit Wrapper-Problemumgehungen tun kann. Abgesehen von dieser Verschraubung mit der Seitensemantik und den CSS-Auswahlbeziehungen versuche ich, die Art des Problems zu verstehen und zu verstehen, ob es durch Ändern der Art des EINGANGS selbst überwunden werden kann.

Ok, das ist wirklich seltsam! Ich habe festgestellt, dass die Lösung darin besteht, einfach max-width:100%eine Eingabe mit hinzuzufügen width:100%;padding:5px;. Dies wirft jedoch noch mehr Fragen auf (die ich in einer separaten Frage stellen werde), aber es scheint, dass width das normale CSS-Box-Modell und max-width das Internet Explorer-Border-Box-Modell verwendet. Wie seltsam.

Ok, das letzte scheint ein Fehler in Firefox 3 zu sein. Internet Explorer 8 und Safari 4 beschränken die maximale Breite auf 100% + Auffüllen + Rand, was in der Spezifikation angegeben ist. Schließlich hat Internet Explorer etwas richtig gemacht.

Oh mein Gott, das ist großartig! Während ich damit spielte und mit viel Hilfe der ehrwürdigen Gurus Dean Edwards und Erik Arvidsson , gelang es mir, drei separate Lösungen zusammenzusetzen, um eine echte browserübergreifende Breite von 100% für Elemente mit willkürlichen Auffüllungen und Rändern zu erzielen. Siehe Antwort unten. Diese Lösung erfordert kein zusätzliches HTML-Markup, nur eine Klasse (oder einen Selektor) und ein optionales Verhalten für den älteren Internet Explorer.

SpliFF
quelle
7
@SleepyCod das ist kein genaues Duplikat. Diese Frage befasst sich mit dem Problem von inputElementen, die anscheinend nicht der CSS 2.1-Spezifikation entsprechen, während die Frage, mit der Sie verknüpft haben, die Frage stellt, wie überlaufende Boxen verhindert werden können, die übrigens perfekt innerhalb der Grenzen der CSS 2.1-Spezifikation auftreten. Sowohl die Fragen als auch ihre Lösungen überschneiden sich, aber es ist einfach falsch
Amn

Antworten:

130

Schauen Sie sich an, was ich mir ausgedacht habe, eine Lösung, die den relativ unbekannten box-sizing:border-boxStil von CSS 3 verwendet. Dies ermöglicht eine "echte" Breite von 100% für jedes Element, unabhängig von der Auffüllung und / oder den Rändern dieser Elemente.

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

Diese Lösung unterstützt Internet Explorer 6 und Internet Explorer 7 über ein von Erik Arvidsson geschriebenes Verhalten mit einigen Verbesserungen von Dean Edwards, um prozentuale und andere Nicht-Pixel-Breiten zu unterstützen.

Arbeitsbeispiel
Verhalten (boxsizing.htc)

SpliFF
quelle
Dies sieht nach einer erstaunlichen Lösung aus, funktioniert jedoch nicht in IE8 (die Div & Field-Felder sind nicht breit genug). Wissen Sie, ob diese Methode aktualisiert wurde? Vielen Dank!
Raketenmonkey
2
Diese Polyfüllung von Schepp aktualisiert die IE6 / 7-Polyfüllung, um mehr Randfälle zu behandeln und mit IE8 bei github zu arbeiten: github.com/Schepp/box-sizing-polyfill
nicjohnson
Vielen Dank! Ich konnte nicht herausfinden, warum <input type = text> und <input type = submit> unterschiedliche Breiten hatten, als ich beide auf 300px Breite eingestellt hatte. Das hat es gelöst! Beachten Sie, dass Sie zwei Jahre später immer noch das Präfix -moz- für die neueste Version von Firefox verwenden müssen. caniuse.com/#feat=css3-boxsizing
Darren Cook
4
Leider kann dieser Ansatz nicht verwendet werden, um das Wrapper-Div zu entfernen, wenn Sie auch Ränder hinzufügen müssen (da Ränder bei keinem Element richtig funktionieren, wenn Sie width: 100% verwenden)
SystemParadox
6
Das behebt das Problem jedoch nicht. Ja, es funktioniert, wenn Sie verwenden, width:100%aber es funktioniert nicht, wenn Sie verwenden width:auto, siehe hier: jsfiddle.net/hGuzE
nimrod
8

Der Grund dafür ist, dass die Größe einer Texteingabe durch ihr Größenattribut bestimmt wird. add size = "50" innerhalb des <input> -Tags. Dann ändern Sie es in Größe = "100" - sehen Sie, was ich meine?

Ich vermute, es gibt eine bessere Lösung, aber die einzige, die mir in den Sinn kommt, ist etwas, das ich in der Frage "Versteckte Funktionen von HTML" zu SO gefunden habe: Verwenden Sie ein inhaltsbearbeitbares div anstelle einer Eingabe. Das Übergeben der Benutzereingaben an das beiliegende Formular (falls erforderlich) kann etwas schwierig sein.

Versteckte Funktionen von HTML

MatrixFrog
quelle
8
Ich bin gespannt, wie die CSS-Leute dies rechtfertigen. Wenn die Breite die Größe explizit mit Pixeln / Prozent überschreiben kann, verstehe ich nicht, warum sie weiterhin berücksichtigt werden sollte, wenn das Element ein Block ist.
SpliFF
1
Aber das gleiche passiert buttonauch mit dem, das kein sizeAttribut hat?
Zanona
1
Eine Frage, die sich mehr auf den Teil "Warum ist der Standard so ? " Konzentriert, wie diese Antwort: stackoverflow.com/questions/4567988/… Die oberste Behauptung dort ist, dass es sich inputum ein ersetztes Element handelt.
Ciro Santilli 法轮功 冠状 病 六四 事件 27
7

Am besten wickeln Sie die Eingabe in ein Div mit Ihrem Rand, Ihren Rändern usw. ein und lassen die Eingabe mit einer Breite von 100% und ohne Rand, ohne Ränder usw. im Inneren.

Beispielsweise,

<!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>
Jonathan Fingland
quelle
1
Ja, es wird funktionieren, aber das ist eher eine Problemumgehung als eine Antwort. Ich versuche herauszufinden, warum die Eingabe das Blockverhalten zu ignorieren scheint.
SpliFF
2
Jonathan, bitte verzeihen Sie meine offensichtliche Unhöflichkeit hier, aber ich bin hierher gekommen, um nach der richtigen (tm) Antwort zu suchen, und habe auch gerne den Teil gelesen, in dem @SpliFF ausdrücklich erwähnt, dass er eine "direkte Antwort auf eine Problemumgehung" vorziehen würde, aber Sie fügen noch eine weitere überflüssige hinzu (wie in, viele Male wiederholt sowohl auf sO und anderswo im Internet) Antwort, scheinbar den Vertrag der Frage ignorieren Darf ich Sie fragen -. ? , warum . vielen Dank im Voraus -Curiously Ihnen.
amn
1

Sie könnten es so vortäuschen:

<!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>
Jacob
quelle
1
Ich habe in der Vergangenheit den falschen Ansatz gewählt, aber um ehrlich zu sein, habe ich es satt. Am Ende habe ich alle Arten von verzögerten Hacks, wie zum Beispiel die Verwendung von 99% Breite, um passende Eingaben und Auswahlen zu erhalten. Ich möchte wirklich einen Weg finden, einen Input wie einen Div zu behandeln, und ich hatte gehofft, ich hätte gerade etwas übersehen.
SpliFF
2
Außerdem wird Ihre Eingabe in inputWrapper überlaufen, da sie immer noch eine Breite von 100% mit einem internen Abstand hat.
SpliFF
1

Versuche dies:

form { padding-right: 12px; overflow: visible; }
input { display: block; width: 100%; }
Mike
quelle
1
Sie haben das Eingabefeld und den Rand weggelassen. Ich wollte gerade sagen, dass du falsch liegst, bis mir klar wurde, was du tust. Jetzt verstehe ich, was Merkuro versucht hat (sein Code ist immer noch falsch, aber das Konzept war fast da). Das Auffüllrecht ändert die Bedeutung von 100% um 12 Pixel (Rand plus Auffüllen der Eingabe). Der Nachteil dieses Ansatzes ist jedoch, dass auch alle anderen Kinder der Form von der Polsterung betroffen sind und diese ebenfalls kompensieren müssen.
SpliFF
1

Sie könnten es auch so vortäuschen:

<!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>
AlexC
quelle
1
Mit der gleichen Wahrscheinlichkeit wie oben haben Sie eine interne Polsterung mit einer Breite von 100%. Das wird überlaufen.
SpliFF
Sie können dies mit Javascript tun
AlexC
1

Fügen Sie dies Ihrem Stil hinzu:

box-sizing: border-box;
John Porter
quelle