Jak mogę utworzyć TextArea o 100% szerokości bez przepełnienia, gdy w CSS występuje wypełnienie?

426

Renderowany jest następujący fragment kodu CSS i HTML.

textarea
{
  border:1px solid #999999;
  width:100%;
  margin:5px 0;
  padding:3px;
}
<div style="display: block;" id="rulesformitem" class="formitem">
  <label for="rules" id="ruleslabel">Rules:</label>
  <textarea cols="2" rows="10" id="rules"/>
</div>

Problem polega na tym, że obszar tekstowy jest o 8px szerszy (2px dla ramki + 6px dla wypełnienia) niż element nadrzędny. Czy istnieje sposób, aby nadal używać ramki i wypełnienia, ale ograniczyć całkowity rozmiar textareado szerokości elementu nadrzędnego?

Eric Schoonover
źródło
Przy okazji jest dobry artykuł Jeffrey Way na tutsplus tutaj: net.tutsplus.com/tutorials/html-css-techniques/… Może to komuś pomoże;)
Ktoś

Odpowiedzi:

664

Dlaczego nie zapomnieć o włamaniach i po prostu zrobić to za pomocą CSS?

Z którego często korzystam:

.boxsizingBorder {
    -webkit-box-sizing: border-box;
       -moz-box-sizing: border-box;
            box-sizing: border-box;
}

Zobacz obsługę przeglądarki tutaj .

Piet Bijl
źródło
22
Nie wierzę, że to zadziałało. Ale tak się stało. CSS nigdy nie jest tak łatwy. :-)
Nate Bird,
1
To musi być jedna z najfajniejszych rzeczy, które znalazłem od jakiegoś czasu. Dziękuję, czy jest szansa, aby to zrobić również w IE7?
Jeremy A. West
47
Pamiętaj, że nadal będziesz chciał użyć szerokości: 100% w połączeniu z ramką.
Tyler
3
Czy stare wersje Internet Explorera nie wykorzystują jedynie zachowania ramki?
Peter Hedberg,
3
czy ktoś może to wyjaśnić, dokąd idzie ta klasa? div otaczający textarea?
koolaang,
81

Odpowiedzią na wiele problemów z formatowaniem CSS wydaje się być „dodaj kolejny <div>!”

Czy w tym duchu próbowałeś dodać div otoki, do którego zastosowano obramowanie / wypełnienie, a następnie umieścić w nim obszar tekstowy o szerokości 100%? Coś w stylu (niesprawdzone):

textarea
{
  width:100%;
}
.textwrapper
{
  border:1px solid #999999;
  margin:5px 0;
  padding:3px;
}
<div style="display: block;" id="rulesformitem" class="formitem">
  <label for="rules" id="ruleslabel">Rules:</label>
  <div class="textwrapper"><textarea cols="2" rows="10" id="rules"/></div>
</div>

Dave Sherohman
źródło
1
Skończyło się odejście od używania% szerokości. Wierzę, że twoje podejście zadziałałoby równie dobrze. Dzięki!
Eric Schoonover,
5
Nie zapomnij dodać „.” do klasy textwrapper.
Chris Porter
3
@Chris: Dzięki i naprawione. Jestem lekko zaskoczony, że złapanie tego zajęło prawie półtora roku ...
Dave Sherohman
2
Jak będą wyglądały paski przewijania textarei w tym przypadku?
Daniel LeCheminant
1
W chromie, gdy skupiasz się na elemencie textarea, jest on automatycznie podświetlany i jeśli utworzysz wypełnienie dla opakowania div, to wypełnienie będzie widoczne i dzięki temu będą widoczne dwie ramki. Jeden z podświetlenia, a drugi z .textwrapper border: 1px solid # 999999;
Ktoś
22

rozważmy ostateczny wynik uzyskany dla użytkownika tego, co chcemy osiągnąć: wypełniony obszar tekstowy zarówno z ramką, jak i wypełnienie, których cechami jest to, że po kliknięciu przenoszą one fokus na nasz obszar tekstowy, a zaletą jest automatyczna 100% szerokość typowe dla elementów blokowych.

Moim zdaniem najlepsze podejście polega na wykorzystaniu w miarę możliwości rozwiązań niskiego poziomu, aby osiągnąć maksymalną obsługę przeglądarek. W takim przypadku jedyny HTML mógłby działać dobrze, unikając korzystania z Javascript (który tak czy inaczej wszyscy kochamy).

