Entrée CSS avec largeur: 100% sort de la limite du parent

172

J'essaie de créer un formulaire de connexion constitué de deux champs d'entrée avec un remplissage en incrustation, mais ces deux champs finissent toujours par dépasser les limites de son parent; le problème provient de l'ajout encart rembourrage. Que pourrait-on faire pour remédier à ce problème?

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

NB: Le code n'est peut-être pas à son niveau le plus propre. Par exemple, l'élément span qui encapsule les entrées de texte peut ne pas être du tout nécessaire.

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

Réponses:

310

Utilisez la définition CSS box-sizing:border-boxpour empêcher le remplissage d'affecter la largeur ou la hauteur d'un élément. Voir box-sizing.

border-box : Les propriétés width et height incluent le padding et la bordure, mais pas la marge ... Notez que le padding et la bordure seront à l'intérieur de la boîte.

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

Veuillez noter la compatibilité du navigateur debox-sizing (IE8 +).
Au moment de cette modification, aucun préfixe n'est nécessaire; voir shouldiprefix.com .

Voici une démonstration:

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


Sinon, plutôt que d'ajouter un remplissage aux <input>éléments eux-mêmes, stylisez les <span>éléments enveloppant les entrées. De cette façon, les <input>éléments peuvent être définis surwidth:100% sans être affectés par un remplissage supplémentaire. Exemple ci-dessous:

showdev
la source
1
Cela semble faire le travail. Merci beaucoup, vous m'avez fait gagner beaucoup de temps.
peelz
2
Pour développer votre première partie:box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;
Bradmage
tu fais mon copain de jour ... petit css mais très important :)
Gourav Makhija
18

Si tout ce qui précède échoue, essayez de définir les propriétés suivantes pour votre entrée, pour qu'elle prenne un maximum d'espace mais ne déborde pas:

input {
    min-width: 100%;
    max-width: 100%;
}
Deiu
la source
1
c'est ce qui a fonctionné pour moi solution très simple merci
AlexGH
13

Les autres réponses semblent vous indiquer de coder en dur la largeur ou d'utiliser un hack spécifique au navigateur. Je pense qu'il existe un moyen plus simple.

En calculant la largeur et en soustrayant le remplissage (ce qui provoque le chevauchement des champs). Le 20px vient de 10px pour le rembourrage gauche et 10px pour le rembourrage droit.

input[type=text],
input[type=password] {
    ...
    width: calc(100% - 20px);
}
Al Zziwa
la source
3
je ne peux pas croire que je n'ai jamais vu cela auparavant. Convient parfaitement à mon cas d'utilisation, contrairement aux autres réponses. merci
rob
A travaillé pour moi. min/max-width: 100%;n'a pas, box-sizing: border-box;n'a pas fait. J'imagine que mettre tout mon site dans un conteneur et lui donner un remplissage fonctionnerait, mais je ne veux pas avoir à le faire uniquement pour cette solution simple.
SUM1
4

Essayez de changer le box-sizingen border-box. L' paddingajout widthde votreinput éléments.

Voir la démo ici

CSS

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

input {
    box-sizing: border-box;
}

+box-sizing

Sourabh
la source
2

Un rembourrage est ajouté à la largeur totale. Étant donné que votre conteneur a une largeur de pixel, il est préférable de donner également aux entrées une largeur de pixel, mais n'oubliez pas de supprimer le remplissage et la bordure de la largeur que vous avez définie pour éviter le même problème.

ralph.m
la source
1

J'ai essayé ces solutions mais je n'ai jamais obtenu de résultat concluant. En fin de compte, j'ai utilisé un balisage sémantique approprié avec un fieldset. Cela évitait d'avoir à ajouter des calculs de largeur et tout dimensionnement de boîte.

Il vous permet également de définir la largeur du formulaire selon vos besoins et les entrées restent dans le remplissage dont vous avez besoin pour vos bords.

Dans cet exemple, j'ai placé une bordure sur le formulaire et le jeu de champs et un arrière-plan opaque sur la légende et le jeu de champs afin que vous puissiez voir comment ils se chevauchent et s'articulent les uns avec les autres.

<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
la source
0

Le remplissage est essentiellement ajouté à la largeur, donc lorsque vous dites width:100%et padding: 5px 10pxque vous ajoutez en fait 20 px à la largeur de 100%.

n00dle
la source
1
Et comment pourrais-je remédier à ce problème? J'ai essayé beaucoup de choses pendant des heures: /
peelz
Supprimez la largeur de 100%, ce n'est pas nécessaire car les entrées sont des éléments de bloc en ligne.
Andy G
0

Vous avez également une erreur dans votre css avec le point d'exclamation dans cette ligne:

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

retirez le point-virgule avant. Cependant,! Important doit être utilisé rarement et peut être largement évité.

Andy G
la source
Ah merci, je dois l'avoir manqué, de plus, la balise! Important n'était même pas nécessaire.
peelz
-1

Voulez-vous que les champs de saisie soient centrés? Une astuce pour centrer les éléments: spécifiez la largeur de l'élément et définissez la marge sur auto, par exemple:

margin : 0px auto;
width:300px

Un lien vers votre violon mis à jour:

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

monika
la source
Pas vraiment, j'essaye de les amener à la taille automatique à la largeur de ".loginForm". Par exemple: jsfiddle.net/4x2KP/7
peelz
Vous pouvez modifier la largeur de .loginForm et les entrées doivent rester centrées
monika
Oui, cela fonctionne, mais j'ai ajouté un remplissage "en incrustation" pour une raison: je ne veux pas que le texte commence "tout de suite depuis le début". Voir cette image: d.pr/i/xSH1 (Comparez l'entrée de l'e-mail avec celle du mot de passe)
peelz