Input CSS con larghezza: 100% va oltre il limite del genitore


172

Sto cercando di creare un modulo di accesso costituito da due campi di input con un riempimento interno, ma quei due campi finiscono sempre per superare i confini dei suoi genitori; il problema deriva dall'imbottitura dell'inserzione aggiunta . Cosa si potrebbe fare per risolvere questo problema?

JSFiddle snippet: http://jsfiddle.net/4x2KP/

NB: il codice potrebbe non essere più pulito. Ad esempio, potrebbe non essere necessario l'elemento span che incapsula gli input di testo.

    #mainContainer {
    	line-height: 20px;
    	font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
        background-color: rgba(0,50,94,0.2);
    	margin: 20px auto;
    	display: table;
    	-moz-border-radius: 15px;
    	border-style: solid;
    	border-color: rgb(40, 40, 40);
    	border-radius: 2px 5px 2px 5px / 5px 2px 5px 2px;
    	border-radius: 2px;
    	border-radius: 2px 5px / 5px;
    	box-shadow: 0 5px 10px 5px rgba(0,0,0,0.2);
    }
    
    .loginForm {
    	width: 320px;
    	height: 250px;
    	padding: 10px 15px 25px 15px;
    	overflow: hidden;
    }
    
    .login-fields > .login-bottom input#login-button_normal {
    	float: right;
    	padding: 2px 25px;
    	cursor: pointer;
    	margin-left: 10px;
    }
    
    .login-fields > .login-bottom input#login-remember {
    	float: left;
    	margin-right: 3px;
    }
    
    .spacer {
    	padding-bottom: 10px;
    }
    
    /* ELEMENT OF INTEREST HERE! */
    input[type=text],
    input[type=password] {
        width: 100%;
    	height: 20px;
    	padding: 5px 10px;
    	background-color: rgb(215, 215, 215);
        line-height: 20px;
        font-size: 12px;
        color: rgb(136, 136, 136);
        border-radius: 2px 2px 2px 2px;
        border: 1px solid rgb(114, 114, 114);
    	box-shadow: 0 1px 0 rgba(24, 24, 24,0.1);
    }
    
    input[type=text]:hover,
    input[type=password]:hover,
    label:hover ~ input[type=text],
    label:hover ~ input[type=password] {
     	background:rgb(242, 242, 242) !important;
    }
    
    input[type=submit]:hover {
      box-shadow:
        inset 0 1px 0 rgba(255,255,255,0.3),
        inset 0 -10px 10px rgba(255,255,255,0.1);
    }
    <div id="mainContainer">
        <div id="login" class="loginForm">
            <div class="login-top">
            </div>
            <form class="login-fields" onsubmit="alert('test'); return false;">
                <div id="login-email" class="login-field">
                    <label for="email" style="-moz-user-select: none;-webkit-user-select: none;" onselectstart="return false;">E-mail address</label>
                    <span><input name="email" id="email" type="text"></input></span>
                </div>
                <div class="spacer"></div>
                <div id="login-password" class="login-field">
                    <label for="password" style="-moz-user-select: none;-webkit-user-select: none;" onselectstart="return false;">Password</label>
                    <span><input name="password" id="password" type="password"></input></span>
                </div>
                <div class="login-bottom">
                    <input type="checkbox" name="remember" id="login-remember"></input>
                    <label for="login-remember" style="-moz-user-select: none;-webkit-user-select: none;" onselectstart="return false;">Remember my email</label>
                    <input type="submit" name="login-button" id="login-button_normal" style="cursor: pointer" value="Log in"></input>
                </div>
            </form>
        </div>
    </div>

Risposte:


310

Utilizzare la definizione CSS box-sizing:border-boxper evitare che il riempimento influisca sulla larghezza o altezza di un elemento. Vedere box-sizing.

border-box : le proprietà di larghezza e altezza includono il riempimento e il bordo, ma non il margine ... Nota che il riempimento e il bordo saranno all'interno del riquadro.

input[type=text],
input[type=password] {
    box-sizing : border-box;
}

Nota la compatibilità del browser dibox-sizing (IE8 +).
Al momento di questa modifica, non sono necessari prefissi; vedi shouldiprefix.com .

Ecco una dimostrazione:

