Ingresso con display: blocco non è un blocco, perché no?


153

Perché display:block;width:auto;il mio input di testo non si comporta come un div e riempie la larghezza del contenitore?

Avevo l'impressione che un div fosse semplicemente un elemento a blocchi con larghezza automatica. Nel codice seguente div e input non dovrebbero avere dimensioni identiche?

Come ottengo l'input per riempire la larghezza? La larghezza del 100% non funzionerà, perché l'input ha un'imbottitura e un bordo (che causa una larghezza finale di 1 pixel + 5 pixel + 100% + 5 pixel + 1 pixel). Le larghezze fisse non sono un'opzione e sto cercando qualcosa di più flessibile.

Preferirei una risposta diretta a una soluzione alternativa. Sembra una stranezza CSS e capire che potrebbe essere utile in seguito.

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

Devo sottolineare che posso già farlo con soluzioni alternative wrapper. A parte questo rovinare con la semantica della pagina e le relazioni con i selettori CSS, sto cercando di capire la natura del problema e se può essere superato cambiando la natura dell'INPUT stesso.

Ok, questo è VERAMENTE strano! Ho scoperto che la soluzione è semplicemente aggiungere max-width:100%a un input con width:100%;padding:5px;. Tuttavia, ciò solleva ancora più domande (che farò in una domanda separata), ma sembra che la larghezza usi il normale modello di box CSS e la larghezza massima usi il modello di border-box di Internet Explorer. Che strano.

Ok, l'ultimo sembra essere un bug in Firefox 3. Internet Explorer 8 e Safari 4 limitano la larghezza massima al 100% + riempimento + bordo che è ciò che le specifiche dicono di fare. Finalmente, Internet Explorer ha fatto qualcosa di giusto.

Oh mio Dio, è fantastico! Nel processo di gioco con questo, e con molto aiuto del venerabile guru Dean Edwards e Erik Arvidsson , sono riuscito a mettere insieme tre soluzioni separate per creare un vero cross-browser 100% di larghezza su elementi con imbottitura e bordi arbitrari. Vedi la risposta sotto. Questa soluzione non richiede alcun markup HTML aggiuntivo, solo una classe (o un selettore) e un comportamento facoltativo per Internet Explorer legacy.



7
@SleepyCod che non è un duplicato esatto. Questa domanda affronta il problema di inputelementi che apparentemente non rispettano la specifica CSS 2.1, mentre la domanda a cui ti sei collegato chiede come evitare caselle traboccanti che si verificano perfettamente entro i limiti della specifica CSS 2.1. Sia le domande che le loro soluzioni si sovrappongono ma chiamarle esattamente duplicati è semplicemente sbagliata.
AMN

Risposte:


130

Scopri cosa mi è venuto in mente, una soluzione che utilizza lo box-sizing:border-boxstile relativamente sconosciuto di CSS 3. Ciò consente una larghezza "reale" del 100% su qualsiasi elemento indipendentemente dall'imbottitura e / o dai bordi di quell'elemento.

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

Questa soluzione supporta Internet Explorer 6 e Internet Explorer 7 tramite un comportamento scritto da Erik Arvidsson con alcune modifiche da Dean Edwards per supportare percentuali e altre larghezze non pixel.

Esempio di funzionamento
Comportamento (boxsizing.htc)


Sembra una soluzione straordinaria, ma non funziona in IE8 (i box div e field non sono abbastanza larghi). Sai se ci sono stati aggiornamenti su questo metodo? Grazie!
rocketmonkeys,

2
Questo polyfill di Schepp aggiorna il polyfill IE6 / 7 per gestire più casi limite e lavorare con IE8 su github: github.com/Schepp/box-sizing-polyfill
nicjohnson

Grazie! Non riuscivo a capire perché <input type = text> e <input type = submit> avessero larghezze diverse quando le avrei impostate su 300 pixel di larghezza. Questo ha risolto! Si noti che due anni dopo è ancora necessario utilizzare il prefisso -moz- per l'ultima versione di Firefox. caniuse.com/#feat=css3-boxsizing
Darren Cook