Tag LABEL jest dostępny w naszej pomocy, ponieważ ma takie zachowanie i może zawierać elementy wejściowe, do których musi się odnosić. Jego domyślnym stylem jest jeden z elementów wbudowanych, więc nadając etykiecie styl wyświetlania bloków, możemy skorzystać z automatycznej 100% szerokości, w tym wypełnienia i obramowań, podczas gdy wewnętrzny obszar tekstowy nie ma obramowania, wypełnienia i 100% szerokości .

Patrząc na specyfikę W3C możemy zauważyć inne zalety:

  • nie jest potrzebny atrybut „for”: gdy tag LABEL zawiera dane wejściowe celu, automatycznie skupia dane potomne po kliknięciu;
  • jeśli zewnętrzna etykieta dla obszaru tekstowego została już zaprojektowana, nie występują konflikty, ponieważ dane wejściowe mogą mieć jedną lub więcej etykiet.

Zobacz szczegółowe informacje na temat W3C, aby uzyskać bardziej szczegółowe informacje.

Prosty przykład:

.container { 
  width: 400px; 
  border: 3px 
  solid #f7c; 
  }
.textareaContainer {
	display: block;
	border: 3px solid #38c;
	padding: 10px;
  }
textarea { 
  width: 100%; 
  margin: 0; 
  padding: 0; 
  border-width: 0; 
  }
<body>
<div class="container">
	I am the container
	<label class="textareaContainer">
		<textarea name="text">I am the padded textarea with a styled border...</textarea>
	</label>
</div>
</body>

Wypełnienie i ramka elementów .textareaContainer to te, które chcemy nadać obszarowi tekstowemu. Spróbuj je edytować, aby stylizować go tak, jak chcesz. Dałem duże i widoczne wypełnienie i obramowania elementowi .textareaContainer, aby umożliwić ich zachowanie po kliknięciu.

Emanuele Del Grande
źródło
Nie jestem pewien, co czają się tutaj przeglądarki z różnych przeglądarek, ale podobało mi się to podejście. +1
HRJ
15

Jeśli nie przeszkadza ci szerokość wypełnienia, to rozwiązanie utrzyma wypełnienie również w procentach.

textarea
{
    border:1px solid #999999;
    width:98%;
    margin:5px 0;
    padding:1%;
}

Nie idealnie, ale dostaniesz trochę wypełnienia, a szerokość dodaje się do 100%, więc wszystko jest dobrze

qui
źródło
12

Natrafiłem tutaj na inne rozwiązanie które jest tak proste: dodaj padding-prawo do kontenera textarea. Dzięki temu margines, obramowanie i wypełnienie pola tekstowego zostają usunięte, co pozwala uniknąć problemu wskazanego przez Becka na temat podświetlenia fokusa, które chrom i safari umieszczają wokół obszaru tekstowego.

Prawa dopełnienie kontenera powinna być sumą efektywnego marginesu, ramki i dopełnienia po obu stronach obszaru tekstowego, a także dopełnienie, które w innym przypadku może być potrzebne dla kontenera. Zatem w przypadku pierwotnego pytania:

textarea{
    border:1px solid #999999;
    width:100%;
    margin:5px 0;
    padding:3px;
}
.textareacontainer{
    padding-right: 8px; /* 1 + 3 + 3 + 1 */
}

<div class="textareacontainer">
    <textarea></textarea>
</div>
Brian
źródło
1
+1 Będzie to działać w większej liczbie przeglądarek niż instrukcje CSS3. Niefortunna prawda jest taka, że ​​świat wciąż potrzebuje otulaczy.
BenSwayne,
Naprawdę podoba mi się ta odpowiedź. Sprawia, że ​​obszar tekstowy dopasowuje się bez magicznych liczb procentowych mniejszych niż 100%. Możesz użyć dopełnienia ze wszystkich stron w opakowaniu, aby zmusić obszar tekstowy do przejścia i pozostania wewnątrz elementu nadrzędnego. Minimalna wysokość i wysokość muszą również wynosić 100% na owijce. Obszar tekstowy można następnie ustawić na 100% z tym samym wypełnieniem, aby wszystko idealnie pasowało.
justdan23
9

