ฉันจะสร้างความกว้างของ TextArea ได้ 100% โดยไม่ล้นเมื่อมีช่องว่างภายใน CSS


426

ฉันมีตัวอย่างข้อมูล CSS และ 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>

ปัญหาคือว่าพื้นที่ข้อความลงท้ายด้วยความกว้าง 8px (2px สำหรับเส้นขอบ + 6px สำหรับการขยาย) กว่าพาเรนต์ มีวิธีที่จะใช้เส้นขอบและช่องว่างภายใน แต่ จำกัด ขนาดรวมของtextareaถึงความกว้างของแม่หรือไม่


Btw มีบทความที่ดีสำหรับสิ่งนี้โดยJeffrey Wayบน tutsplus ที่นี่: net.tutsplus.com/tutorials/html-css-techniques/…บางทีมันอาจจะช่วยใครซักคนได้)
ใครบางคน

คำตอบ:


664

ทำไมไม่ลืมแฮ็กและทำมันด้วย CSS?

หนึ่งที่ฉันใช้บ่อย:

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

ดูการสนับสนุนเบราว์เซอร์ที่นี่


22
ฉันไม่อยากจะเชื่อเลยว่าสิ่งนี้ได้ผล แต่มันก็ทำ CSS ไม่ใช่เรื่องง่าย :-)
Nate Bird

1
นี่ต้องเป็นหนึ่งในสิ่งที่เจ๋งที่สุดที่ฉันเจอในขณะนี้ ขอบคุณโอกาสใด ๆ ที่มีวิธีการทำเช่นนี้ใน IE7 เช่นกัน?
Jeremy A. West

47
โปรดทราบว่าคุณยังคงต้องการใช้ความกว้าง: 100% ร่วมกับกล่องขอบ
Tyler

3
Internet Explorer รุ่นเก่าใช้ลักษณะการทำงานของกล่องแบบขอบเท่านั้นหรือไม่
Peter Hedberg

3
ใครสามารถอธิบายสิ่งนี้ได้โปรดชั้นนี้ไปที่ไหน กองรอบ textarea หรือไม่
koolaang

81

คำตอบของปัญหาการจัดรูปแบบ CSS ดูเหมือนจะ "เพิ่มอีก <div>!"

ดังนั้นในวิญญาณคุณลองเพิ่ม div wrapper ที่ใช้กับเส้นขอบ / แพ็ดดิ้งแล้วใส่ textarea ความกว้าง 100% ไว้ข้างในหรือไม่? สิ่งที่ชอบ (ยังไม่ทดลอง):

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>


1
ฉันลงเอยโดยไม่ใช้ความกว้าง% ฉันเชื่อว่าวิธีการของคุณจะทำงานได้ดีเช่นกัน ขอบคุณ!
Eric Schoonover

5
อย่าลืมเพิ่ม "." ไปยังคลาส textwrapper
Chris Porter

3
@Chris: ขอบคุณและแก้ไข ฉันประหลาดใจอย่างอ่อนโยนว่ามันใช้เวลาเกือบปีครึ่งสำหรับใครบางคนที่จะจับมัน ...
Dave Sherohman

2
แถบเลื่อนของ textarea จะมีลักษณะอย่างไรในกรณีนี้
Daniel LeCheminant

1
ในโครเมี่ยมเมื่อคุณเน้นองค์ประกอบ textarea มันจะถูกไฮไลต์โดยอัตโนมัติและถ้าคุณสร้างช่องว่างภายในสำหรับ wrapper div ช่องว่างนี้จะมองเห็นได้และสองเส้นขอบจะมองเห็นได้เนื่องจากสิ่งนั้น หนึ่งจากการไฮไลต์และอีกอันจาก. textwrapper border: 1px solid # 999999;
ใครบางคน

22

ลองพิจารณาผลลัพธ์สุดท้ายที่ให้กับผู้ใช้ในสิ่งที่เราต้องการเพื่อให้บรรลุ: ข้อความแบบเต็มที่มีทั้งเส้นขอบและแผ่นขยายซึ่งลักษณะใดที่ถูกคลิกพวกมันจะมุ่งเน้นไปที่ textarea ของเราและข้อดีของความกว้างอัตโนมัติ 100% องค์ประกอบทั่วไปของบล็อก

