Hộp văn bản đầu vào HTML có chiều rộng 100% tràn các ô trong bảng


106

Có ai biết tại sao các phần tử đầu vào có chiều rộng 100% đi qua đường viền ô của bảng không.

Trong ví dụ đơn giản dưới đây, hộp nhập liệu đi qua đường viền ô của bảng, kết quả thật kinh khủng. Điều này đã được thử nghiệm và nó xảy ra theo cách tương tự trên: Firefox, IE7 và Safari.

Nó có ý nghĩa với bạn không? Tôi đang thiếu một cái gì đó, bạn có biết về một giải pháp khả thi?

<!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
Tôi đề nghị rằng, nếu bạn chỉ sử dụng một bảng để trình bày các đầu vào, bạn có thể chuyển sang sử dụng a formvới các labels và inputs bên trong a ulhoặc ol. nghĩa là, ít nhất là ngữ nghĩa hơn một chút. Mặc dù vậy, chắc chắn bạn nên sử dụng một form, ngay cả khi bạn gắn bó với table.
David nói hãy phục hồi Monica vào ngày

Câu trả lời:


216

Bạn có thể sử dụng thuộc tính CSS3 box-sizingđể bao gồm phần đệm và đường viền bên ngoài:

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

1
Rất tiếc phải nói nhưng rất tiếc là IE 7 không xử lý đúng kích thước hộp. Hãy thử cách sau trong IE 7 ... css3.info/preview/box-sizing hoặc xem css-tricks.com/box-sizing
AnthonyVO

@AnthonyVO: đúng, thực hiện giải pháp duy nhất cho IE7 là thêm CSS cụ thể cho nó sử dụng IE bình luận có điều kiện <!--[if lt IE 8]>input[type="text"] {width:95%}
Marco Demaio

24

Giá trị chiều rộng không tính đến đường viền hoặc phần đệm:

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

Bạn nhận được 2px đệm ở mỗi bên, cộng với 1px đường viền ở mỗi bên.
100% + 2 * (2px + 1px) = 100% + 6px, nhiều hơn 100% nội dung con mà td gốc có.

Bạn có tùy chọn:


xa hơn với câu trả lời của Sr pts, bạn có thể đặt padding và border thành 0px thì 100% sẽ hoạt động.
Mauro

Thật vậy, ngay cả khi không đặt bất kỳ phần đệm nào cho td - rất tốt được thêm vào.
ANeves ngày

1
Ngoài ra, nếu phần đệm gây ra sự cố, bạn có thể sử dụng text-indentđể mô phỏng phần đệm phía trước mép trước của văn bản và line-heightcho phần đệm dọc (mặc dù việc giữ lại phần đệm dọc sẽ không ảnh hưởng đến chiều rộng).
David nói hãy phục hồi Monica vào ngày

14

Vấn đề với những thứ như vậy width:95%;là chúng trông không đúng trong các bố cục linh hoạt rộng (vì 5% khi đó có thể giống như 30 pixel).

Các giải pháp sau hoạt động rất tốt đối với tôi (được thử nghiệm trên 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>

(đã thêm màu sắc để dễ dàng nhận thấy phần đệm chính xác)

Bí quyết là quấn đầu vào bằng hai div, bên ngoài có lề 3px (làm cho nó nhỏ hơn 3px so với td), bên trong có đệm 3px. Điều này làm cho đầu vào nhỏ hơn 6px so với td, đó là những gì bạn muốn bắt đầu.

Tôi không chắc về cơ chế của việc này, nhưng nó hoạt động.

Trong ví dụ đơn giản này, nó cũng hoạt động chỉ với một div duy nhất với lề phải 6. Tuy nhiên, trong trường hợp ứng dụng web của tôi, chỉ có giải pháp trên hoạt động.

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

Nó hoạt động (+1). Thật kỳ lạ, tôi đã chèn một số văn bản trước mỗi <input> và thêm "white-space: nowrap" để giữ chúng trên cùng một dòng, sau đó ba <inputs> làm tràn các ô trong bảng, nếu tôi xóa "white-space: nowrap" thì mọi thứ hoạt động trở lại. Kỳ dị.
Jose Manuel Abarca Rodríguez

8

Vấn đề đã được giải thích trước đó vì vậy tôi sẽ chỉ nhắc lại: chiều rộng không tính đến đường viền và phần đệm. Một câu trả lời có thể cho điều này không được thảo luận nhưng tôi đã tìm thấy đã giúp tôi ra một loạt là gói đầu vào của bạn. Đây là mã và tôi sẽ giải thích cách điều này giúp ích trong giây lát:

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

DIV bao bọc INPUT không có phần đệm cũng như không có đường viền. Đây là giải pháp. DIV sẽ mở rộng đến kích thước của vùng chứa, nhưng nó cũng sẽ tuân theo đường viền và phần đệm. Bây giờ, INPUT sẽ không có vấn đề gì khi mở rộng đến kích thước của vùng chứa vì nó không có viền và không có đệm. Cũng lưu ý rằng DIV có phần tràn của nó được đặt thành ẩn. Có vẻ như theo mặc định, các mục có thể nằm ngoài vùng chứa của chúng với phần tràn mặc định hiển thị. Điều này chỉ đảm bảo rằng đầu vào vẫn ở bên trong vùng chứa của nó và không cố gắng chọc thủng.

Tôi đã thử nghiệm điều này trong Chrome và trong Fire Fox. Cả hai dường như tôn trọng tốt giải pháp này.

CẬP NHẬT : Vì tôi vừa nhận được một phiếu phản đối ngẫu nhiên, tôi muốn nói rằng cách tốt hơn để đối phó với tình trạng tràn là sử dụng thuộc tính kích thước hộp CSS3 như được mô tả bởi 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;
}

