Entrada CSS com largura: 100% sai do limite dos pais

172

Estou tentando fazer um formulário de login constituído por dois campos de entrada com um preenchimento de inserção, mas esses dois campos sempre acabam excedendo os limites de seus pais; o problema decorre do preenchimento de inserção adicional . O que poderia ser feito para corrigir esse problema?

Snippet do JSFiddle: http://jsfiddle.net/4x2KP/

NB: O código pode não estar mais limpo. Por exemplo, o elemento span que encapsula as entradas de texto pode não ser necessário.

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

peelz
fonte

Respostas:

310

Use a definição CSS box-sizing:border-boxpara impedir que o preenchimento afete a largura ou a altura de um elemento. Veja box-sizing.

caixa de borda : as propriedades de largura e altura incluem o preenchimento e a borda, mas não a margem ... Observe que o preenchimento e a borda estarão dentro da caixa.

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

Observe a compatibilidade do navegadorbox-sizing (IE8 +).
No momento desta edição, nenhum prefixo é necessário; consulte shouldiprefix.com .

Aqui está uma demonstração:

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


Como alternativa, em vez de adicionar preenchimento aos <input>próprios elementos, estilize os <span>elementos que envolvem as entradas. Dessa forma, os <input>elementos podem ser definidos como width:100%sem serem afetados por nenhum preenchimento adicional. Exemplo abaixo:

showdev
fonte
1
Isso parece fazer o trabalho. Muito obrigado, você me salvou bastante tempo.
Peelz
2
Para expandir sua primeira parte:box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;
Bradmage
você faz meu dia amigo ... pequena css, mas muito importante :)
Gourav Makhija
18

Se tudo acima falhar, tente definir as seguintes propriedades para sua entrada, para que ocupe espaço máximo, mas não exceda:

input {
    min-width: 100%;
    max-width: 100%;
}
Deiu
fonte
1
isto é o que funcionou para mim muito simples solução graças
AlexGH
13

As outras respostas parecem dizer para você codificar a largura ou usar um hack específico do navegador. Eu acho que existe uma maneira mais simples.

Calculando a largura e subtraindo o preenchimento (que causa a sobreposição do campo). Os 20 px vêm de 10 px no preenchimento esquerdo e 10 px no preenchimento direito.

input[type=text],
input[type=password] {
    ...
    width: calc(100% - 20px);
}
Al Zziwa
fonte
3
Não posso acreditar que nunca vi isso antes. Ajustou perfeitamente meu caso de uso, enquanto as outras respostas não. graças
Rob
Trabalhou para mim. min/max-width: 100%;não, box-sizing: border-box;não. Eu imagino colocar meu site inteiro em um contêiner e dar preenchimento funcionaria, mas não quero fazer isso apenas para essa correção simples.
SUM1
4

Tente mudar box-sizingpara border-box. O paddingestá adicionando aos widthseus inputelementos.

Veja a demonstração aqui

CSS

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

input {
    box-sizing: border-box;
}

+box-sizing

Sourabh
fonte
2

O preenchimento é adicionado à largura total. Como o contêiner possui uma largura de pixel, é melhor fornecer também uma largura de pixel às entradas, mas lembre-se de remover o preenchimento e a borda da largura definida para evitar o mesmo problema.

ralph.m
fonte
1

Tentei essas soluções, mas nunca obtive um resultado conclusivo. No final, usei a marcação semântica adequada com um conjunto de campos. Ele economizou a necessidade de adicionar cálculos de largura e qualquer tamanho de caixa.

Também permite definir a largura do formulário conforme necessário e as entradas permanecem dentro do preenchimento necessário para as bordas.

Neste exemplo, coloquei uma borda no formulário e no conjunto de campos e um fundo opaco na legenda e no conjunto de campos para que você possa ver como eles se sobrepõem e se assentam.

<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>
Jason Merry
fonte
0

O preenchimento é essencialmente adicionado à largura; portanto, quando você diz width:100%e padding: 5px 10pxna verdade está adicionando 20px à largura de 100%.

n00dle
fonte
1
E como eu poderia remediar esse problema? Eu tenho tentado muitas coisas por horas: /
peelz
Remova a largura de 100%, não é necessário, pois as entradas são elementos de bloco embutido.
Andy G
0

Você também tem um erro no seu css com o ponto de exclamação nesta linha:

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

remova o ponto e vírgula antes dele. No entanto, o importante deve ser usado raramente e pode ser amplamente evitado.

Andy G
fonte
Ah, obrigado, eu devo ter perdido, além disso, a etiqueta! Important nem era necessária.
precisa saber é
-1

Deseja que os campos de entrada sejam centralizados? Um truque para centralizar elementos: especifique a largura do elemento e defina a margem como automática, por exemplo:

margin : 0px auto;
width:300px

Um link para o seu violino atualizado:

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

monika
fonte
Na verdade, não, estou tentando fazer com que eles dimensionem automaticamente para a largura do ".loginForm". Por exemplo: jsfiddle.net/4x2KP/7
peelz
Você pode alterar a largura da .loginForm e as entradas devem permanecer centrado
Monika
Sim, isso funciona, mas adicionei preenchimento "inserido" por um motivo: não quero que o texto comece "imediatamente desde o início". Veja esta foto: d.pr/i/xSH1 (Compare a entrada de e-mail com a senha)
peelz