วิธีที่ดีที่สุดในความคิดของฉันคือการใช้โซลูชันระดับต่ำที่สุดเท่าที่จะทำได้เพื่อเข้าถึงการสนับสนุนเบราว์เซอร์สูงสุด ในกรณีนี้ HTML เท่านั้นที่สามารถใช้งานได้ดีหลีกเลี่ยงการใช้ Javascript (ซึ่งเราทุกคนรัก)

แท็ก LABEL มาในความช่วยเหลือของเราเนื่องจากมีพฤติกรรมดังกล่าวและได้รับอนุญาตให้มีองค์ประกอบอินพุตที่ต้องระบุ สไตล์เริ่มต้นของมันคือหนึ่งในองค์ประกอบแบบอินไลน์ดังนั้นเพื่อให้ป้ายแสดงรูปแบบบล็อกเราสามารถใช้ประโยชน์จากความกว้างอัตโนมัติ 100% รวมถึงช่องว่างภายในและเส้นขอบในขณะที่พื้นที่ข้อความภายในไม่มีขอบไม่มีช่องว่างและความกว้าง 100% .

ดูที่ W3C เฉพาะข้อดีอื่น ๆ ที่เราอาจสังเกตเห็นคือ:

  • ไม่จำเป็นต้องมีแอตทริบิวต์ "สำหรับ": เมื่อแท็ก LABEL มีอินพุตเป้าหมายมันจะเน้นอินพุตเด็กโดยอัตโนมัติเมื่อคลิก
  • หากมีการออกแบบป้ายชื่อภายนอกสำหรับ textarea แล้วจะไม่มีข้อขัดแย้งเกิดขึ้นเนื่องจากอินพุตที่ระบุอาจมีป้ายกำกับอย่างน้อยหนึ่งรายการ

ดูข้อมูลเฉพาะของ W3Cสำหรับข้อมูลรายละเอียดเพิ่มเติม

ตัวอย่างง่ายๆ:

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

การขยายและขอบขององค์ประกอบ. textareaContainer เป็นสิ่งที่เราต้องการให้กับ textarea ลองแก้ไขภาพให้มีสไตล์ตามที่คุณต้องการ ฉันให้ช่องว่างภายในขนาดใหญ่และมองเห็นได้กับองค์ประกอบ. textareaContainer เพื่อให้คุณเห็นพฤติกรรมของพวกเขาเมื่อคลิก


ไม่แน่ใจว่า gotchas ข้ามเบราว์เซอร์ตัวใดที่นี่ แต่ฉันชอบวิธีการ +1
HRJ

15

หากคุณไม่ใส่ใจเกี่ยวกับความกว้างของช่องว่างภายในโซลูชันนี้จะทำให้ระยะห่างระหว่างช่องว่างเป็นเปอร์เซ็นต์เช่นกัน

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

ไม่สมบูรณ์แบบ แต่คุณจะได้รับการเติมเต็มและความกว้างเพิ่มขึ้นถึง 100% ดังนั้นจึงเป็นเรื่องดี


12

ฉันเจอวิธีแก้ไขปัญหาอื่นที่นี่ซึ่งง่ายมาก: เพิ่มการเติมด้านขวาลงในคอนเทนเนอร์ textarea สิ่งนี้จะช่วยรักษาระยะขอบเส้นขอบและการเว้นระยะห่างบน textarea ซึ่งจะช่วยหลีกเลี่ยงปัญหาที่เบ็คชี้ให้เห็นเกี่ยวกับไฮไลต์โฟกัสที่โครมและซาฟารีใส่ไว้รอบ ๆ ตัวอักษร

ช่องว่างภายในของขวาควรเป็นผลรวมของระยะขอบที่มีประสิทธิภาพชายแดนและช่องว่างภายในทั้งสองด้านของ textarea รวมทั้งการขยายใด ๆ ที่คุณอาจต้องการภาชนะ ดังนั้นสำหรับกรณีในคำถามเดิม:

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>