Ten kod działa dla mnie z IE8 i Firefox

<td>
    <textarea style="width:100%" rows=3 name="abc">Modify width:% accordingly</textarea>
</td>
Jeff Guest
źródło
Pracował też w Chrome.
Sanjeev
5

Możesz skorzystać z właściwości zmiany wielkości pudełka, jest ona obsługiwana przez wszystkie główne przeglądarki zgodne ze standardem i IE8 +. Nadal będziesz potrzebować obejścia dla IE7. Przeczytaj więcej tutaj .

jzfgo
źródło
@DavidJohnstone: A ponieważ nie tworzysz już witryn dla IE7 lub starszych, jest to NAJLEPSZE rozwiązanie :)
Jonatan Littke,
2

Nie, nie możesz tego zrobić za pomocą CSS. To jest powód, dla którego Microsoft początkowo wprowadził inny, a może bardziej praktyczny model pudełkowy . Model pudełkowy, który ostatecznie wygrał, sprawia, że ​​mieszanie procentów i jednostek jest niepraktyczne.

Nie sądzę, aby wyrażanie szerokości wypełnienia i obramowania w procentach elementu nadrzędnego było w porządku.

buti-oxa
źródło
2

Szukałem rozwiązania do stylizacji wbudowanej zamiast rozwiązania CSS, a to najlepsze, co mogę zrobić, aby uzyskać responsywny obszar tekstowy:

<div style="width: 100%; max-width: 500px;">
  <textarea style="width: 100%;"></textarea>
</div>
Jee Mok
źródło
1

Jeśli padniesz i przesuniesz w następujący sposób:

textarea
{
    border:1px solid #999999;
    width:100%;
    padding: 7px 0 7px 7px; 
    position:relative; left:-8px; /* 1px border, too */
}

prawa strona obszaru tekstowego idealnie dopasowuje się do prawej strony pojemnika, a tekst wewnątrz obszaru tekstowego idealnie dopasowuje się do tekstu podstawowego w pojemniku ... a lewa strona obszaru tekstowego „nieco wystaje”. czasami jest ładniejsza.

pospolity
źródło
1

Dla osób korzystających z Bootstrap, textarea.form-control może również powodować problemy z rozmiarem textarea. Chrome i Firefox wydają się używać różnych wysokości w następującym CSS Bootstrap:

textarea.form-conrtol{
    height:auto;
}
Gwi7d31
źródło
1

Często naprawiam ten problem calc(). Po prostu dajesz obszarowi tekstowemu szerokość 100% i pewną ilość dopełnienia, ale musisz odjąć całkowitą lewą i prawą dopełnienie 100% szerokości, którą nadałeś obszarowi tekstowemu:

textarea {
    border: 0px;
    width: calc(100% -10px);
    padding: 5px; 
}

Lub jeśli chcesz nadać obszarowi tekstowemu granicę:

textarea {
    border: 1px;
    width: calc(100% -12px); /* plus the total left and right border */
    padding: 5px; 
}
Jeroen Bellemans
źródło
0

Co powiesz na ujemne marże?

textarea {
    border:1px solid #999999;
    width:100%;
    margin:5px -4px; /* 4px = border+padding on one side */
    padding:3px;
}
meustrus
źródło
0

* {
    box-sizing: border-box;
}

.container {
    border-radius: 5px;
    background-color: #f2f2f2;
    padding: 20px;
}

/* Clear floats after the columns */
.row:after {
    content: "";
    display: table;
    clear: both;
}

input[type=text], select, textarea{
    width: 100%;
    padding: 12px;
    border: 1px solid #ccc;
    border-radius: 4px;
    box-sizing: border-box;
    resize: vertical;
}
<div class="container">
  <div class="row">
    <label for="name">Name</label>
    <input type="text" id="name" name="name" placeholder="Your name..">
  </div>
  <div class="row">
    <label for="country">Country</label>
    <select id="country" name="country">
      <option value="australia">UK</option>
      <option value="canada">USA</option>
      <option value="usa">RU</option>
    </select>
  </div>    
  <div class="row">
    <label for="subject">Subject</label>
    <textarea id="subject" name="subject" placeholder="Write something.." style="height:200px"></textarea>
  </div>
</div>

antylopa
źródło