Wie kann ich eine TextArea-Breite von 100% erstellen, ohne überzulaufen, wenn in CSS Polster vorhanden sind?

426

Ich habe das folgende CSS- und HTML-Snippet gerendert.

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>

Das Problem ist, dass der Textbereich 8 Pixel breiter ist (2 Pixel für Rand + 6 Pixel für Auffüllen) als der übergeordnete Bereich. Gibt es eine Möglichkeit, weiterhin Rahmen und Polster zu verwenden, aber die Gesamtgröße von textareaauf die Breite des übergeordneten Elements zu beschränken?

Eric Schoonover
quelle
Übrigens gibt es hier einen guten Artikel von Jeffrey Way auf tutsplus hier: net.tutsplus.com/tutorials/html-css-techniques/… Vielleicht hilft es jemandem;)
Jemand

Antworten:

664

Warum nicht die Hacks vergessen und es einfach mit CSS machen?

Eine, die ich häufig benutze:

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

Siehe Browserunterstützung hier .

Piet Bijl
quelle
21
Ich kann nicht glauben, dass das funktioniert hat. Aber es tat es. CSS ist noch nie so einfach. :-)
Nate Bird
1
Dies muss eines der coolsten Dinge sein, die ich seit einiger Zeit gefunden habe. Vielen Dank, gibt es eine Möglichkeit, dies auch in IE7 zu tun?
Jeremy A. West
47
Beachten Sie, dass Sie weiterhin width: 100% in Verbindung mit dem Rahmen verwenden möchten.
Tyler
3
Verwenden alte Versionen von Internet Explorer nicht nur das Border-Box-Verhalten?
Peter Hedberg
3
Kann jemand dies bitte erklären, wohin geht diese Klasse? ein div um den textbereich?
Koolaang
81

Die Antwort auf viele CSS-Formatierungsprobleme scheint zu sein: "Füge ein weiteres <div> hinzu!"

Haben Sie in diesem Sinne versucht, ein Wrapper-Div hinzuzufügen, auf das der Rand / die Polsterung angewendet wird, und dann den Textbereich mit 100% Breite darin zu platzieren? So etwas wie (ungetestet):

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
quelle
1
Am Ende habe ich mich von der Verwendung von% widths entfernt. Ich glaube, Ihr Ansatz würde genauso gut funktionieren. Vielen Dank!
Eric Schoonover
5
Vergessen Sie nicht, "." zur Textwrapper-Klasse.
Chris Porter
3
@ Chris: Danke und behoben. Ich bin leicht überrascht, dass es fast anderthalb Jahre
gedauert hat
2
Wie sehen die Bildlaufleisten des Textbereichs in diesem Fall aus?
Daniel LeCheminant
1
Wenn Sie in Chrome das Textarea-Element fokussieren, wird es automatisch hervorgehoben. Wenn Sie eine Auffüllung für den Div-Wrapper erstellen, ist diese Auffüllung sichtbar, und aus diesem Grund sind zwei Ränder sichtbar. Eine von Hightlighting und eine von .textwrapper border: 1px solid # 999999;
Jemand
22

Betrachten wir die endgültige Ausgabe, die an den Benutzer gerendert wird, was wir erreichen möchten: einen gepolsterten Textbereich mit Rand und Polsterung. Diese Eigenschaften sind, dass durch Klicken der Fokus auf unseren Textbereich übertragen wird, und der Vorteil einer automatischen Breite von 100% typisch für Blockelemente.

Meiner Meinung nach ist es am besten, so weit wie möglich Low-Level-Lösungen zu verwenden, um die maximale Browserunterstützung zu erreichen. In diesem Fall könnte der einzige HTML-Code einwandfrei funktionieren und die Verwendung von Javascript vermeiden (was wir jedenfalls alle lieben).

Das LABEL-Tag wird in unserer Hilfe angezeigt, da es ein solches Verhalten aufweist und die Eingabeelemente enthalten darf, an die es adressieren muss. Der Standardstil ist der eines Inline-Elements. Wenn Sie dem Etikett einen Blockanzeigestil geben, können Sie die automatische Breite von 100% einschließlich Polsterung und Rahmen nutzen, während der innere Textbereich keinen Rand, keine Polsterung und eine Breite von 100% aufweist .

Wenn wir uns die W3C-Besonderheiten ansehen, können wir folgende weitere Vorteile feststellen:

  • Es wird kein "for" -Attribut benötigt: Wenn ein LABEL-Tag die Zieleingabe enthält, fokussiert es automatisch die untergeordnete Eingabe, wenn darauf geklickt wird.
  • Wenn bereits eine externe Beschriftung für den Textbereich entworfen wurde, treten keine Konflikte auf, da eine bestimmte Eingabe eine oder mehrere Beschriftungen haben kann.

Weitere Informationen finden Sie in den W3C-Spezifikationen .

Einfaches Beispiel:

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

Das Auffüllen und der Rand der .textareaContainer-Elemente sind diejenigen, die wir dem Textbereich geben möchten. Bearbeiten Sie sie, um sie nach Ihren Wünschen zu gestalten. Ich habe dem .textareaContainer-Element große und sichtbare Auffüllungen und Rahmen gegeben, damit Sie ihr Verhalten beim Klicken sehen können.

