2010-03-03 7 views
92

Qualcuno sa perché gli elementi di input con una larghezza del 100% vanno oltre il bordo delle celle della tabella.Casella di testo di input HTML con una larghezza del 100% che supera le celle della tabella

Nell'esempio seguente, la casella di input va oltre il bordo delle celle della tabella, il risultato è orribile. Questo è stato testato e succede allo stesso modo su: Firefox, IE7 e Safari.

Ha senso per te? Mi manca qualcosa, sai 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

I suggerirebbe che, se si sta solo usando una tabella per presentare gli input, si potrebbe passare ad usare un 'form' con' label' s e 'input' s all'interno di' ul' o 'ol'. che è, almeno leggermente più semantico. Certamente, però, dovresti usare un 'form', anche se ti limiti a' table'. –

risposta

191

è possibile utilizzare la proprietà CSS3 box-sizing per includere l'imbottitura esterna e di frontiera:

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 tratta correttamente il dimensionamento della scatola. Prova quanto segue in IE 7 ... http: //www.css3.informazioni/anteprima/box-dimensionamento/o vedere http://css-tricks.com/box-sizing/ – AnthonyVO

+2

avuto lo stesso problema e abbiamo trovato questo gioiello – Steoates

+0

@AnthonyVO: vero, l'unica soluzione per IE7 è quello di aggiungere specifica CSS per usando i commenti condizionali di IE '' e 'input [type =" text "] {width: 95%}' –

23

valore Larghezza non tiene conto di bordo o padding:

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

Si ottiene 2px di imbottitura in ogni lato, più 1px di confine, in ogni lato.
100% + 2 * (2px + 1px) = 100% + 6px, che è superiore al contenuto figlio 100% del padre td.

si ha la possibilità di:

  • entrambe le impostazioni box-sizing: border-box; secondo @pricco's answer;
  • Oppure utilizzare 0 margine e riempimento (evitando la dimensione extra).
+0

in seguito alla risposta di Sr. è possibile impostare padding e border su 0px, quindi il 100% dovrebbe funzionare. – Mauro

+0

Infatti, anche senza impostare alcuna padding per td - molto ben aggiunto. – ANeves

+1

Inoltre, se il padding crea un problema, è possibile usare 'text-indent' per simulare il padding prima del leading-edge del testo, e' line-height' per il padding verticale (sebbene il mantenimento del padding verticale non influenzi comunque la larghezza). –

-2

Il problema si trova in border-width dell'elemento di input. In breve, provare a impostare margin-left dell'elemento di input su -2px.

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

non la penso così. quello sposta semplicemente la scatola a sinistra e distrugge il margine sinistro –

-4

Ho avuto esattamente lo stesso problema e risolto in questo modo:

input[type="text"] {width: 95%;} 
+0

per i miei soldi, questo più centrando l'input nel campo è il modo migliore per andare –

7

Il problema è stato spiegato in precedenza così sarò solo ribadire: larghezza non tiene conto border e padding. Una possibile risposta a questo non discusso, ma che ho trovato mi ha aiutato un mucchio di avvolgere i tuoi input. Ecco il codice, e 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 avvolgendo l'ingresso ha alcuna imbottitura né ha un bordo. Questa è la soluzione. Un DIV si espanderà alle dimensioni del suo contenitore, ma rispetterà anche il bordo e il riempimento. Ora, l'INPUT non avrà problemi di espansione delle dimensioni del suo contenitore poiché è senza margini e senza pad. Si noti inoltre che il DIV ha il suo overflow impostato su nascosto. Sembra che, per impostazione predefinita, gli oggetti possano cadere all'esterno del loro contenitore con l'overflow predefinito di visible. Questo assicura che l'input rimanga all'interno del suo contenitore e non tenti di penetrare.

Ho provato questo in Chrome e in Fire Fox. Entrambi sembrano rispettare bene questa soluzione.

UPDATE: Dal momento che ho appena ricevuto una downvote a caso, vorrei dire che un modo migliore per trattare con trabocco è con l'attributo CSS3 box-sizing 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.Vi sono, tuttavia, alcuni problemi minori sui browser correnti con questo approccio (vedi Problemi noti http://caniuse.com/#search=box-sizing).

+2

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

-1

Io di solito impostare la larghezza dei miei ingressi al 99% per risolvere questo problema:

input { 
    width: 99%; 
} 

È possibile anche rimuovere gli stili di default, ma che renderà meno evidente che si tratta di una casella di testo. Tuttavia, vi mostrerò il codice per che in ogni caso:

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

annuncio @ m

13

Il problema con le cose come width:95%; è che essi non guardare a destra in ampi layout flessibili (a causa del 5% può quindi essere come 30 pixel).

Le seguenti soluzioni funziona molto bene per me (testato 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 l'imbottitura giusta)

Il trucco è di avvolgere l'input con due div, l'esterno ha un margine di 3px (che lo rende 3px più piccolo del td), l'interno ha una imbottitura 3px. Questo rende l'input 6px più piccolo del td, che è ciò che 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 di cui 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> 
0

estrarre il "http://www.w3.org/TR/html4/loose.dtd" dalla dichiarazione DOCTYPE e risolvere il problema.

Cheers! :)

+0

Intendi usare 'http: // www.w3.org/TR/html4/strict.dtd' Strict? rif. http://www.w3.org/QA/2002/04/valid-dtd-list.html Ad ogni modo questa non è un'opzione, perché modificare DOCTYPE ora potrebbe influire sul rendering di molti altri stuf nelle pagine web. –

1

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

Includi l'input con un altro elemento, ad esempio un div. Quindi applica lo stile che vuoi 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; 
} 

Dare .input-wrapper arrotondato angolo imbottitura ecc, tutto quello che volete per il vostro input, poi dare larghezza dell'ingresso 100%. Hai inserito il tuo input piacevolmente con un bordo, ecc, ma senza il fastidioso trabocco!

1

Ho risolto questo problema partendo @ di hallodom risposta. Tutti i miei input erano contenuti in li, quindi tutto ciò che dovevo fare era impostare l'overflow di li: nascosto per rimuoverlo dall'eccesso di input.

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

.ie7 input { 
    width:100%; 
} 
0

Con un po 'Javascript è possibile ottenere la larghezza esatta del TD che contiene e quindi assegnare che direttamente l'elemento di input.

Quello che segue è javascript jQuery grezzo ma renderebbe più pulita ...

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 si dispone di ingressi contenute in un altro elemento, ad esempio un SPAN allora avrai bisogno di andare in loop e trovare il TD perché elementi come gli SPAN avvolgeranno l'input e mostreranno le sue dimensioni piuttosto che essere limitate alle dimensioni del TD.

2) Se sono stati aggiunti padding o margini a livelli diversi, potrebbe essere necessario sottrarre esplicitamente quello 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 causerà il reflow della tabella in alcuni browser e si potrebbe ottenere un effetto a gradino mentre si "correggono" le dimensioni di input in modo sequenziale. La soluzione è di assegnare larghezze specifiche alla colonna come percentuali o pixel OPPURE raccogliere le nuove larghezze e impostarle dopo. Vedere il codice seguente ..

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; 
} 
2

so che questa domanda è di 3 anni, ma il problema persiste per i browser e gente attuali sono ancora 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.

0

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

1

invece di questa lotta margine basta fare

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

questo modo il bordo della cella è visibile e si può controllare il colore fila sfondo

0

ho risolto il problema utilizzando 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; 
}