Berbatasan dengan baris tertentu dalam tabel?

120

Saya mencoba mendesain beberapa HTML / CSS yang dapat memberi batas di sekitar baris tertentu dalam tabel. Ya, saya tahu saya tidak seharusnya menggunakan tabel untuk tata letak tetapi saya belum cukup tahu CSS untuk menggantikannya sepenuhnya.

Bagaimanapun, saya memiliki tabel dengan beberapa baris dan kolom, beberapa digabungkan dengan rowpan dan colspan, dan saya ingin membuat batas sederhana di sekitar bagian tabel. Saat ini, saya menggunakan 4 kelas CSS terpisah (atas, bawah, kiri, kanan) yang saya lampirkan ke <td>sel yang masing-masing berada di sepanjang bagian atas, bawah, kiri, dan kanan tabel.

.top {
  border-top: thin solid;
  border-color: black;
}

.bottom {
  border-bottom: thin solid;
  border-color: black;
}

.left {
  border-left: thin solid;
  border-color: black;
}

.right {
  border-right: thin solid;
  border-color: black;
}
<html>

<body>

  <table cellspacing="0">
    <tr>
      <td>no border</td>
      <td>no border here either</td>
    </tr>
    <tr>
      <td class="top left">one</td>
      <td class="top right">two</td>
    </tr>
    <tr>
      <td class="bottom left">three</td>
      <td class="bottom right">four</td>
    </tr>
    <tr>
      <td colspan="2">once again no borders</td>
    </tr>
    <tr>
      <td class="top bottom left right" colspan="2">hello</td>
    </tr>
    <tr>
      <td colspan="2">world</td>
    </tr>
  </table>

</html>

Adakah cara yang lebih mudah untuk melakukan apa yang saya inginkan? Saya mencoba menerapkan atas dan bawah ke a <tr>tetapi tidak berhasil. (ps Saya baru mengenal CSS, jadi mungkin ada solusi yang sangat mendasar untuk ini yang saya lewatkan.)

catatan: Saya memang perlu memiliki beberapa bagian yang dibatasi. Ide dasarnya adalah memiliki beberapa cluster berbatasan yang masing-masing berisi beberapa baris.

Kyle Cronin
sumber
9
Di luar topik tetapi saya hanya ingin mengatakan, tabel sangat sesuai dan direkomendasikan saat menampilkan data tabel ...
md1337

Jawaban:

114

Bagaimana dengan tr {outline: thin solid black;}? Bekerja untuk saya pada elemen tr atau tbody, dan tampaknya kompatibel dengan sebagian besar browser, termasuk IE 8+, tetapi tidak sebelumnya.

teka-teki
sumber
Saya bertanya tentang menempatkan satu perbatasan di sekitar beberapa baris dalam sebuah tabel, pada dasarnya membaginya secara visual menjadi beberapa bagian tetapi dalam tabel yang sama sehingga barang-barang dari bagian yang berbeda akan sejajar.
Kyle Cronin
3
Dimengerti, saya membutuhkan itu juga. Lampirkan set baris yang Anda ingin tepinya di dalam tbodynya sendiri, dan css di atas akan membuat batas di sekitar setnya - yaitu, batas atas di baris atas, batas bawah di baris bawah, dan kiri dan batas kanan pada semua baris di tubuh. Perbatasan sebenarnya tidak "pada" baris itu, melainkan pada garis luar tubuh itu sendiri, hanya mencoba untuk mendeskripsikan efeknya.
enigment
Oh, begitu, banyak anak perempuan - itu berfungsi, dan merupakan sesuatu yang belum saya pertimbangkan. Suara positif :)
Kyle Cronin
Saya akan menyarankan menggunakan properti css nth-child () daripada mendefinisikan tbodys kecuali Anda benar-benar memiliki beberapa data yang cukup dinamis. Dengan menggunakan nth-child (), nth-last-child (), dan bukan (), Anda dapat memilih baris / sel apa pun yang Anda inginkan (selama Anda mengetahui indeks relatif hal-hal dalam tabel). Misalnya, Anda dapat memilih semua baris kecuali dua baris teratas dan baris terbawah dengan tr: not (: nth-child (-n + 2)): not (: nth-last-child (1))
BT
1
Perhatikan bahwa garis besar tidak memiliki kemungkinan untuk membatasi sisi tertentu dari suatu elemen. Tidak ada "outline-top" misalnya. Ini adalah solusi terbatas
BT
53

