Entrada CSS con ancho: 100% va fuera del límite del padre

172

Estoy tratando de hacer un formulario de inicio de sesión constituido por dos campos de entrada con un relleno de inserción, pero esos dos campos siempre terminan excediendo los límites de sus padres; el problema se deriva del agregado inserción de relleno. ¿Qué se podría hacer para corregir este problema?

Fragmento de JSFiddle: http://jsfiddle.net/4x2KP/

NB: el código puede no ser el más limpio. Por ejemplo, el elemento span que encapsula las entradas de texto puede no ser necesario en absoluto.

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

Respuestas:

310

Use la definición CSS box-sizing:border-boxpara evitar que el relleno afecte el ancho o alto de un elemento. Ver box-sizing.

border-box : las propiedades de ancho y alto incluyen el relleno y el borde, pero no el margen ... Tenga en cuenta que el relleno y el borde estarán dentro del cuadro.

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

Tenga en cuenta la compatibilidad del navegador debox-sizing (IE8 +).
En el momento de esta edición, no se necesitan prefijos; ver shouldiprefix.com .

Aquí hay una demostración:

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


Alternativamente, en lugar de agregar relleno a los <input>elementos, diseñe los <span>elementos que envuelven las entradas. De esa manera, los <input>elementos se pueden configurar width:100%sin verse afectados por ningún relleno adicional. Ejemplo a continuación:

showdev
fuente
1
Esto parece hacer el trabajo. Muchas gracias, me has ahorrado mucho tiempo.
peelz
2
Para ampliar en su primera parte:box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;
Bradmage
me haces el día amigo ... pequeño css pero muy importante :)
Gourav Makhija
18

Si todo lo anterior falla, intente configurar las siguientes propiedades para su entrada, para que ocupe espacio máximo pero no se desborde:

input {
    min-width: 100%;
    max-width: 100%;
}
Deiu
fuente
1
esto es lo que funcionó para mí solución muy simple gracias
AlexGH
13

Las otras respuestas parecen decirle que codifique el ancho o use un truco específico del navegador. Creo que hay una manera más simple.

Calculando el ancho y restando el relleno (lo que provoca la superposición del campo). El 20px viene de 10px para el relleno izquierdo y 10px para el relleno derecho.

input[type=text],
input[type=password] {
    ...
    width: calc(100% - 20px);
}
Al Zziwa
fuente
3
No puedo creer que nunca haya visto eso antes. Se ajustó perfectamente a mi caso de uso mientras que las otras respuestas no. gracias
robar
Trabajó para mi. min/max-width: 100%;no lo hizo, box-sizing: border-box;no lo hizo. Me imagino que poner todo mi sitio en un contenedor y darle relleno funcionaría, pero no quiero tener que hacer eso solo por esta simple solución.
SUM1
4

Intenta cambiar el box-sizinga border-box. La paddingestá agregando a widthsus inputelementos.

Ver demostración aquí

CSS

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

input {
    box-sizing: border-box;
}

+box-sizing

Sourabh
fuente
2

El relleno se agrega al ancho total. Debido a que su contenedor tiene un ancho de píxel, es mejor darle a las entradas un ancho de píxel también, pero recuerde quitar el relleno y el borde del ancho que configuró para evitar el mismo problema.

ralph.m
fuente
1

Probé estas soluciones pero nunca obtuve un resultado concluyente. Al final utilicé el marcado semántico adecuado con un conjunto de campos. Se ahorró tener que agregar cualquier cálculo de ancho y cualquier tamaño de caja.

También le permite establecer el ancho del formulario según lo requiera y las entradas permanecen dentro del relleno que necesita para sus bordes.

En este ejemplo, he puesto un borde en el formulario y el conjunto de campos y un fondo opaco en la leyenda y el conjunto de campos para que pueda ver cómo se superponen y se sientan entre sí.

<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
fuente
0

El relleno se agrega esencialmente al ancho, por lo tanto, cuando dices width:100%y en padding: 5px 10pxrealidad estás agregando 20 píxeles al 100% de ancho.

n00dle
fuente
1
¿Y cómo podría remediar este problema? He estado intentando muchas cosas durante horas: /
peelz
Elimine el ancho del 100%, no es necesario ya que las entradas son elementos de bloque en línea.
Andy G
0

También tiene un error en su CSS con el signo de exclamación en esta línea:

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

quite el punto y coma antes que él. Sin embargo,! Important debe usarse raramente y puede evitarse en gran medida.

Andy G
fuente
Ah, gracias, debo haberlo perdido, además, la etiqueta! Importante ni siquiera era necesaria.
peelz
-1

¿Desea que los campos de entrada estén centrados? Un truco para centrar elementos: especifique el ancho del elemento y configure el margen en automático, por ejemplo:

margin : 0px auto;
width:300px

Un enlace a su violín actualizado:

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

monika
fuente
En realidad no, estoy tratando de hacer que se ajusten automáticamente al ancho de ".loginForm". Por ejemplo: jsfiddle.net/4x2KP/7
peelz
Puede cambiar el ancho de .loginForm y las entradas deben permanecer centradas
monika
Sí, esto funciona, pero he agregado relleno "insertado" por una razón: no quiero que el texto comience "directamente desde el principio". Vea esta imagen: d.pr/i/xSH1 (compare la entrada de correo electrónico con la contraseña)
peelz