La casella di testo di input HTML con una larghezza del 100% supera le celle della tabella


106

Qualcuno sa perché gli elementi di input con una larghezza del 100% superano il bordo delle celle della tabella.

Nel semplice esempio sotto la casella di input, vai sul bordo delle celle della tabella, il risultato è orribile. Questo è stato testato e accade allo stesso modo su: Firefox, IE7 e Safari.

Ha senso per te? Mi manca qualcosa, conosci una possibile soluzione?

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">    
<html><head>    
   <meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> <!-- don't use closing slash in meta tag, it breaks HTML4.01 transitional -->
   <title>Test input text in table</title>
   <style type="text/css">      
      table {border-top: 1px solid #ff0000; border-left: 1px solid #ff0000;}
      table td {border-right: 1px solid #00ff00; border-bottom: 1px solid #00ff00;}
      input[type="text"] {width: 100%;} /* removing this would make input not to go over cells border, but they would be too short, I want them to fit cells size */
   </style>    
</head><body>

<table cellpadding="0" cellspacing="0">
   <tr>
      <td><p>column one hello babe babe babe</p></td>
      <td><p>column two hello babe more</p></td>
      <td><p>column three hello babe more and more</p></td>
   </tr>
   <tr>
      <td><input type="text" value="test"></td>
      <td><input type="text" value="test"></td>
      <td><input type="text" value="test"></td>
   </tr>
</table>

</body></html>

1
Suggerirei che, se stai usando solo una tabella per presentare gli input, potresti passare all'uso di a formcon labels e inputs all'interno di a ulo ol. che è, almeno leggermente più semantico. Sicuramente, però, dovresti usare un form, anche se rimani con il table.
David dice di reintegrare Monica

Risposte:


216

È possibile utilizzare la box-sizingproprietà CSS3 per includere la spaziatura interna e il bordo esterni:

input[type="text"] {
     width: 100%; 
     box-sizing: border-box;
     -webkit-box-sizing:border-box;
     -moz-box-sizing: border-box;
}

1
Triste a dirsi, ma sfortunatamente IE 7 non si occupa correttamente del dimensionamento della scatola. Prova quanto segue in IE 7 ... css3.info/preview/box-sizing o vedi css-tricks.com/box-sizing
AnthonyVO,

@AnthonyVO: vero, l'unica soluzione alternativa per IE7 è aggiungere CSS specifici utilizzando commenti condizionali di IE <!--[if lt IE 8]>einput[type="text"] {width:95%}
Marco Demaio

24

Il valore della larghezza non tiene conto del bordo o del riempimento:

http://www.htmldog.com/reference/cssproperties/width/

Ottieni 2 px di imbottitura su ciascun lato, più 1 px di bordo su ciascun lato.
100% + 2 * (2px + 1px) = 100% + 6px, che è più del 100% di contenuto figlio del padre td.

Hai la possibilità di:

  • O impostazione box-sizing: border-box;come da risposta di @ pricco ;
  • O usando 0 margine e riempimento (evitando la dimensione extra).

oltre alla risposta di Sr pts puoi impostare il padding e il bordo su 0px, quindi il 100% dovrebbe funzionare.
Mauro

In effetti, anche senza impostare alcun riempimento per td - molto ben aggiunto.
ANeves

1
Inoltre, se il riempimento crea un problema, è possibile utilizzarlo text-indentper simulare il riempimento prima del bordo iniziale del testo e line-heightper il riempimento verticale (anche se mantenere il riempimento verticale non influirebbe comunque sulla larghezza).
David dice di reintegrare Monica

14

Il problema con cose del genere width:95%;è che non sembrano giuste in layout ampi e flessibili (perché il 5% può quindi essere come 30 pixel).

Le seguenti soluzioni funzionano molto bene per me (testate in Firefox, IE 9, Safari):

<table style="background-color: blue; width: 100%;" cellpadding="0" cellspacing="0">
<tr>
    <td style="background-color: red;   padding: 3px;">
        <div style="margin-right: 3px;">
            <div style="padding-right: 3px;">
                <input type="text" style="width:100%;">
            </div>
        </div>
    </td>
    <td style="background-color: purple;   padding: 3px;">
        <div style="margin-right: 3px;">
            <div style="padding-right: 3px;">
                <input type="text" style="width:100%;">
            </div>
        </div>
    </td>
    <td style="background-color: green;   padding: 3px;">
        <div style="margin-right: 3px;">
            <div style="padding-right: 3px;">
                <input type="text" style="width:100%;">
            </div>
        </div>
    </td>
</tr>
</table>

(aggiunti i colori per rendere più facile notare la corretta imbottitura)

Il trucco è racchiudere l'input con due div, l'esterno ha un margine di 3px (che lo rende 3px più piccolo del td), l'interno ha un'imbottitura di 3px. Questo rende l'input 6px più piccolo del td, che è ciò con cui volevi iniziare.

Non sono sicuro della meccanica di questo, ma funziona.

In questo semplice esempio, funziona anche con un solo div con margine destro 6. Tuttavia, nel caso della mia applicazione web, funziona solo la soluzione sopra.

<table style="background-color: blue; width: 100%;" cellpadding="0" cellspacing="0">
<tr>
    <td style="background-color: red;   padding: 3px;">
        <div style="margin-right: 6px;">
                <input type="text" style="width:100%;">
        </div>
    </td>
    <td style="background-color: purple;   padding: 3px;">
        <div style="margin-right: 6px;">
                <input type="text" style="width:100%;">
        </div>
    </td>
    <td style="background-color: green;   padding: 3px;">
        <div style="margin-right: 6px;">
                <input type="text" style="width:100%;">
        </div>
    </td>
</tr>
</table>

Funziona (voto positivo +1). Stranamente, ho inserito del testo prima di ogni <input> e ho aggiunto "white-space: nowrap" per mantenerli sulla stessa riga, quindi i tre <input> hanno superato le celle della tabella, se rimuovo "white-space: nowrap" tutto funziona di nuovo. Strano.
Jose Manuel Abarca Rodríguez

8

Il problema è stato spiegato in precedenza, quindi lo ripeterò solo: la larghezza non tiene conto del bordo e del padding. Una possibile risposta a questo non discusso ma che ho trovato mi ha aiutato un sacco è racchiudere i tuoi input. Ecco il codice e ti spiegherò come questo aiuta in un secondo:

<table>
  <tr>
    <td><div style="overflow:hidden"><input style="width:100%" type="text" name="name" value="hello world" /></div></td>
  </tr>
</table>

Il DIV che avvolge l'INPUT non ha riempimento né un bordo. Questa è la soluzione. Un DIV si espanderà fino alle dimensioni del suo contenitore, ma rispetterà anche il bordo e il riempimento. Ora, l'INPUT non avrà problemi a espandersi alla dimensione del suo contenitore poiché è senza bordi e senza pad. Si noti inoltre che il DIV ha il suo overflow impostato su nascosto. Sembra che per impostazione predefinita gli elementi possano cadere al di fuori del loro contenitore con l'overflow predefinito di visibile. Ciò garantisce solo che l'input rimanga all'interno del suo contenitore e non tenti di penetrare.

L'ho testato in Chrome e in Fire Fox. Entrambi sembrano rispettare bene questa soluzione.

AGGIORNAMENTO : Dato che ho appena ricevuto un voto negativo casuale, vorrei dire che un modo migliore per gestire l'overflow è con l'attributo di dimensionamento del riquadro CSS3 come descritto da pricco:

.myinput {
    -moz-box-sizing: border-box;
    -webkit-box-sizing: border-box;
    -ms-box-sizing: border-box;
    -o-box-sizing: border-box;
    box-sizing: border-box;
}

Questo sembra essere abbastanza ben supportato dai principali browser e non è "hacky" come il trucco dell'overflow. Ci sono, tuttavia, alcuni problemi minori sui browser attuali con questo approccio (vedi http://caniuse.com/#search=box-sizing Known Issues).


3
Una breve nota: con overflow: hidden;il contenuto ancora "spunta" all'esterno della scatola esattamente nello stesso modo, ma viene troncato invece di essere mostrato, quindi non si sovrappone ad altri contenuti.
ANeves

2

So che questa domanda è vecchia di 3 anni ma il problema persiste per i browser attuali e le persone continuano a venire qui. La soluzione per ora è calc () :

input {
    width: calc(100% - 12px); /* IE 9,10 , Chrome, Firefox */
    width: -webkit-calc(100% - 12px); /*For safari 6.0*/
}

È supportato dalla maggior parte dei browser moderni.


1

Il problema è dovuto al modello box degli elementi di input. Di recente ho trovato una buona soluzione al problema cercando di mantenere il mio input al 100% per i dispositivi mobili.

Racchiudi il tuo input con un altro elemento, ad esempio un div. Quindi applica lo stile che desideri per il tuo input a quel div wrapper. Per esempio:

<div class="input-wrapper">
 <input type="text" />
</div>

.input-wrapper {
    border-raius:5px;
    padding:10px;
}
.input-wrapper input[type=text] {
    width:100%;
    font-size:16px;
}

Dai .input-wrapper padding angoli arrotondati ecc., Qualunque cosa tu voglia per il tuo input, quindi dai la larghezza di input al 100%. Hai il tuo input ben imbottito con un bordo ecc.Ma senza il fastidioso trabocco!


1

Ho risolto questo problema iniziando con la risposta di @ hallodom. Tutti i miei input erano contenuti all'interno di li, quindi tutto quello che dovevo fare era impostare l'overflow di li: nascosto per rimuovere quell'eccesso di input overflow.

.ie7 form li {
  width:100%;
  overflow:hidden;
}

.ie7 input {
  width:100%;
}

1

invece di questa lotta di margine fallo e basta

input{
    width:100%;
    background:transparent !important;
}

in questo modo il bordo della cella è visibile e puoi controllare il colore di sfondo della riga


0

Estrai "http://www.w3.org/TR/html4/loose.dtd" dalla dichiarazione DOCTYPE e risolverai il tuo problema.

Saluti! :)


Intendi usare http://www.w3.org/TR/html4/strict.dtdStrict? rif. w3.org/QA/2002/04/valid-dtd-list.html Comunque questa non è un'opzione perché cambiare il DOCTYPE ora probabilmente avrebbe un impatto sul rendering di molte altre cose nelle pagine web.
Marco Demaio

0

Con alcuni Javascript è possibile ottenere la larghezza esatta del TD che lo contiene e quindi assegnarlo direttamente all'elemento di input.

Il seguente è javascript grezzo ma jQuery lo renderebbe più pulito ...

var inputs = document.getElementsByTagName('input');
for (var i = 0; i < inputs.length; i++)
{
    var el = inputs[i];
    if (el.style.width == '100%')
    {
        var pEl = el.parentNode;  // Assumes the parent node is the TD...
        el.style.width = pEl.offsetWidth;
    }
}

I problemi con questa soluzione sono:

1) Se hai i tuoi input contenuti in un altro elemento come uno SPAN, allora avrai bisogno di loop up e trovare il TD perché elementi come SPANs avvolgeranno l'input e mostreranno la sua dimensione piuttosto che essere limitati alla dimensione del TD.

