Dane wejściowe CSS o szerokości: 100% wykracza poza granice rodzica

172

Próbuję utworzyć formularz logowania składający się z dwóch pól wejściowych ze wstawionym wypełnieniem, ale te dwa pola zawsze przekraczają granice swojego rodzica; problem wynika z dodanej wyściółki wstawki . Co można zrobić, aby rozwiązać ten problem?

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

Uwaga: kod może nie być najczystszy. Na przykład element span, który hermetyzuje dane wejściowe, może w ogóle nie być potrzebny.

    #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
źródło

Odpowiedzi:

310

Użyj definicji CSS, box-sizing:border-boxaby dopełnienie nie wpłynęło na szerokość lub wysokość elementu. Zobacz box-sizing.

border-box : Właściwości width i height obejmują dopełnienie i border, ale nie margines ... Zwróć uwagę, że dopełnienie i border będą znajdować się wewnątrz ramki.

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

Zwróć uwagę na zgodność przeglądarkibox-sizing (IE8 +).
W chwili tej edycji żadne przedrostki nie są konieczne; zobacz shouldiprefix.com .

Oto demonstracja:

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


Alternatywnie, zamiast dodawać dopełnienie do <input>samych elementów, nadaj styl <span>elementom zawijającym dane wejściowe. W ten sposób <input>elementy można ustawić width:100%bez dodatkowego wypełnienia. Przykład poniżej:

showdev
źródło
1
Wydaje się, że to działa. Wielkie dzięki, zaoszczędziłeś mi sporo czasu.
peelz
2
Aby rozwinąć twoją pierwszą część:box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;
Bradmage,
sprawiasz, że mój dzień kolego ... mały css, ale bardzo ważny :)
Gourav Makhija
18

Jeśli wszystkie powyższe zawiodą, spróbuj ustawić następujące właściwości danych wejściowych, aby zajmowały maksymalną przestrzeń, ale nie przepełniły:

input {
    min-width: 100%;
    max-width: 100%;
}
Deiu
źródło
1
to właśnie zadziałało dla mnie bardzo proste rozwiązanie dzięki
AlexGH
13

Inne odpowiedzi wydają się sugerować sztywne zakodowanie szerokości lub użycie hackowania specyficznego dla przeglądarki. Myślę, że jest prostszy sposób.

Obliczając szerokość i odejmując wypełnienie (które powoduje nakładanie się pól). Wartość 20 pikseli pochodzi z 10 pikseli dla wypełnienia z lewej strony i 10 pikseli dla wypełnienia z prawej strony.

input[type=text],
input[type=password] {
    ...
    width: calc(100% - 20px);
}
Al Zziwa
źródło
3
nie mogę uwierzyć, że nigdy wcześniej tego nie widziałem. Idealnie pasował do mojego przypadku użycia, podczas gdy inne odpowiedzi nie. dzięki
obrabowany
Pracował dla mnie. min/max-width: 100%;nie, box-sizing: border-box;nie. Wyobrażam sobie, że umieszczenie całej mojej witryny w kontenerze i nadanie jej wypełnienia zadziała, ale nie chcę tego robić tylko dla tej prostej poprawki.
SUM 1
4

Spróbuj zmienić box-sizingTO border-box. paddingJest dodanie do widthswoich inputelementów.

Zobacz Demo tutaj

CSS

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

input {
    box-sizing: border-box;
}

+box-sizing

Sourabh
źródło
2

Dopełnienie jest dodawane do całkowitej szerokości. Ponieważ kontener ma szerokość w pikselach, lepiej jest podać wejściom szerokość w pikselach, ale pamiętaj, aby usunąć dopełnienie i obramowanie z ustawionej szerokości, aby uniknąć tego samego problemu.

ralph.m
źródło
1

Wypróbowałem te rozwiązania, ale nigdy nie uzyskałem rozstrzygającego wyniku. Na koniec użyłem odpowiedniego znacznika semantycznego z zestawem pól. Oszczędzało to konieczności dodawania wszelkich obliczeń szerokości i rozmiaru pudełka.

Pozwala również na ustawienie wymaganej szerokości formy, a dane wejściowe pozostają w wypełnieniu potrzebnym do krawędzi.

W tym przykładzie umieściłem obramowanie na formularzu i zestawie pól oraz nieprzezroczyste tło na legendzie i zestawie pól, abyś mógł zobaczyć, jak nakładają się i siedzą ze sobą.

<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
źródło
0

Dopełnienie jest zasadniczo dodawane do szerokości, więc kiedy mówisz width:100%i padding: 5px 10pxfaktycznie dodajesz 20 pikseli do 100% szerokości.

n00dle
źródło
1
Jak mogłem zaradzić temu problemowi? Od kilku godzin próbuję wielu rzeczy: /
peelz
Usuń szerokość 100%, nie jest to konieczne, ponieważ dane wejściowe są elementami inline-block.
Andy G
0

Masz również błąd w swoim css z wykrzyknikiem w tym wierszu:

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

usuń znajdujący się przed nim średnik. Jednak! Ważne powinno być używane rzadko i można go w dużym stopniu uniknąć.

Andy G.
źródło
Ach dzięki, musiałem to przeoczyć, a ponadto! Ważny tag nie był nawet wymagany.
peelz
-1

Czy chcesz, aby pola wejściowe były wyśrodkowane? Sztuczka do wyśrodkowania elementów: określ szerokość elementu i ustaw margines na auto, np .:

margin : 0px auto;
width:300px

Link do zaktualizowanych skrzypiec:

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

monika
źródło
Niezupełnie, próbuję zmusić je do automatycznego rozmiaru do szerokości „.loginForm”. Np .: jsfiddle.net/4x2KP/7
peelz
Możesz zmienić szerokość pliku .loginForm, a dane wejściowe powinny pozostać wyśrodkowane
monika
Tak, to działa, ale nie bez powodu dodałem wypełnienie "wstawką": nie chcę, aby tekst zaczynał się "od razu od początku". Zobacz to zdjęcie: d.pr/i/xSH1 (Porównaj wprowadzony adres e-mail z hasłem)
peelz