กล่องข้อความอินพุต HTML ที่มีความกว้าง 100% ล้นเซลล์ตาราง


106

มีใครรู้บ้างว่าทำไมองค์ประกอบอินพุตที่มีความกว้าง 100% จึงอยู่เหนือเส้นขอบเซลล์ของตาราง

ในตัวอย่างง่ายๆด้านล่างช่องป้อนข้อมูลไปที่เส้นขอบเซลล์ของตารางผลลัพธ์ที่ได้นั้นแย่มาก สิ่งนี้ได้รับการทดสอบแล้วและเกิดขึ้นในลักษณะเดียวกันกับ: Firefox, IE7 และ Safari

มันสมเหตุสมผลสำหรับคุณหรือไม่? ฉันขาดอะไรไปคุณรู้วิธีแก้ปัญหาที่เป็นไปได้ไหม

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">    
<html><head>    
   <meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> <!-- don't use closing slash in meta tag, it breaks HTML4.01 transitional -->
   <title>Test input text in table</title>
   <style type="text/css">      
      table {border-top: 1px solid #ff0000; border-left: 1px solid #ff0000;}
      table td {border-right: 1px solid #00ff00; border-bottom: 1px solid #00ff00;}
      input[type="text"] {width: 100%;} /* removing this would make input not to go over cells border, but they would be too short, I want them to fit cells size */
   </style>    
</head><body>

<table cellpadding="0" cellspacing="0">
   <tr>
      <td><p>column one hello babe babe babe</p></td>
      <td><p>column two hello babe more</p></td>
      <td><p>column three hello babe more and more</p></td>
   </tr>
   <tr>
      <td><input type="text" value="test"></td>
      <td><input type="text" value="test"></td>
      <td><input type="text" value="test"></td>
   </tr>
</table>

</body></html>

1
ผมขอแนะนำว่าถ้าคุณเพียงแค่ใช้ตารางปัจจัยการผลิตเพื่อนำเสนอคุณอาจเปลี่ยนไปใช้formกับlabelและinputs ภายในหรือul olซึ่งอย่างน้อยก็มีความหมายมากกว่านี้เล็กน้อย แน่นอนว่าคุณควรใช้ a formแม้ว่าคุณจะยึดติดกับไฟล์table.
David กล่าวว่าคืนสถานะ Monica

คำตอบ:


216

คุณสามารถใช้box-sizingคุณสมบัติCSS3 เพื่อรวมช่องว่างภายในและเส้นขอบภายนอก:

input[type="text"] {
     width: 100%; 
     box-sizing: border-box;
     -webkit-box-sizing:border-box;
     -moz-box-sizing: border-box;
}

1
น่าเศร้าที่ต้องบอกว่าน่าเสียดายที่ IE 7 ไม่จัดการกับขนาดกล่องอย่างถูกต้อง ลองทำสิ่งต่อไปนี้ใน IE 7 ... css3.info/preview/box-sizingหรือดู css-tricks.com/box-sizing
AnthonyVO

@AnthonyVO: จริงวิธีแก้ปัญหาเฉพาะสำหรับ IE7 คือการเพิ่ม CSS เฉพาะโดยใช้ความคิดเห็นตามเงื่อนไขของ IE <!--[if lt IE 8]>และinput[type="text"] {width:95%}
Marco Demaio

24

ค่าความกว้างไม่คำนึงถึงเส้นขอบหรือช่องว่างภายใน:

http://www.htmldog.com/reference/cssproperties/width/

คุณจะได้รับช่องว่างภายใน 2px ในแต่ละด้านบวก 1px ของเส้นขอบในแต่ละด้าน
100% + 2 * (2px + 1px) = 100% + 6px ซึ่งมากกว่าเนื้อหาย่อย 100% ที่ผู้ปกครองมี

คุณมีตัวเลือกดังนี้

  • ทั้งการตั้งค่าbox-sizing: border-box;ตามคำตอบของ @ pricco ;
  • หรือใช้ 0 ขอบและช่องว่างภายใน (หลีกเลี่ยงขนาดพิเศษ)

เพิ่มเติมสำหรับคำตอบ Sr pts คุณสามารถตั้งค่าช่องว่างภายในและเส้นขอบเป็น 0px จากนั้น 100% ควรใช้งานได้
Mauro

อันที่จริงแม้ว่าจะไม่ได้ตั้งค่าช่องว่างใด ๆ สำหรับ td - เพิ่มได้เป็นอย่างดี
ANeves คิดว่า SE ชั่วร้าย

1
นอกจากนี้หากช่องว่างภายในสร้างปัญหาก็เป็นไปได้ที่จะใช้text-indentเพื่อจำลองช่องว่างข้างหน้าข้อความและline-heightสำหรับช่องว่างในแนวตั้ง (แม้ว่าการคงช่องว่างในแนวตั้งจะไม่ส่งผลต่อความกว้างก็ตาม)
David กล่าวว่าคืนสถานะ Monica

14

ปัญหาของสิ่งต่างๆเช่นwidth:95%;พวกเขาดูไม่ถูกต้องในรูปแบบที่ยืดหยุ่นกว้าง ๆ (เพราะ 5% อาจเป็น 30 พิกเซล)

วิธีแก้ปัญหาต่อไปนี้ใช้งานได้ดีสำหรับฉัน (ทดสอบใน Firefox, IE 9, Safari):

<table style="background-color: blue; width: 100%;" cellpadding="0" cellspacing="0">
<tr>
    <td style="background-color: red;   padding: 3px;">
        <div style="margin-right: 3px;">
            <div style="padding-right: 3px;">
                <input type="text" style="width:100%;">
            </div>
        </div>
    </td>
    <td style="background-color: purple;   padding: 3px;">
        <div style="margin-right: 3px;">
            <div style="padding-right: 3px;">
                <input type="text" style="width:100%;">
            </div>
        </div>
    </td>
    <td style="background-color: green;   padding: 3px;">
        <div style="margin-right: 3px;">
            <div style="padding-right: 3px;">
                <input type="text" style="width:100%;">
            </div>
        </div>
    </td>
</tr>
</table>

(เพิ่มสีเพื่อให้สังเกตเห็นช่องว่างภายในที่ถูกต้องได้ง่ายขึ้น)

เคล็ดลับคือการห่ออินพุตด้วย div สองอันด้านนอกมีระยะขอบ 3px (ซึ่งทำให้เล็กกว่า td 3px) ด้านในมีช่องว่างภายใน 3px สิ่งนี้ทำให้อินพุตเล็กกว่า td 6px ซึ่งเป็นสิ่งที่คุณต้องการเริ่มต้นด้วย

ฉันไม่แน่ใจเกี่ยวกับกลไกของสิ่งนี้ แต่ได้ผล

ในตัวอย่างง่ายๆนี้มันยังใช้งานได้กับ div เพียงตัวเดียวที่มีขอบด้านขวา 6 อย่างไรก็ตามในกรณีของเว็บแอปพลิเคชันของฉันมีเพียงโซลูชันข้างต้นเท่านั้นที่ใช้ได้

<table style="background-color: blue; width: 100%;" cellpadding="0" cellspacing="0">
<tr>
    <td style="background-color: red;   padding: 3px;">
        <div style="margin-right: 6px;">
                <input type="text" style="width:100%;">
        </div>
    </td>
    <td style="background-color: purple;   padding: 3px;">
        <div style="margin-right: 6px;">
                <input type="text" style="width:100%;">
        </div>
    </td>
    <td style="background-color: green;   padding: 3px;">
        <div style="margin-right: 6px;">
                <input type="text" style="width:100%;">
        </div>
    </td>
</tr>
</table>

มันใช้งานได้ (โหวตขึ้น +1) น่าแปลกที่ฉันแทรกข้อความก่อน <input> แต่ละรายการและเพิ่ม "white-space: nowrap" เพื่อให้อยู่ในบรรทัดเดียวกันจากนั้น <inputs> ทั้งสามจะล้นเซลล์ตารางถ้าฉันลบ "white-space: nowrap" ทุกอย่าง ใช้งานได้อีกครั้ง แปลก.
Jose Manuel Abarca Rodríguez

8

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

<table>
  <tr>
    <td><div style="overflow:hidden"><input style="width:100%" type="text" name="name" value="hello world" /></div></td>
  </tr>
</table>

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

ฉันได้ทดสอบสิ่งนี้ใน Chrome และใน Fire Fox ทั้งสองดูเหมือนจะเคารพการแก้ปัญหานี้ดี

อัปเดต : เนื่องจากฉันเพิ่งได้รับการโหวตแบบสุ่มฉันอยากจะบอกว่าวิธีที่ดีกว่าในการจัดการกับการล้นคือการใช้แอตทริบิวต์ขนาดกล่อง CSS3 ตามที่ pricco อธิบายไว้:

.myinput {
    -moz-box-sizing: border-box;
    -webkit-box-sizing: border-box;
    -ms-box-sizing: border-box;
    -o-box-sizing: border-box;
    box-sizing: border-box;
}

ดูเหมือนว่าเบราว์เซอร์หลัก ๆ จะได้รับการสนับสนุนเป็นอย่างดีและไม่ได้ "แฮ็ก" เหมือนเคล็ดลับล้น อย่างไรก็ตามมีปัญหาเล็กน้อยบางประการในเบราว์เซอร์ปัจจุบันที่ใช้วิธีนี้ (ดูhttp://caniuse.com/#search=box-sizingปัญหาที่ทราบ)


3
หมายเหตุสั้น ๆ : overflow: hidden;เนื้อหายังคง 'โผล่ผ่าน' ไปด้านนอกของกรอบในลักษณะเดียวกันทุกประการ แต่จะถูกตัดทอนแทนที่จะแสดง - ดังนั้นเนื้อหาอื่น ๆ จึงไม่ทับซ้อนกัน
ANeves คิดว่า SE ชั่วร้าย

2

ฉันรู้ว่าคำถามนี้มีอายุ 3 ปีแล้ว แต่ปัญหายังคงมีอยู่สำหรับเบราว์เซอร์ปัจจุบันและผู้คนยังคงมาที่นี่ ทางออกสำหรับตอนนี้คือcalc () :

input {
    width: calc(100% - 12px); /* IE 9,10 , Chrome, Firefox */
    width: -webkit-calc(100% - 12px); /*For safari 6.0*/
}

ได้รับการสนับสนุนโดยเบราว์เซอร์ที่ทันสมัยที่สุด


1

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

รวมอินพุตของคุณด้วยองค์ประกอบอื่นตัวอย่างเช่น div จากนั้นใช้สไตล์ที่คุณต้องการสำหรับข้อมูลที่คุณป้อนกับ Wrapper div ตัวอย่างเช่น:

<div class="input-wrapper">
 <input type="text" />
</div>

.input-wrapper {
    border-raius:5px;
    padding:10px;
}
.input-wrapper input[type=text] {
    width:100%;
    font-size:16px;
}

ให้ .input-wrapper การเว้นช่องมุมโค้งมน ฯลฯ สิ่งที่คุณต้องการสำหรับอินพุตของคุณจากนั้นให้ความกว้างอินพุต 100% คุณมีข้อมูลที่คุณใส่ไว้อย่างดีด้วยเส้นขอบ ฯลฯ แต่ไม่มีการล้นที่น่ารำคาญ!


1

ฉันแก้ไขปัญหานี้โดยเริ่มจากคำตอบของ @ hallodom อินพุตทั้งหมดของฉันอยู่ใน li's ดังนั้นสิ่งที่ฉันต้องทำคือตั้งค่า li overflow: ซ่อนไว้เพื่อลบอินพุตส่วนเกินนั้นออก

.ie7 form li {
  width:100%;
  overflow:hidden;
}

.ie7 input {
  width:100%;
}

1

แทนที่จะต่อสู้กับมาร์จิ้นนี้

input{
    width:100%;
    background:transparent !important;
}

วิธีนี้จะมองเห็นเส้นขอบเซลล์และคุณสามารถควบคุมสีพื้นหลังของแถวได้


0

นำ "http://www.w3.org/TR/html4/loose.dtd" ออกจากประกาศ DOCTYPE และแก้ไขปัญหาของคุณ

ไชโย! :)


คุณหมายถึงใช้http://www.w3.org/TR/html4/strict.dtdStrict หรือเปล่า? อ้างอิง w3.org/QA/2002/04/valid-dtd-list.htmlอย่างไรก็ตามนี่ไม่ใช่ตัวเลือกที่ทำให้การเปลี่ยน DOCTYPE ในตอนนี้อาจส่งผลกระทบต่อการแสดงผลของ stuf อื่น ๆ ในหน้าเว็บ
Marco Demaio

0

ด้วย Javascript บางตัวคุณจะได้รับความกว้างที่แน่นอนของ TD ที่มีอยู่แล้วกำหนดให้กับองค์ประกอบอินพุตโดยตรง

ต่อไปนี้เป็น javascript ดิบ แต่ jQuery จะทำให้สะอาดกว่า ...

var inputs = document.getElementsByTagName('input');
for (var i = 0; i < inputs.length; i++)
{
    var el = inputs[i];
    if (el.style.width == '100%')
    {
        var pEl = el.parentNode;  // Assumes the parent node is the TD...
        el.style.width = pEl.offsetWidth;
    }
}

ปัญหาในการแก้ปัญหานี้คือ:

1) หากคุณมีอินพุตของคุณอยู่ในองค์ประกอบอื่นเช่น SPAN คุณจะต้องวนซ้ำและค้นหา TD เนื่องจากองค์ประกอบเช่น SPAN จะห่ออินพุตและแสดงขนาดแทนที่จะถูก จำกัด ไว้ที่ขนาดของ TD

2) หากคุณมีการเพิ่มช่องว่างภายในหรือระยะขอบในระดับที่แตกต่างกันคุณอาจต้องลบออกจาก [pEl.offsetWidth] อย่างชัดเจน ขึ้นอยู่กับโครงสร้าง HTML ของคุณที่สามารถคำนวณได้