2) Se si aggiungono padding o margini a diversi livelli, potrebbe essere necessario sottrarli esplicitamente da [pEl.offsetWidth]. A seconda della struttura HTML che può essere calcolata.

3) Se le colonne della tabella vengono ridimensionate dinamicamente, la modifica della dimensione di un elemento provocherà il reflow della tabella in alcuni browser e potresti ottenere un effetto graduale mentre "aggiusti" sequenzialmente le dimensioni dell'input. La soluzione è assegnare larghezze specifiche alla colonna come percentuali o pixel OPPURE raccogliere le nuove larghezze e impostarle dopo. Vedi il codice qui sotto ..

var inputs = document.getElementsByTagName('input');
var newSizes = [];
for (var i = 0; i < inputs.length; i++)
{
    var el = inputs[i];
    if (el.style.width == '100%')
    {
        var pEl = el.parentNode;  // Assumes the parent node is the TD...
        newSizes.push( { el: el, width: pEl.offsetWidth });
    }
}

// Set the sizes AFTER to avoid stepping...
for (var i = 0; i < newSizes.length; i++)
{
    newSizes[i].el.style.width = newSizes[i].width;
}

0

Ho risolto il problema applicando box-sizing:border-box; alle celle della tabella stesse, oltre a fare lo stesso con l'input e il wrapper.


0

Ho risolto il problema usando questo

tr td input[type=text] {
  width: 100%;
  box-sizing: border-box;
  -webkit-box-sizing:border-box;
  -moz-box-sizing: border-box;
  background:transparent !important;
  border: 0px;
}

-1

Di solito imposto la larghezza dei miei input al 99% per risolvere questo problema:

input {
    width: 99%;
}

Puoi anche rimuovere gli stili predefiniti, ma ciò renderà meno ovvio che si tratta di una casella di testo. Tuttavia, mostrerò comunque il codice per quello:

input {
    width: 100%;
    border-width: 0;
    margin: 0;
    padding: 0;
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
}

Ad @ m


-2

Il problema sta nell'elemento border-widthdi input. In breve, prova a impostare l' margin-leftelemento di input su -2px.

table input {
  margin-left: -2px;
}

non credo proprio. che sposta appena la scatola a sinistra e distrugge il margine sinistro
cc giovane
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.