Điều này dường như được hỗ trợ khá tốt bởi các trình duyệt chính và không "hacky" như thủ thuật tràn. Tuy nhiên, có một số vấn đề nhỏ trên các trình duyệt hiện tại với cách tiếp cận này (xem http://caniuse.com/#search=box-sizing Sự cố đã biết).


3
Một lưu ý ngắn: với overflow: hidden;nội dung vẫn 'xuyên qua' ra bên ngoài hộp theo đúng cách, nhưng nó được cắt bớt thay vì được hiển thị - vì vậy nó không chồng chéo nội dung khác.
ANeves

2

Tôi biết rằng câu hỏi này đã được 3 năm nhưng vấn đề vẫn còn tồn tại đối với các trình duyệt hiện tại và mọi người vẫn đang đến đây. Giải pháp cho bây giờ là calc () :

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

Nó được hỗ trợ bởi hầu hết các trình duyệt hiện đại.


1

Vấn đề là do mô hình hộp phần tử đầu vào. Gần đây, tôi đã tìm thấy một giải pháp tốt cho vấn đề khi cố gắng giữ đầu vào của mình ở mức 100% cho các thiết bị di động.

Kết hợp đầu vào của bạn bằng một phần tử khác, ví dụ như div. Sau đó, áp dụng kiểu bạn muốn cho đầu vào của bạn cho div trình bao bọc đó. Ví dụ:

<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;
}

Cung cấp phần đệm góc tròn .input-wrapper, v.v., bất kỳ thứ gì bạn muốn cho đầu vào của mình, sau đó cung cấp 100% chiều rộng đầu vào. Bạn có đầu vào của mình được đệm độc đáo với đường viền, v.v. nhưng không bị tràn gây phiền nhiễu!


1

Tôi đã khắc phục sự cố này bắt đầu bằng câu trả lời của @ hallodom. Tất cả các đầu vào của tôi được chứa trong li's, vì vậy tất cả những gì tôi phải làm là thiết lập tràn li: ẩn để nó loại bỏ tràn đầu vào dư thừa đó.

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

.ie7 input {
  width:100%;
}

1

thay vì đấu tranh lợi nhuận này, chỉ cần làm

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

theo cách này, đường viền ô hiển thị và bạn có thể kiểm soát màu nền của hàng


0

Lấy ra "http://www.w3.org/TR/html4/loose.dtd" từ khai báo DOCTYPE và nó khắc phục được sự cố của bạn.

Chúc mừng! :)


Ý bạn là sử dụng http://www.w3.org/TR/html4/strict.dtdNghiêm ngặt? giới thiệu w3.org/QA/2002/04/valid-dtd-list.html Dù sao đây không phải là một tùy chọn vì việc thay đổi DOCTYPE bây giờ có thể sẽ ảnh hưởng đến việc hiển thị nhiều stuf khác trong các trang web.
Marco Demaio

0

Với một số Javascript, bạn có thể lấy chiều rộng chính xác của TD chứa và sau đó gán trực tiếp cho phần tử đầu vào.

Sau đây là javascript thô nhưng jQuery sẽ làm cho nó sạch hơn ...

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;
    }
}

Các vấn đề với giải pháp này là:

1) Nếu bạn có đầu vào của mình chứa trong một phần tử khác như SPAN thì bạn sẽ cần lặp lại và tìm TD vì các phần tử như SPAN sẽ bao bọc đầu vào và hiển thị kích thước của nó thay vì bị giới hạn ở kích thước của TD.

2) Nếu bạn có thêm khoảng đệm hoặc lề ở các cấp khác nhau thì bạn có thể phải trừ rõ ràng nó khỏi [pEl.offsetWidth]. Tùy thuộc vào cấu trúc HTML của bạn mà có thể được tính toán.

3) Nếu các cột trong bảng được định kích thước động thì việc thay đổi kích thước của một phần tử sẽ khiến bảng điều chỉnh lại trong một số trình duyệt và bạn có thể nhận được hiệu ứng từng bước khi liên tục "sửa" các kích thước đầu vào. Giải pháp là chỉ định độ rộng cụ thể cho cột dưới dạng phần trăm hoặc pixel HOẶC thu thập độ rộng mới và đặt chúng sau đó. Xem mã bên dưới ..

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

Tôi đã giải quyết vấn đề bằng cách áp dụng box-sizing:border-box; với chính các ô trong bảng, ngoài việc thực hiện tương tự với đầu vào và trình bao bọc.


0

Tôi đã giải quyết vấn đề bằng cách sử dụng cái này

tr td input[type=text] {
  width: 100%;
  box-sizing: border-box;
  -webkit-box-sizing:border-box;
  -moz-box-sizing: border-box;
  background:transparent !important;
  border: 0px;
}

-1

Tôi thường đặt chiều rộng của đầu vào là 99% để khắc phục điều này:

input {
    width: 99%;
}

Bạn cũng có thể xóa các kiểu mặc định, nhưng điều đó sẽ làm cho nó ít rõ ràng hơn rằng đó là một hộp văn bản. Tuy nhiên, tôi sẽ hiển thị mã cho điều đó bằng cách nào:

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

Ad @ m


-2

Vấn đề nằm ở border-widthyếu tố đầu vào. Trong thời gian ngắn, hãy thử đặt margin-leftphần tử đầu vào thành -2px.

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

đừng nghĩ vậy. mà chỉ cần thay đổi hộp sang trái và phá hủy lề trái
cc trẻ
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.