3) หากคอลัมน์ของตารางมีขนาดแบบไดนามิกการเปลี่ยนขนาดขององค์ประกอบหนึ่งจะทำให้ตารางแสดงซ้ำในบางเบราว์เซอร์และคุณอาจได้รับเอฟเฟกต์แบบขั้นตอนเมื่อคุณ "แก้ไข" ขนาดอินพุตตามลำดับ วิธีแก้ปัญหาคือการกำหนดความกว้างเฉพาะให้กับคอลัมน์เป็นเปอร์เซ็นต์หรือพิกเซลหรือรวบรวมความกว้างใหม่และตั้งค่าหลังจากนั้น ดูโค้ดด้านล่าง ..

var inputs = document.getElementsByTagName('input');
var newSizes = [];
for (var i = 0; i < inputs.length; i++)
{
    var el = inputs[i];
    if (el.style.width == '100%')
    {
        var pEl = el.parentNode;  // Assumes the parent node is the TD...
        newSizes.push( { el: el, width: pEl.offsetWidth });
    }
}

// Set the sizes AFTER to avoid stepping...
for (var i = 0; i < newSizes.length; i++)
{
    newSizes[i].el.style.width = newSizes[i].width;
}

0

ฉันแก้ปัญหาโดยการสมัครbox-sizing:border-box; ไปยังเซลล์ตารางเองนอกเหนือจากการทำเช่นเดียวกันกับอินพุตและกระดาษห่อหุ้ม



-1

ฉันมักจะตั้งค่าความกว้างของอินพุตเป็น 99% เพื่อแก้ไขสิ่งนี้:

input {
    width: 99%;
}

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

input {
    width: 100%;
    border-width: 0;
    margin: 0;
    padding: 0;
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
}

แอด @ ม


-2

ปัญหาอยู่ที่border-widthองค์ประกอบอินพุต ไม่นานลองตั้งค่าขององค์ประกอบการป้อนข้อมูลเพื่อmargin-left-2px

table input {
  margin-left: -2px;
}

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