Czy mogę powstrzymać pola tekstowe o 100% szerokości przed rozciąganiem się poza pojemniki?

181

Powiedzmy, że mam pole tekstowe, które chcę wypełnić całą linię. Dałbym mu taki styl:

input.wide {display:block; width: 100%}

Powoduje to problemy, ponieważ szerokość zależy od zawartości pola tekstowego. Pola tekstowe mają domyślnie margines, obramowanie i wypełnienie, co powoduje, że pole tekstowe o szerokości 100% jest większe niż jego pojemnik.

Na przykład tutaj po prawej:

wprowadź opis zdjęcia tutaj

Czy istnieje sposób, aby pole tekstowe wypełniało szerokość kontenera bez rozszerzania się poza niego?

Oto przykładowy kod HTML pokazujący, co mam na myśli:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title>Untitled Page</title>
    <style type="text/css">
        #outer{border: 1px solid #000; width: 320px; margin: 0px;padding:0px}
        #inner{margin: 20px; padding: 20px; background: #999;border: 1px solid #000;}
        input.wide {display:block; margin: 0px}
        input.normal {display:block; float: right}
    </style>
</head>
<body>
    <div id="outer">
        <div id="inner">
            <input type="text" class="wide" />
            <input type="text" class="normal" />
            <div style="clear:both;"></div>
        </div>
    </div>
</body>
</html>

Jeśli zostanie to uruchomione, możesz zobaczyć, patrząc na „normalne” pole tekstowe, że „szerokie” pole tekstowe wystaje poza pojemnik. „Normalne” pole tekstowe unosi się do faktycznej krawędzi kontenera. Próbuję sprawić, by „szerokie” pole tekstowe wypełniało swój kontener, nie wykraczając poza krawędź, tak jak „normalne” pole tekstowe.

Dan Herbert
źródło

Odpowiedzi:

87

Co możesz zrobić, to usunąć domyślne „dodatki” z input:

input.wide {display:block; width:100%;padding:0;border-width:0}

To zatrzyma inputwnętrze jego pojemnika. Teraz, jeśli chcesz, obramowania, zawiń inputw div, z obramowaniami ustawionymi na div(w ten sposób możesz usunąć również display:blockz input). Coś jak:

<div style="border:1px solid gray;">
 <input type="text" class="wide" />
</div>

Edycja: Inną opcją jest, aby zamiast usunąć styl z input, skompensować go w zawiniętym div:

input.wide {width:100%;}

<div style="padding-right:4px;padding-left:1px;margin-right:2px">
  <input type="text" class="wide" />
</div>

To da ci nieco inne wyniki w różnych przeglądarkach, ale nie będą one nakładać się na pojemnik. Wartości w div zależą od tego, jak duża jest granica inputi ile miejsca chcesz między nią inputa granicą.

Hilbrand Bouwkamp
źródło
3
To bardzo kreatywne rozwiązanie. Jedyny problem, jaki mam z tym, to to, że nie mogę zdefiniować konturu na polu tekstowym, gdy zostanie ono zogniskowane, chyba że użyję JavaScript do zmiany granicy otoki opakowania.
Dan Herbert
@ DanHerbert, masz rację, to poważna wada UX tej metody
Baumr
275

Czy istnieje sposób, aby pole tekstowe wypełniało szerokość kontenera bez rozszerzania się poza niego?

Tak: za pomocą właściwości CSS3 „rozmiar pudełka: ramka” można ponownie zdefiniować, co „szerokość” ma obejmować zewnętrzne wypełnienie i ramkę.

Niestety, ponieważ jest to CSS3, obsługa nie jest bardzo dojrzała, a ponieważ proces specyfikacji jeszcze się nie zakończył, w międzyczasie ma różne nazwy tymczasowe w przeglądarkach. Więc:

input.wide {
    width: 100%;
    box-sizing: border-box;
    -moz-box-sizing: border-box;
    -webkit-box-sizing: border-box;
}