#mainContainer {
  line-height: 20px;
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  background-color: rgba(0, 50, 94, 0.2);
  margin: 20px auto;
  display: table;
  -moz-border-radius: 15px;
  border-style: solid;
  border-color: rgb(40, 40, 40);
  border-radius: 2px 5px 2px 5px / 5px 2px 5px 2px;
  border-radius: 2px;
  border-radius: 2px 5px / 5px;
  box-shadow: 0 5px 10px 5px rgba(0, 0, 0, 0.2);
}
.loginForm {
  width: 320px;
  height: 250px;
  padding: 10px 15px 25px 15px;
  overflow: hidden;
}
.login-fields > .login-bottom input#login-button_normal {
  float: right;
  padding: 2px 25px;
  cursor: pointer;
  margin-left: 10px;
}
.login-fields > .login-bottom input#login-remember {
  float: left;
  margin-right: 3px;
}
.spacer {
  padding-bottom: 10px;
}
input[type=text],
input[type=password] {
  width: 100%;
  height: 30px;
  padding: 5px 10px;
  background-color: rgb(215, 215, 215);
  line-height: 20px;
  font-size: 12px;
  color: rgb(136, 136, 136);
  border-radius: 2px 2px 2px 2px;
  border: 1px solid rgb(114, 114, 114);
  box-shadow: 0 1px 0 rgba(24, 24, 24, 0.1);
  box-sizing: border-box;
}
input[type=text]:hover,
input[type=password]:hover,
label:hover ~ input[type=text],
label:hover ~ input[type=password] {
  background: rgb(242, 242, 242);
  !important;
}
input[type=submit]:hover {
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.3), inset 0 -10px 10px rgba(255, 255, 255, 0.1);
}
.login-top {
  height: auto;/*85px;*/
}
.login-bottom {
  padding: 35px 15px 0 0;
}
<div id="mainContainer">
  <div id="login" class="loginForm">
    <div class="login-top">
    </div>
    <form class="login-fields" onsubmit="alert('test'); return false;">
      <div id="login-email" class="login-field">
        <label for="email" style="-moz-user-select: none;-webkit-user-select: none;" onselectstart="return false;">E-mail address</label>
        <span><input name="email" id="email" type="text" /></span>
      </div>
      <div class="spacer"></div>
      <div id="login-password" class="login-field">
        <label for="password" style="-moz-user-select: none;-webkit-user-select: none;" onselectstart="return false;">Password</label>
        <span><input name="password" id="password" type="password" /></span>
      </div>
      <div class="login-bottom">
        <input type="checkbox" name="remember" id="login-remember" />
        <label for="login-remember" style="-moz-user-select: none;-webkit-user-select: none;" onselectstart="return false;">Remember my email</label>
        <input type="submit" name="login-button" id="login-button_normal" style="cursor: pointer" value="Log in" />
      </div>
    </form>
  </div>
</div>


In alternativa, anziché aggiungere il riempimento agli <input>elementi stessi, modellare gli <span>elementi che avvolgono gli input. In questo modo, gli <input>elementi possono essere impostati width:100%senza essere influenzati da alcuna imbottitura aggiuntiva. Esempio sotto:


1
Questo sembra fare il lavoro. Grazie mille, mi hai fatto risparmiare un sacco di tempo.
peelz,

2
Per espandere la tua prima parte:box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;
Bradmage

mi rendi amico mio giorno ... piccolo css ma molto importante :)
Gourav Makhija

18

Se tutto quanto sopra fallisce, prova a impostare le seguenti proprietà per l'input, in modo che occupi spazio massimo ma non overflow:

input {
    min-width: 100%;
    max-width: 100%;
}

1
questo è ciò che ha funzionato per me una soluzione molto semplice grazie
AlexGH,

13

Le altre risposte sembrano dirti di codificare la larghezza o utilizzare un hack specifico del browser. Penso che ci sia un modo più semplice.

Calcolando la larghezza e sottraendo l'imbottitura (che causa la sovrapposizione del campo). Il 20px proviene da 10px per imbottitura sinistra e 10px per imbottitura destra.

input[type=text],
input[type=password] {
    ...
    width: calc(100% - 20px);
}

3
non posso credere di non averlo mai visto prima. Montato perfettamente il mio caso d'uso mentre le altre risposte no. grazie
rob