Terima kasih untuk semua yang telah menanggapi! Saya telah mencoba semua solusi yang disajikan di sini dan saya telah melakukan lebih banyak pencarian di internet untuk solusi lain yang memungkinkan, dan saya rasa saya telah menemukan satu yang menjanjikan:

tr.top td {
  border-top: thin solid black;
}

tr.bottom td {
  border-bottom: thin solid black;
}

tr.row td:first-child {
  border-left: thin solid black;
}

tr.row td:last-child {
  border-right: thin solid black;
}
<html>

<head>
</head>

<body>

  <table cellspacing="0">
    <tr>
      <td>no border</td>
      <td>no border here either</td>
    </tr>
    <tr class="top row">
      <td>one</td>
      <td>two</td>
    </tr>
    <tr class="bottom row">
      <td>three</td>
      <td>four</td>
    </tr>
    <tr>
      <td colspan="2">once again no borders</td>
    </tr>
    <tr class="top bottom row">
      <td colspan="2">hello</td>
    </tr>
    <tr>
      <td colspan="2">world</td>
    </tr>
  </table>

</body>

</html>

Keluaran:

masukkan deskripsi gambar di sini

Daripada harus menambahkan top, bottom, left, dan rightkelas untuk setiap <td>, semua harus saya lakukan adalah menambahkan top rowke atas <tr>, bottom rowke bawah <tr>, dan rowuntuk setiap <tr>di antara. Apakah ada yang salah dengan solusi ini? Apakah ada masalah lintas platform yang harus saya ketahui?

Kyle Cronin
sumber
Baru saja menjalankan tes melalui screenshot browser dan sepertinya IE (semua versi) tidak menyukai atribut anak pertama dan anak terakhir. : - /
Kyle Cronin
1
Sepertinya IE 7 & 8 mendukung first-child, tetapi tidak ada yang mendukung last-child (!) Msdn.microsoft.com/en-us/library/cc351024(VS.85).aspx
mechanical_meat
The cellspacingatribut usang dalam HTML5. Sepertinya CSS table { border-collapse: collapse; border-spacing: 0; }adalah cara yang harus dilakukan sekarang.
Stefan van den Akker
36

Jika Anda menyetel border-collapsegaya ke collapsepada tabel induk, Anda harus bisa memberi gaya tr: (gaya sebaris untuk demo)

<table style="border-collapse: collapse;">
  <tr>
    <td>No Border</td>
  </tr>
  <tr style="border:2px solid #f00;">
    <td>Border</td>
  </tr>
  <tr>
    <td>No Border</td>
  </tr>
</table>

Keluaran:

Keluaran HTML

Matahari terbit
sumber
8

Saya hanya bermain-main dengan melakukan ini juga, dan ini sepertinya pilihan terbaik bagi saya:

<style>
    tr { 
        display: table;            /* this makes borders/margins work */
        border: 1px solid black;
        margin: 5px;
    }
</style>

Perhatikan bahwa ini akan mencegah penggunaan lebar kolom yang dapat menyesuaikan / otomatis , karena sel tidak lagi sejajar dengan yang ada di baris lain, tetapi pemformatan batas / warna masih berfungsi dengan baik. Solusinya adalah memberi TR dan TDs lebar yang ditentukan (baik px atau%).