4
Sfortunatamente, questo approccio non può essere utilizzato per eliminare il div wrapper se è necessario anche aggiungere margini (perché i margini non funzionano bene su alcun elemento se si utilizza la larghezza: 100%)
SystemParadox

6
Ciò non risolve il problema però. Sì funziona se si usa width:100%ma non è così se si utilizza width:auto, vedere qui: jsfiddle.net/hGuzE
Nimrod

8

Il motivo per cui ciò accade è che la dimensione di un input di testo è determinata dal suo attributo size. aggiungi size = "50" all'interno del tag <input>. Quindi cambiarlo in size = "100" - vedi cosa intendo?

Ho il sospetto che esista una soluzione migliore, ma l'unica che mi viene in mente è qualcosa che ho trovato sulla domanda "Funzioni nascoste di HTML" su SO: utilizzare un div modificabile del contenuto, anziché un input. Passare l'input dell'utente al modulo allegato (se è quello che devi fare) potrebbe essere un po 'complicato.

Funzionalità nascoste di HTML


8
Sono curioso di sapere come le persone CSS lo giustifichino. Se la larghezza può sovrascrivere esplicitamente la dimensione con pixel / percentuale, non vedo perché dovrebbe continuare a onorarla quando l'elemento è un blocco.
SpliFF,

1
Tuttavia lo stesso succede buttonanche a chi non ha un sizeattributo?
zanona,

1
Una domanda che si concentra maggiormente sulla parte "perché è lo standard come questo" come questa risposta: stackoverflow.com/questions/4567988/… L'affermazione principale è che è perché inputè un elemento sostituito.
Ciro Santilli 27 冠状 病 六四 事件 法轮功

7

La tua scommessa migliore è di avvolgere l'input in un div con il bordo, i margini, ecc. E avere l'input all'interno con larghezza 100% e senza bordo, senza margini, ecc.

Per esempio,

<!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
Sì, funzionerà ma è più una soluzione che una risposta. Sto cercando di stabilire perché l'input sembra ignorare il comportamento del blocco.
SpliFF,

2
Jonathan, ti prego di perdonare la mia apparente maleducazione qui, ma sono venuto qui cercando la risposta giusta (tm), e ho anche letto volentieri la parte in cui @SpliFF menziona specificamente che preferirebbe una "risposta diretta a una soluzione alternativa, ma ne aggiungi ancora un'altra ridondante (come in, ripetuto molte volte sia a SO e altrove su Internet) risposta, apparentemente ignorando il contratto della questione Posso chiedervi -. ? perché . Grazie in anticipo la vostra -Curiously.
AMN

1

Potresti fingere, in questo modo:

<!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
Ho fatto l'approccio falso in passato, ma ad essere sincero mi sto stancando. Finisco con tutti i tipi di hack ritardati come usare la larghezza del 99% per ottenere input e seleziona la corrispondenza. Voglio davvero un modo per trattare un input come un div e speravo di aver trascurato qualcosa.
SpliFF,

2
anche il tuo input traboccerà inputWrapper perché ha ancora larghezza: 100% con un'imbottitura interna.
SpliFF,

1

Prova questo:

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

1
hai lasciato fuori l'imbottitura e il bordo di input. Stavo per dire che ti sbagli fino a quando non ho capito cosa stai facendo. Ora capisco cosa stava cercando di fare Merkuro (il suo codice è ancora sbagliato, ma il concetto era quasi arrivato). Il padding-right cambia il significato del 100% di 12px (border plus padding of input). Lo svantaggio di questo approccio è che anche tutti gli altri figli della forma sono influenzati dall'imbottitura e devono anche compensare.
SpliFF,

1

Inoltre potresti simularlo, in questo modo:

<!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
stesso problema come sopra, hai un'imbottitura interna su una larghezza del 100%. Quello traboccerà.
SpliFF,

puoi farlo con javascript
AlexC,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.