Kotak teks input HTML dengan lebar 100% meluap sel tabel

106

Adakah yang tahu mengapa elemen input dengan lebar 100% melewati batas sel tabel.

Dalam contoh sederhana di bawah kotak input melewati batas sel tabel, hasilnya mengerikan. Ini telah diuji dan terjadi dengan cara yang sama di: Firefox, IE7 dan Safari.

Apakah ini masuk akal untuk Anda? Apakah saya melewatkan sesuatu, apakah Anda tahu tentang solusi yang mungkin?

<!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>
Marco Demaio
sumber
1
Saya menyarankan bahwa, jika Anda hanya menggunakan tabel untuk menyajikan input, Anda dapat beralih menggunakan a formdengan labels dan inputs di dalam ulatau ol. yaitu, setidaknya sedikit lebih semantik. Tentu saja, Anda harus menggunakan form, meskipun Anda tetap menggunakan file table.
David mengatakan mengembalikan Monica

Jawaban:

216

Anda dapat menggunakan box-sizingproperti CSS3 untuk menyertakan padding dan batas eksternal:

input[type="text"] {
     width: 100%; 
     box-sizing: border-box;
     -webkit-box-sizing:border-box;
     -moz-box-sizing: border-box;
}
pricco
sumber
1
Sedih untuk dikatakan tetapi sayangnya IE 7 tidak menangani ukuran kotak dengan benar. Coba yang berikut ini di IE 7 ... css3.info/preview/box-sizing atau lihat css-tricks.com/box-sizing
AnthonyVO
@AnthonyVO: benar, satu-satunya solusi untuk IE7 adalah menambahkan CSS khusus untuk itu menggunakan komentar bersyarat IE <!--[if lt IE 8]>daninput[type="text"] {width:95%}
Marco Demaio
24

Nilai lebar tidak memperhitungkan batas atau bantalan akun:

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

Anda mendapatkan 2px padding di setiap sisi, ditambah 1px perbatasan di setiap sisi.
100% + 2 * (2px + 1px) = 100% + 6px, yang lebih dari 100% konten anak yang dimiliki td induk.

Anda memiliki pilihan untuk:

  • Baik pengaturan box-sizing: border-box;sesuai jawaban @ pricco ;
  • Atau menggunakan 0 margin dan padding (menghindari ukuran ekstra).
ANeves
sumber
lebih lanjut ke jawaban pts Sr Anda dapat mengatur padding dan perbatasan ke 0px maka 100% harus bekerja.
Mauro
Memang, bahkan tanpa mengatur padding untuk td - ditambahkan dengan sangat baik.
ANeves
1
Selain itu, jika padding menimbulkan masalah, mungkin saja digunakan text-indentuntuk mensimulasikan padding di depan tepi terdepan teks, dan line-heightuntuk padding vertikal (meskipun mempertahankan padding vertikal tidak akan memengaruhi lebarnya).
David mengatakan mengembalikan Monica
14

Masalah dengan hal-hal seperti itu width:95%;adalah mereka tidak terlihat benar dalam tata letak fleksibel yang lebar (karena 5% kemudian bisa seperti 30 piksel).

Solusi berikut berfungsi dengan sangat baik untuk saya (diuji di 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>

(menambahkan warna agar lebih mudah melihat padding yang benar)

Triknya adalah untuk membungkus input dengan dua div, bagian luar memiliki margin 3px (yang membuatnya lebih kecil 3px dari td), bagian dalam memiliki bantalan 3px. Ini membuat input 6px lebih kecil dari td, yang Anda ingin mulai.

Saya tidak yakin tentang mekanisme ini, tetapi berhasil.

Dalam contoh sederhana ini, ini juga bekerja hanya dengan satu div dengan margin kanan 6. Namun, dalam kasus aplikasi web saya, hanya solusi di atas yang berfungsi.

<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>
Andreas
sumber
Ini berfungsi (diberi suara positif +1). Anehnya, saya memasukkan beberapa teks sebelum masing-masing <input> dan menambahkan "white-space: nowrap" agar tetap di baris yang sama, lalu tiga <inputs> memenuhi sel tabel, jika saya menghapus "white-space: nowrap" semuanya bekerja lagi. Aneh.
Jose Manuel Abarca Rodríguez
8

Masalahnya telah dijelaskan sebelumnya jadi saya hanya akan mengulangi: lebar tidak memperhitungkan batas dan bantalan. Satu kemungkinan jawaban untuk ini tidak dibahas tetapi yang saya temukan membantu saya adalah dengan membungkus masukan Anda. Inilah kodenya, dan saya akan menjelaskan bagaimana ini membantu sebentar lagi:

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

DIV yang membungkus INPUT tidak memiliki bantalan dan juga tidak memiliki batas. Inilah solusinya. DIV akan meluas ke ukuran wadahnya, tetapi juga akan menghormati batas dan bantalan. Sekarang, INPUT tidak akan mengalami masalah dalam memperluas ukuran penampungnya karena tidak memiliki batas dan tanpa bantalan. Perhatikan juga bahwa DIV memiliki overflow yang disetel ke tersembunyi. Tampaknya secara default, item dapat berada di luar penampungnya dengan luapan default terlihat. Ini hanya memastikan bahwa input tetap berada di dalam penampungnya dan tidak mencoba untuk masuk.

Saya telah menguji ini di Chrome dan di Fire Fox. Keduanya tampaknya menghargai solusi ini dengan baik.

UPDATE : Karena saya baru saja mendapat downvote acak, saya ingin mengatakan bahwa cara yang lebih baik untuk menangani overflow adalah dengan atribut ukuran kotak CSS3 seperti yang dijelaskan oleh 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;
}