Emanuele Del Grande
quelle
Ich bin mir nicht sicher, welche browserübergreifenden Fallstricke hier lauern, aber ich mochte den Ansatz. +1
HRJ
15

Wenn Sie sich nicht zu sehr um die Breite der Polsterung kümmern, hält diese Lösung die Polsterung auch in Prozent.

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

Nicht perfekt, aber Sie erhalten etwas Polsterung und die Breite summiert sich auf 100%, also ist alles gut

qui
quelle
12

Ich bin hier auf eine andere Lösung gestoßen , die so einfach ist: Füge dem Container des Textbereichs ein Auffüllrecht hinzu. Dadurch bleiben Rand, Rand und Polsterung des Textbereichs erhalten, wodurch das Problem vermieden wird, auf das Beck bei der Hervorhebung des Fokus hingewiesen hat, den Chrom und Safari um den Textbereich gelegt haben.

Das Auffüllrecht des Containers sollte die Summe aus dem effektiven Rand, dem Rand und dem Auffüllen auf beiden Seiten des Textbereichs sowie allen Auffüllungen sein, die Sie ansonsten für den Container wünschen. Also für den Fall in der ursprünglichen Frage:

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
quelle
1
+1 Dies funktioniert in mehr Browsern als in den CSS3-Anweisungen. Die unglückliche Wahrheit ist, dass die Welt immer noch Wrapper Divs braucht.
BenSwayne
Diese Antwort gefällt mir sehr gut. Dadurch passt der Textbereich ohne magische Prozentzahlen unter 100%. Sie können den Wrapper an allen Seiten auffüllen, um zu erzwingen, dass sich der Textbereich nach innen bewegt und im übergeordneten Element verbleibt. Die Mindesthöhe und -höhe muss ebenfalls 100% auf der Verpackung betragen. Der Textbereich kann dann mit der gleichen Polsterung auf 100% eingestellt werden, damit alles perfekt passt.
Justdan23
9

Dieser Code funktioniert für mich mit IE8 und Firefox

<td>
    <textarea style="width:100%" rows=3 name="abc">Modify width:% accordingly</textarea>
</td>
Jeff Gast
quelle
Arbeitete auch in Chrome.
Sanjeev
5

Sie können die Box-Sizing-Eigenschaft verwenden, die von allen gängigen standardkonformen Browsern und IE8 + unterstützt wird. Sie benötigen jedoch noch eine Problemumgehung für IE7. Lesen Sie hier mehr .

jzfgo
quelle
@ DavidJohnstone: Und da Sie keine Websites mehr für IE7 oder älter entwickeln, ist dies DIE Lösung :)
Jonatan Littke
2

Nein, das geht mit CSS nicht. Aus diesem Grund hat Microsoft zunächst ein anderes und möglicherweise praktischeres Box-Modell eingeführt . Das Box-Modell, das letztendlich gewonnen hat, macht es unpraktisch, Prozentsätze und Einheiten zu mischen.

Ich denke nicht, dass es in Ordnung ist, Polsterung und Randbreiten auch in Prozent des übergeordneten Elements auszudrücken.

Buti-Oxa
quelle
2

Ich suchte nach einer Inline-Styling-Lösung anstelle einer CSS-Lösung, und dies ist das Beste, was ich für einen reaktionsschnellen Textbereich tun kann:

<div style="width: 100%; max-width: 500px;">
  <textarea style="width: 100%;"></textarea>
</div>
Jee Mok
quelle
1

Wenn Sie es wie folgt auffüllen und versetzen:

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

Die rechte Seite des Textbereichs ist perfekt auf die rechte Seite des Containers ausgerichtet, und der Text im Textbereich ist perfekt auf den Text im Container ausgerichtet ... und die linke Seite des Textbereichs ragt etwas heraus. es ist manchmal schöner.

Commonpike
quelle
1

Verwenden Sie die Box Sizing-Eigenschaft :

-moz-box-sizing:border-box; 
-webkit-box-sizing:border-box; 
box-sizing:border-box;

Das wird helfen

user3074446
quelle
1

Für Benutzer von Bootstrap kann textarea.form-control ebenfalls zu Problemen bei der Größe von Textbereichen führen. Chrome und Firefox scheinen mit dem folgenden Bootstrap-CSS unterschiedliche Höhen zu verwenden:

textarea.form-conrtol{
    height:auto;
}
Gwi7d31
quelle
1

Ich behebe dieses Problem oft mit calc(). Sie geben dem Textbereich nur eine Breite von 100% und eine bestimmte Polsterung, aber Sie müssen die gesamte linke und rechte Polsterung von der 100% Breite subtrahieren, die Sie dem Textbereich gegeben haben:

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

Oder wenn Sie dem Textbereich einen Rand geben möchten:

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

Wie wäre es mit negativen Margen?

textarea {
    border:1px solid #999999;
    width:100%;
    margin:5px -4px; /* 4px = border+padding on one side */
    padding:3px;
}
Meustrus
quelle
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>

Anteliebe
quelle