Oldschoolową alternatywą jest po prostu umieszczenie pewnej ilości „padding-right” na otaczającym elemencie <div> lub <td> równej temu, ile dodatkowej lewej / prawej strony padding / border w „px”, twoim zdaniem, przeglądarki podać dane wejściowe. (Zazwyczaj 6px dla IE <8.)

Bobin
źródło
To działałoby świetnie, z wyjątkiem tego, że nie mogę tego użyć, ponieważ celuję w urządzenia mobilne, które prawdopodobnie nie będą obsługiwać tego przez lata. : - \
Dan Herbert
20
Myślę, że urządzenia mobilne będą miały pełną obsługę HTML5 przed komputerami.
Mariano Cavallo
4
@Kindred: zdecydowanie nie, jeśli włączysz w to IEMobile i Blackberry.
bobince
1
Ma to wielkie wsparcie dla przeglądarek desktopowych, choć: quirksmode.org/css/contents.html
Logan
2
Jak długo zajęło mi znalezienie tej niesamowitej buttersauce ??? Czy możemy przyjąć tę akceptowaną odpowiedź?
streetlogics,
14

To rozwiązało problem dla mnie!

Bez potrzeby zewnętrznego div. Po prostu zastosuj go do podanego pola tekstowego.

box-sizing: border-box; 

Dzięki tej właściwości „Właściwości szerokości i wysokości (oraz właściwości min / max) obejmują zawartość, dopełnienie i obramowanie, ale nie margines”

Zobacz opis nieruchomości w w3schools .

Mam nadzieję, że to komuś pomoże!

Jack Trowbridge
źródło
Cudownie proste! Dzięki!
pielęgniarka
10

Właśnie natknąłem się na ten problem, a jedynym rozwiązaniem, jakie mogłem znaleźć, które działało we wszystkich moich testowych przeglądarkach (IE6, IE7, Firefox) było:

  1. Zawiń pole wejściowe w dwa osobne DIV
  2. Ustaw zewnętrzny DIV na szerokość 100%, co zapobiega przepełnieniu dokumentu przez nasz pojemnik
  3. Umieść dopełnienie w wewnętrznym DIV dokładnie takiej wysokości, aby skompensować poziomy przelew na wejściu.
  4. Ustaw niestandardowe dopełnienie na wejściu, aby przepełniało go o tę samą liczbę, na jaką zezwoliłem w wewnętrznym DIV

Kod:

<div style="width: 100%">
    <div style="padding-right: 6px;">
        <input type="text" style="width: 100%; padding: 2px; margin: 0;
                                  border : solid 1px #999" />
    </div>
</div>

Tutaj całkowity przelew poziomy dla elementu wejściowego wynosi 6px - 2x (wypełnienie + ramka) - więc ustawiliśmy prawo dopełniania dla wewnętrznego DIV równego 6px.

Tobias Cohen
źródło
dodaj do elementu wejściowego wypełnienie
8px
7

obsługa zmiany rozmiaru pudełka jest całkiem dobra: http://caniuse.com/#search=box-sizing

Więc jeśli nie kierujesz na IE7, powinieneś być w stanie rozwiązać tego rodzaju problemy za pomocą tej właściwości. Warstwa taka jak sass lub mniejsza ułatwia obsługę takich prefiksów reguł, btw.

chikamichi
źródło
3

W rzeczywistości jest tak, ponieważ CSS definiuje 100% w stosunku do całej szerokości kontenera, w tym jego marginesów, ramek i wypełnienia; oznacza to, że przestrzeń jest dostępna. jego zawartość jest mniejsza niż 100%, chyba że pojemnik nie ma marginesów, ramek ani wypełnienia.

Jest to sprzeczne z intuicją i powszechnie uważane przez wielu za błąd, z którym się teraz utknęliśmy . Skutecznie oznacza to, że% wymiarów nie nadaje się do niczego poza pojemnikiem najwyższego poziomu, a nawet wtedy, tylko jeśli nie ma marginesów, ramek ani wypełnienia.