1
+1 สิ่งนี้จะทำงานในเบราว์เซอร์มากกว่าคำสั่ง CSS3 ความจริงที่โชคร้ายคือโลกยังคงต้องการเสื้อคลุม
BenSwayne

ฉันชอบคำตอบนี้จริงๆ มันทำให้ textarea snap ให้พอดีโดยไม่มีตัวเลขเวทย์ใด ๆ น้อยกว่า 100% คุณสามารถใช้ช่องว่างภายในทุกด้านใน wrapper เพื่อบังคับให้พื้นที่ข้อความเลื่อนเข้าและอยู่ในพาเรนต์ ความสูงขั้นต่ำและความสูงจะต้องเป็น 100% ของเสื้อคลุมเช่นกัน สามารถตั้งค่า textarea เป็น 100% ด้วยการเติมเต็มเดียวกันเพื่อให้ทุกอย่างลงตัว
justdan23


5

คุณสามารถใช้ประโยชน์จากคุณสมบัติการปรับขนาดกล่องซึ่งรองรับโดยเบราว์เซอร์ที่ได้มาตรฐานและ IE8 + ทั้งหมด คุณยังคงต้องใช้วิธีการแก้ปัญหาสำหรับ IE7 อ่านเพิ่มเติมที่นี่


@DavidJohnstone: และเนื่องจากคุณไม่ได้พัฒนาเว็บไซต์สำหรับ IE7 หรือมากกว่าอีกต่อไปนี้เป็นวิธีการแก้ปัญหา :)
Jonatan Littke

2

ไม่คุณไม่สามารถทำได้ด้วย CSS นั่นคือเหตุผลว่าไมโครซอฟท์เปิดตัวครั้งแรกอีกและอาจจะปฏิบัติมากขึ้นรูปแบบกล่อง รูปแบบกล่องที่ได้รับรางวัลในที่สุดทำให้ไม่สามารถผสมเปอร์เซ็นต์และหน่วยต่าง ๆ ได้

ฉันไม่คิดว่ามันโอเคสำหรับคุณที่จะแสดงการขยายและความกว้างของเส้นขอบในหน่วยเปอร์เซ็นต์ของผู้ปกครองด้วย


2

ฉันกำลังมองหาวิธีแก้ปัญหาแบบอินไลน์แทนที่จะเป็นวิธีแก้ปัญหา CSS และนี่คือสิ่งที่ดีที่สุดที่ฉันสามารถทำได้เพื่อตอบสนองการใช้งาน textarea:

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

1

หากคุณกดและชดเชยเช่นนี้:

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

ด้านขวาของ textarea สอดคล้องกับด้านขวาของคอนเทนเนอร์อย่างสมบูรณ์และข้อความภายใน textarea จัดเรียงอย่างสมบูรณ์แบบกับเนื้อความในคอนเทนเนอร์ ... และด้านซ้ายของ textarea 'ยื่นออกมาเล็กน้อย' บางครั้งมันก็สวยกว่า



1

สำหรับผู้ที่ใช้ Bootstrap textarea.form-control สามารถนำไปสู่ปัญหาการกำหนดขนาด textarea ได้เช่นกัน Chrome และ Firefox ใช้ความสูงที่แตกต่างกันด้วย Bootstrap CSS ต่อไปนี้:

textarea.form-conrtol{
    height:auto;
}

1

calc()ฉันมักจะแก้ไขปัญหาด้วย คุณเพียงแค่ให้ textarea มีความกว้าง 100% และ padding ในจำนวนหนึ่ง แต่คุณต้องลบการเติม padding ทั้งหมดและซ้ายของความกว้าง 100% ที่คุณให้กับ textarea:

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

หรือถ้าคุณต้องการให้ข้อความเป็นเส้นขอบ:

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

0

ระยะขอบด้านลบเป็นอย่างไร?

textarea {
    border:1px solid #999999;
    width:100%;
    margin:5px -4px; /* 4px = border+padding on one side */
    padding:3px;
}

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>

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.