Tentu saja Anda bisa membuat selektor tr.myClassjika ingin menerapkannya hanya pada baris tertentu. Namun, tampaknya display: tabletidak berfungsi untuk IE 6/7, tetapi mungkin ada peretasan lain (hasLayout?) Yang mungkin berhasil untuk itu. :-(

Simon Timur
sumber
6
Solusi ini salah: "display: table" menempatkan seluruh baris ke dalam satu sel tabel --- Anda kehilangan pemformatan sehubungan dengan baris lain pada tabel. Saya mencoba ini di Firefox dan Chromium.
Yaakov Belch
Yaakov, menurut saya yang Anda maksud adalah lebar kolom yang berubah-ubah tidak lagi sejajar dengan baris lain dalam tabel (seperti yang terlihat di biola ini: jsfiddle.net/MrKtw ) tetapi pemformatan batas / warna masih berfungsi dengan baik. Solusinya adalah memberi TR dan TDs lebar yang ditentukan (baik px atau%).
Simon East
Simon, untuk menunjukkan maksudku, aku bercabang dan mengganti biolamu. Lihat ini: jsfiddle.net/a6DZV --- Saya menerapkan format "display: table" hanya ke satu baris. Seperti yang Anda lihat, ini mengubah baris ini secara efektif menjadi satu sel tabel. Dengan kata lain: Anda mendapatkan output yang sama dengan menumpuk tabel satu baris di dalam sel tabel lain (dan memperlihatkan batas tabel dalam ini). Solusi Anda menyimpan beberapa node di DOM tetapi tidak kompatibel.
Yaakov Belch
3

Berikut pendekatan menggunakan elemen tbody yang bisa menjadi cara untuk melakukannya. Anda tidak dapat mengatur border pada tbody (sama seperti pada tr) tetapi Anda dapat mengatur warna latar belakang. Jika efek yang ingin Anda capai dapat diperoleh dengan warna latar belakang pada kelompok baris alih-alih batas, ini akan berfungsi.

<table cellspacing="0">  
    <tbody>
        <tr>    
            <td>no border</td>    
            <td>no border here either</td>  
        </tr>  
    <tbody bgcolor="gray">
        <tr>    
            <td>one</td>    
            <td>two</td>  
        </tr>  
        <tr>    
            <td>three</td>    
            <td>four</td>  
        </tr>  
    <tbody>
        <tr>    
             <td colspan="2">once again no borders</td>  
        </tr>  
    <tbody bgcolor="gray">
        <tr>    
             <td colspan="2">hello</td>  
        </tr>
    <tbody>
    <tr>    
         <td colspan="2">world</td>  
    </tr>
</table>
sipwiz
sumber
2

Kelompokkan baris bersama-sama menggunakan <tbody>tag dan kemudian terapkan gaya.

<table>
  <tr><td>No Style here</td></tr>
  <tbody class="red-outline">
    <tr><td>Style me</td></tr>
    <tr><td>And me</td></tr>
  </tbody>
  <tr><td>No Style here</td></tr>
</table>  

Dan css di style.css

.red-outline {
  outline: 1px solid red;
}
csi
sumber
1

Satu-satunya cara lain yang dapat saya pikirkan untuk melakukannya adalah dengan melampirkan setiap baris yang Anda perlukan batasnya dalam tabel bersarang. Itu akan membuat perbatasan lebih mudah dilakukan tetapi berpotensi menimbulkan masalah tata letak lainnya, Anda harus mengatur lebar secara manual pada sel tabel, dll.

Pendekatan Anda mungkin yang terbaik tergantung pada persyaratan tata letak Anda yang lain dan pendekatan yang disarankan di sini hanyalah kemungkinan alternatif.

<table cellspacing="0">  
    <tr>    
        <td>no border</td>    
        <td>no border here either</td>  
    </tr>  
    <tr>
        <td>
             <table style="border: thin solid black">
                  <tr>    
                        <td>one</td>    
                        <td>two</td>  
                  </tr>  
                  <tr>    
                      <td>three</td>    
                      <td>four</td>  
                  </tr>  
             </table>
         </td>
    </tr>
    <tr>    
         <td colspan="2">once again no borders</td>  
    </tr>  
    <tr>
        <td>
             <table style="border: thin solid black">
                  <tr>    
                        <td>hello</td>  
                   </tr>
             </table>
         </td>
    </tr>
    <tr>    
         <td colspan="2">world</td>  
    </tr>
</table>
sipwiz
sumber
Terima kasih atas jawaban anda; Anda benar tentang masalah tata letak - saya lebih suka kolom berbaris tanpa melakukannya dengan tangan. Bagaimana dengan menerapkan kelas ke tag <tr> - apakah itu mungkin?
Kyle Cronin
Jika Anda menggunakan tabel dengan "table-layout: fixed" dan secara eksplisit mengatur lebar setiap kolom (dengan menggunakan <col> atau hanya mengatur lebar sel di baris pertama), kolom akan berbaris terlepas dari kontennya. Anda bahkan tidak perlu menumpuk tabel, tiga tabel terpisah sudah cukup untuk dijadikan contoh.
bobince
1

Berdasarkan kebutuhan Anda bahwa Anda ingin meletakkan perbatasan di sekitar blok sembarang sel MxN, sebenarnya tidak ada cara yang lebih mudah untuk melakukannya tanpa menggunakan Javascript. Jika sel Anda diperbaiki, Anda dapat menggunakan pelampung tetapi ini bermasalah karena alasan lain. apa yang Anda lakukan mungkin membosankan tetapi tidak apa-apa.

Oke, jika Anda tertarik dengan solusi Javascript, menggunakan jQuery (pendekatan pilihan saya), Anda akan mendapatkan potongan kode yang cukup menakutkan ini:

<html>
<head>

<style type="text/css">
td.top { border-top: thin solid black; }
td.bottom { border-bottom: thin solid black; }
td.left { border-left: thin solid black; }
td.right { border-right: thin solid black; }
</style>
<script type="text/javascript" src="jquery-1.3.1.js"></script>
<script type="text/javascript">
$(function() {
  box(2, 1, 2, 2);
});

function box(row, col, height, width) {
  if (typeof height == 'undefined') {
    height = 1;
  }
  if (typeof width == 'undefined') {
    width = 1;
  }
  $("table").each(function() {
    $("tr:nth-child(" + row + ")", this).children().slice(col - 1, col + width - 1).addClass("top");
    $("tr:nth-child(" + (row + height - 1) + ")", this).children().slice(col - 1, col + width - 1).addClass("bottom");
    $("tr", this).slice(row - 1, row + height - 1).each(function() {
      $(":nth-child(" + col + ")", this).addClass("left");
      $(":nth-child(" + (col + width - 1) + ")", this).addClass("right");
    });
  });
}
</script>
</head>
<body>

<table cellspacing="0">
  <tr>
    <td>no border</td>
    <td>no border here either</td>
  </tr>
  <tr>
    <td>one</td>
    <td>two</td>
  </tr>
  <tr>
    <td>three</td>
    <td>four</td>
  </tr>
  <tr>
    <td colspan="2">once again no borders</td>
  </tr>
</tfoot>
</table>
</html>

Saya akan dengan senang hati memberikan saran tentang cara yang lebih mudah untuk melakukan ini ...

cletus
sumber
1
Sepertinya Anda hanya menambahkan kelas ke tag td? Mengapa ini tidak dapat dilakukan dengan beberapa skrip sisi server, yang dibuat secara statis, atau kasus terburuk hanya dengan tangan? Sepertinya penyalahgunaan JavaScript bagi saya.
Thomas
3
Sebenarnya poster MEMINTA solusi Javascript. Anda tidak dapat mengatakan itu penyalahgunaan Javascript karena tidak ada informasi yang cukup. Misalnya, apakah batas ditambahkan karena mengklik yang dilakukan pengguna? Jika demikian, solusi server salah.
cletus
Mohon maaf atas kurangnya informasi. Ini akan dibuat di sisi server, jadi benar bahwa saya bisa menambahkan kelas secara manual, tapi saya suka bagaimana solusi JS menyediakan antarmuka yang lebih sederhana untuk melakukannya. Jadi sementara saya mungkin tidak akan menggunakan JS, itu adalah solusi yang baik untuk dilihat.
Kyle Cronin
0

triknya adalah dengan properti garis besar berkat jawaban enigment dengan sedikit modifikasi

gunakan kelas ini

.row-border{
    outline: thin solid black;
    outline-offset: -1px;
}

lalu di HTML

<tr>....</tr>
<tr class="row-border">
    <td>...</td>
    <td>...</td>
</tr>

dan hasilnya adalah masukkan deskripsi gambar di sini harapan ini membantu Anda

Basheer AL-MOMANI
sumber
-5

Cara yang lebih mudah adalah menjadikan tabel sebagai kontrol sisi server. Anda bisa menggunakan sesuatu yang mirip dengan ini:

Dim x As Integer
table1.Border = "1"

'Change the first 10 rows to have a black border
 For x = 1 To 10
     table1.Rows(x).BorderColor = "Black"
 Next

'Change the rest of the rows to white
 For x = 11 To 22
     table1.Rows(x).BorderColor = "White"
 Next
Curtis
sumber
1
OP meminta cara yang lebih mudah untuk melakukannya
orique
2
Hati-hati, OP juga meminta cara yang lebih mudah untuk melakukannya di HTML / CSS. Saya tidak melihat di mana pun dalam pertanyaannya kata kunci VB atau VBA. Saya sarankan Anda melihat bagian Bantuan kami: stackoverflow.com/help/how-to-answer Good Luck.
ForceMagic