Zauważ, że marginesy, obramowania i dopełnienie pola tekstowego zawarte w określonym dla niego rozmiarze CSS - to kontener wyrzuca rzeczy.

Dopuszczalnie pracowałem nad tym, używając 98%, ale jest to mniej niż idealne rozwiązanie, ponieważ pola wejściowe mają tendencję do zmniejszania się w miarę powiększania się pojemnika.


EDYCJA: Natknąłem się na to podobne pytanie - nigdy nie wypróbowałem udzielonej odpowiedzi i nie wiem na pewno, czy dotyczy ona twojego problemu, ale wydaje się, że tak będzie.

Lawrence Dol
źródło
1

Jednym z rozwiązań, które może działać (działa dla mnie) jest zastosowanie ujemnego marginesu na wejściu (pole tekstowe) ... lub stałej szerokości dla ie7 lub porzucenie obsługi ie7. Powoduje to, że piksel ma idealną szerokość. Dla mnie jest to 7, więc dodałem 3 i 4, ale nadal jest idealny

Miałem ten sam problem i nienawidziłem mieć dodatkowych div na granicy itp!

Oto moje rozwiązanie, które wydaje się działać!

Powinieneś użyć arkusza stylów tylko ie7, aby uniknąć starhacków.

input.text{
    background-color: #fbfbfb;
    border : solid #eee 1px;
    width: 100%;
    -box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
    height: 32px;

    *line-height:32px;
    *margin-left:-3px;
    *margin-right:-4px;
    display: inline;   
    padding: 0px 0 0 5px;

}
GorillaApe
źródło
1

Jeśli nie możesz użyć, box-sizing:border-boxmożesz spróbować usunąć width:100%i umieścić bardzo duży sizeatrybut w <input>elemencie, ale wadą jest to, że musisz zmodyfikować HTML i nie możesz tego zrobić tylko za pomocą CSS:

<input size="1000"></input>
Siddhadev
źródło
0

Jeśli nie musisz tego robić dynamicznie (na przykład twoja forma ma stałą szerokość), możesz po prostu ustawić szerokość <input>elementów potomnych na szerokość ich pojemnika minus wszelkie dekoracje, takie jak wypełnienie, margines, obramowanie itp .:

 // the parent div here has a width of 200px:
.form-signin input[type="text"], .form-signin input[type="password"], .form-signin input[type="email"], .form-signin input[type="number"] {
  font-size: 16px;
  height: auto;
  display: block;
  width: 280px;
  margin-bottom: 15px;
  padding: 7px 9px;
}
Avishai
źródło
0

Jeśli nie możesz użyć funkcji zmiany rozmiaru pola (np. Podczas konwersji HTML na PDF za pomocą iText). Spróbuj tego:

CSS

.input-wrapper { border: 1px solid #ccc; padding: 0 5px; min-height: 20px; } 
.input-wrapper input[type=text] { border: none; height: 20px; width: 100%; padding: 0; margin: 0; }

HTML

<div class="input-wrapper">
     <input type="text" value="" name="city"/>
</div>
robertad
źródło
0

To działa:

<div>
    <input type="text" 
        style="margin: 5px; padding: 4px; border: 1px solid; 
        width: 200px; width: calc(100% - 20px);">
</div>

Pierwsza „szerokość” to zasada rezerwowa dla starszych przeglądarek.

Mo'in Creemers
źródło
0

Po prostu nadaj stylowi wartość wejściową, aby uzyskać dodatkowe wypełnienie. W poniższym przykładzie wypełnienie na wejściu wyniesie 10 pikseli po lewej i prawej stronie, przy całkowitym przesunięciu wypełnienia wynoszącym 20 pikseli:

input[type=text]{
   width: calc(100% - 20px);
}
Quinlo
źródło