250 votes

L'entrée CSS avec width : 100% sort du cadre du parent

J'essaie de créer un formulaire de connexion avec deux champs d'entrée avec un rembourrage inséré, mais ils finissent par dépasser les limites du parent. Quelle est la cause de ce problème ?

Un extrait de JSFiddle : http://jsfiddle.net/4x2KP/

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

420voto

showdev Points 7532

Selon le Modèle de boîte de base CSS La largeur et la hauteur d'un élément sont appliquées à sa zone de contenu. Le remplissage se situe en dehors de cette zone de contenu et augmente la taille globale de l'élément.

Par conséquent, si vous définissez un élément avec un remplissage à une largeur de 100 %, son remplissage le rendra plus large que 100 % de l'élément qui le contient. Dans votre contexte, les entrées deviennent plus larges que leur parent.

CSS Basic Box Model

Vous pouvez modifier la façon dont le modèle de boîte traite le rembourrage et la largeur. Définissez les box-sizing Propriété CSS a border-box pour empêcher le remplissage d'affecter la largeur ou la hauteur d'un élément :

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

Notez le compatibilité des navigateurs box-sizing (IE8+).
Au moment de cette édition, aucun préfixe n'est nécessaire .


Paul Irish y Chris Coyier recommande l'usage "hérité" ci-dessous :

html {
  box-sizing: border-box;
}
*, *:before, *:after {
  box-sizing: inherit;
}

Pour référence, voir :
* { Box-sizing : Border-box } FTW
Hériter de la taille des boîtes est probablement une meilleure pratique. .


Voici une démonstration dans votre contexte spécifique :

#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 du remplissage à l'élément <input> eux-mêmes, donnez un style aux éléments <span> enveloppant les entrées. De cette façon, les <input> peuvent être définis comme width:100% sans être affecté par un quelconque rembourrage supplémentaire. Exemple ci-dessous :

#login-form {
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  background-color: rgba(0, 50, 94, 0.2);
  margin: 20px auto;
  padding: 10px 15px 25px 15px;
  border: 4px solid rgb(40, 40, 40);
  box-shadow: 0 5px 10px 5px rgba(0, 0, 0, 0.2);
  border-radius: 2px;
  width: 320px;
}
label span {
  display: block;
  padding: .3em 1em;
  background-color: rgb(215, 215, 215);
  border-radius: .25em;
  border: 1px solid rgb(114, 114, 114);
  box-shadow: 0 1px 0 rgba(24, 24, 24, 0.1);
  margin: 0 0 1em;
}
label span:hover {
  background: rgb(242, 242, 242);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.3), inset 0 -10px 10px rgba(255, 255, 255, 0.1);
}
input[type=text],
input[type=password] {
  background: none;
  border: none;
  width: 100%;
  height: 2em;
  line-height: 2em;
  font-size: 12px;
  color: rgb(136, 136, 136);
  outline: none;
}
.login-bottom {
  margin: 2em 1em 0 0;
}
input#login-button {
  float: right;
  padding: 2px 25px;
}
input#login-remember {
  float: left;
  margin-right: 3px;
}

<form id="login-form">
  <label>E-mail address
    <span><input name="email" type="text" /></span>
  </label>
  <label>Password
    <span><input name="password" type="password" /></span>
  </label>
  <div class="login-bottom">
    <label>
      <input type="checkbox" name="remember" id="login-remember" />Remember my email
    </label>
    <input type="submit" name="login-button" id="login-button" value="Log in" />
  </div>
</form>

27voto

Al Zziwa Points 1

Les autres réponses semblent vous dire 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 padding (qui provoque le chevauchement des champs). Les 20px proviennent de 10px pour le padding gauche et 10px pour le padding droit.

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

4 votes

Je ne peux pas croire que je n'ai jamais vu ça avant. Elle correspondait parfaitement à mon cas d'utilisation alors que les autres réponses ne le faisaient pas. Merci.

0 votes

Ça a marché pour moi. min/max-width: 100%; ne l'a pas fait, box-sizing: border-box; ne l'a pas fait. J'imagine que mettre l'ensemble de mon site dans un conteneur et lui donner du rembourrage pourrait fonctionner, mais je ne veux pas avoir à le faire juste pour ce simple correctif.

0 votes

Je ne considère pas box-sizing pour être un "hack spécifique au navigateur". Si cela n'a pas fonctionné, vous êtes probablement confronté à des circonstances différentes de celles de l'OP. Il serait intéressant de faire la différence et de comprendre pourquoi ce qui fonctionne fonctionne.

26voto

Deiu Points 437

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

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

1 votes

C'est ce qui a fonctionné pour moi solution très simple merci

0 votes

Cela a également fonctionné pour moi alors que la solution ci-dessus avec le cadre de bordure n'a pas fonctionné - merci !

10voto

Sourabh Points 1920

Essayez de changer le box-sizing a border-box . Le site padding s'ajoute à width de votre input é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

3voto

ralph.m Points 7815

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X