Ha funzionato per me. min/max-width: 100%;no, box-sizing: border-box;no. Immagino che mettere tutto il mio sito in un contenitore e dargli imbottitura funzionerebbe, ma non voglio farlo solo per questa semplice soluzione.
SUM1

4

Prova a cambiare box-sizingin border-box. Il paddingsta aggiungendo a widthdei tuoi inputelementi.

Vedi Demo qui

CSS

input[type=text],
input[type=password] {
    width: 100%;
    margin-top: 5px;
    height: 25px;
    ...
}

input {
    box-sizing: border-box;
}

+box-sizing


2

L'imbottitura viene aggiunta alla larghezza complessiva. Poiché il contenitore ha una larghezza in pixel, è meglio fornire anche agli input una larghezza in pixel, ma ricordarsi di rimuovere l'imbottitura e il bordo dalla larghezza impostata per evitare lo stesso problema.


1

Ho provato queste soluzioni ma non ho mai ottenuto un risultato conclusivo. Alla fine ho usato il markup semantico corretto con un fieldset. Ha risparmiato la necessità di aggiungere calcoli di larghezza e ridimensionamento delle scatole.

Inoltre, consente di impostare la larghezza del modulo desiderata e gli input rimangono all'interno dell'imbottitura necessaria per i bordi.

In questo esempio ho inserito un bordo nella forma e nel set di campi e uno sfondo opaco nella legenda e nel set di campi in modo da poter vedere come si sovrappongono e siedono l'uno con l'altro.

<html>
  <head>
  <style>
    form {
      width: 300px;
      margin: 0 auto;
      border: 1px solid;
    }
    fieldset {
      border: 0;
      margin: 0;
      padding: 0 20px 10px;
      border: 1px solid blue;
      background: rgba(0,0,0,.2);
    }
    legend {
      background: rgba(0,0,0,.2);
      width: 100%;
      margin: 0 -20px;
      padding: 2px 20px;
      color: $col1;
      border: 0;
    }
    input[type="email"],
    input[type="password"],
    button {
      width: 100%;
      margin: 0 0 10px;
      padding: 0 10px;
    }
    input[type="email"],
    input[type="password"] {
      line-height: 22px;
      font-size: 16px;
    }
    button {
    line-height: 26px;
    font-size: 20px;
    }
  </style>
  </head>
  <body>
  <form>
      <fieldset>
          <legend>Log in</legend>
          <p>You may need some content here, a message?</p>
          <input type="email" id="email" name="email" placeholder="Email" value=""/>
          <input type="password" id="password" name="password" placeholder="password" value=""/>
          <button type="submit">Login</button>
      </fieldset>
  </form>
  </body>
</html>

0

L'imbottitura viene essenzialmente aggiunta alla larghezza, quindi quando dici width:100%e padding: 5px 10pxstai effettivamente aggiungendo 20px alla larghezza del 100%.


1
E come potrei porre rimedio a questo problema? Ho provato molte cose per ore: /
peelz

Rimuovere la larghezza del 100%, non è necessario poiché gli ingressi sono elementi a blocchi in linea.
Andy G,

0

Hai anche un errore nel tuo css con il punto esclamativo in questa riga:

background:rgb(242, 242, 242);!important;

rimuovere il punto e virgola prima di esso. Tuttavia,! Important dovrebbe essere usato raramente e può essere ampiamente evitato.


Ah grazie, devo averlo perso, inoltre, il! Tag importante non era nemmeno richiesto.
peelz,

-1

Vuoi che i campi di input siano centrati? Un trucco per centrare gli elementi: specificare la larghezza dell'elemento e impostare il margine su auto, ad esempio:

margin : 0px auto;
width:300px

Un link al violino aggiornato:

http://jsfiddle.net/4x2KP/5/


Non proprio, sto cercando di farli dimensionare automaticamente alla larghezza di ".loginForm". Ad esempio: jsfiddle.net/4x2KP/7
peelz,

Puoi modificare la larghezza di .loginForm e gli input dovrebbero rimanere centrati
monika,

Sì, questo funziona, ma ho aggiunto il riempimento "inset" per un motivo: non voglio che il testo inizi "immediatamente dall'inizio". Vedi questa immagine: d.pr/i/xSH1 (confronta l'input dell'email con quello della password)
peelz
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.