Ini tampaknya didukung dengan cukup baik oleh browser utama dan tidak "hacky" seperti trik overflow. Namun, ada beberapa masalah kecil pada browser saat ini dengan pendekatan ini (lihat http://caniuse.com/#search=box-sizing Masalah yang Diketahui).

David Peterson
sumber
3
Catatan singkat: dengan overflow: hidden;konten yang masih 'menonjol' ke luar kotak dengan cara yang persis sama, tetapi terpotong alih-alih ditampilkan - sehingga tidak tumpang tindih dengan konten lain.
ANeves
2

Saya tahu bahwa pertanyaan ini sudah berumur 3 tahun tetapi masalah masih berlanjut untuk browser saat ini dan orang-orang masih datang ke sini. Solusi untuk saat ini adalah calc () :

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

Ini didukung oleh sebagian besar browser modern.

trojan
sumber
1

Masalahnya adalah karena model kotak elemen masukan. Saya baru-baru ini menemukan solusi yang bagus untuk masalah ini ketika mencoba menjaga masukan saya 100% untuk perangkat seluler.

Bungkus masukan Anda dengan elemen lain, div misalnya. Kemudian terapkan gaya yang Anda inginkan untuk masukan Anda ke div pembungkus itu. Sebagai contoh:

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

Berikan .input-wrapper rounded corner padding dll, apapun yang anda inginkan untuk masukan anda, kemudian berikan lebar masukan 100%. Anda memiliki masukan Anda yang dilapisi dengan baik dengan perbatasan dll tetapi tanpa luapan yang mengganggu!

hallodom.dll
sumber
1

Saya memperbaiki masalah ini dimulai dengan jawaban @ hallodom. Semua input saya terkandung dalam li, jadi yang harus saya lakukan hanyalah mengatur li overflow: hidden untuk menghilangkan kelebihan input overflow.

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

.ie7 input {
  width:100%;
}
chet
sumber
1

alih-alih perjuangan margin ini lakukan saja

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

dengan cara ini batas sel terlihat dan Anda dapat mengontrol warna latar belakang baris

bortunac.dll
sumber
0

Keluarkan "http://www.w3.org/TR/html4/loose.dtd" dari deklarasi DOCTYPE dan itu memperbaiki masalah Anda.

Bersulang! :)

Lucian
sumber
Apakah yang Anda maksud menggunakan http://www.w3.org/TR/html4/strict.dtdKetat? ref. w3.org/QA/2002/04/valid-dtd-list.html Bagaimanapun, ini bukan pilihan karena mengubah DOCTYPE sekarang mungkin akan berdampak pada rendering banyak stuf lainnya di halaman web.
Marco Demaio
0

Dengan beberapa Javascript Anda bisa mendapatkan lebar yang tepat dari TD yang mengandung dan kemudian menetapkannya langsung ke elemen input.

Berikut ini adalah javascript mentah tetapi jQuery akan membuatnya lebih bersih ...

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

Masalah dengan solusi ini adalah:

1) Jika Anda memiliki input yang terkandung dalam elemen lain seperti SPAN maka Anda perlu melakukan loop up dan menemukan TD karena elemen seperti SPAN akan membungkus input dan menunjukkan ukurannya daripada dibatasi pada ukuran TD.

2) Jika Anda memiliki padding atau margin yang ditambahkan pada level yang berbeda, maka Anda mungkin harus menguranginya secara eksplisit dari [pEl.offsetWidth]. Bergantung pada struktur HTML Anda yang dapat dihitung.

3) Jika kolom tabel berukuran dinamis, maka mengubah ukuran satu elemen akan menyebabkan tabel mengalir ulang di beberapa browser dan Anda mungkin mendapatkan efek bertahap saat Anda "memperbaiki" ukuran input secara berurutan. Solusinya adalah dengan menetapkan lebar tertentu ke kolom baik sebagai persentase atau piksel ATAU mengumpulkan lebar baru dan mengaturnya setelahnya. Lihat kode di bawah ini ..

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;
}
AnthonyVO
sumber
0

Saya memecahkan masalah dengan menerapkan box-sizing:border-box; ke sel tabel itu sendiri, selain melakukan hal yang sama dengan input dan pembungkusnya.

Vanco
sumber
0

Saya memecahkan masalah dengan menggunakan ini

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;
}
Kevin Muchwat
sumber
-1

Saya biasanya mengatur lebar input saya menjadi 99% untuk memperbaiki ini:

input {
    width: 99%;
}

Anda juga dapat menghapus gaya default, tetapi itu akan membuatnya kurang jelas bahwa itu adalah kotak teks. Namun, saya akan menunjukkan kode untuk itu:

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

Iklan @ m

kirb
sumber
-2

Masalahnya terletak pada border-widthelemen masukan. Singkatnya, coba setel margin-leftdari elemen masukan ke -2px.

table input {
  margin-left: -2px;
}
burek pekaric
sumber
tidak berpikir begitu. yang hanya menggeser kotak ke kiri dan menghancurkan margin kiri
cc muda