Viền xung quanh các hàng cụ thể trong bảng?


120

Tôi đang cố gắng thiết kế một số HTML / CSS có thể đặt đường viền xung quanh các hàng cụ thể trong bảng. Vâng, tôi biết tôi không thực sự nên sử dụng bảng để bố trí nhưng tôi chưa biết đủ CSS để thay thế hoàn toàn nó.

Dù sao, tôi có một bảng với nhiều hàng và cột, một số được hợp nhất với rowspan và colspan, và tôi muốn đặt một đường viền đơn giản xung quanh các phần của bảng. Hiện tại, tôi đang sử dụng 4 lớp CSS riêng biệt (trên cùng, dưới cùng, trái, phải) mà tôi đính kèm vào các <td>ô dọc theo đầu, dưới, trái và phải của bảng tương ứng.

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

Có cách nào dễ dàng hơn để làm những gì tôi muốn không? Tôi đã thử áp dụng trên và dưới cho a <tr>nhưng nó không hoạt động. (ps Tôi mới làm quen với CSS, vì vậy có lẽ có một giải pháp thực sự cơ bản cho vấn đề này mà tôi đã bỏ qua.)

lưu ý: Tôi cần có nhiều phần có đường viền. Ý tưởng cơ bản là có nhiều cụm có viền, mỗi cụm có nhiều hàng.


9
Off-topic nhưng tôi chỉ muốn nói, bàn là hoàn toàn phù hợp và đề nghị khi hiển thị dữ liệu dạng bảng ...
md1337

Câu trả lời:


114

Làm thế nào về tr {outline: thin solid black;}? Hoạt động đối với tôi trên các phần tử tr hoặc tbody và có vẻ như tương thích với hầu hết các trình duyệt, bao gồm IE 8+ nhưng không phải trước đây.


Tôi đã hỏi về việc đặt một đường viền xung quanh nhiều hàng trong một bảng, về cơ bản là chia nó thành nhiều phần một cách trực quan nhưng trong cùng một bảng để nội dung từ các phần khác nhau sẽ căn chỉnh.
Kyle Cronin

3
Đã hiểu, tôi cũng cần điều đó. Bao bọc tập hợp các hàng bạn muốn có đường viền xung quanh trong thân của chúng và css ở trên sẽ tạo đường viền xung quanh tập hợp chúng - tức là đường viền trên cùng ở hàng trên cùng, đường viền dưới cùng ở hàng dưới và bên trái và các đường viền bên phải trên tất cả các hàng trong tbody. Các đường viền không thực sự nằm "trên" các hàng đó, chúng nằm trên đường viền của chính thân, chỉ đang cố gắng mô tả hiệu ứng.
enigment

Ồ, tôi hiểu rồi, nhiều tbody - điều đó hoạt động, và là thứ mà tôi đã không xem xét. Upvoted :)
Kyle Cronin

Tôi khuyên bạn nên sử dụng thuộc tính css nth-child () hơn là xác định tbody trừ khi bạn thực sự có một số dữ liệu động khá. Sử dụng nth-child (), nth-last-child (), và not (), bạn có thể chọn bất kỳ hàng / ô nào bạn muốn (miễn là bạn biết chỉ mục tương đối của những thứ trong bảng). Ví dụ: bạn có thể chọn tất cả các hàng ngoại trừ hai hàng trên cùng và dưới cùng với tr: not (: nth-child (-n + 2)): not (: nth-last-child (1))
BT

1
Lưu ý rằng phác thảo không có khả năng bao quanh các mặt cụ thể của một phần tử. Ví dụ: không có "outline-top". Đây là một giải pháp hạn chế
BT

53

Cảm ơn tất cả những gì đã phản hồi! Tôi đã thử tất cả các giải pháp được trình bày ở đây và tôi đã tìm kiếm nhiều hơn trên internet để tìm các giải pháp khả thi khác và tôi nghĩ rằng tôi đã tìm thấy một giải pháp đầy hứa hẹn:

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>

Đầu ra:

nhập mô tả hình ảnh ở đây

Thay vì phải thêm top, bottom, left, và rightcác lớp học cho mọi <td>, tất cả tôi phải làm là thêm top rowđầu trang <tr>, bottom rowxuống dưới <tr>, và rowcho tất cả <tr>ở giữa. Có gì sai với giải pháp này? Có bất kỳ vấn đề nền tảng nào mà tôi cần lưu ý không?


Vừa chạy thử nghiệm thông qua ảnh chụp trình duyệt và có vẻ như IE (tất cả các phiên bản) không thích thuộc tính con đầu và con cuối. : - /
Kyle Cronin

1
Có vẻ như IE 7 & 8 hỗ trợ con đầu tiên, nhưng không hỗ trợ con cuối cùng (!) Msdn.microsoft.com/en-us/library/cc351024(VS.85).aspx
Mechanical_meat

Các cellspacingthuộc tính bị phản đối trong HTML5. Có vẻ như CSS table { border-collapse: collapse; border-spacing: 0; }là cách để đi ngay bây giờ.
Stefan van den Akker

36

Nếu bạn đặt border-collapsekiểu thành collapsetrên bảng mẹ, bạn sẽ có thể tạo kiểu cho tr: (kiểu nằm trong dòng cho bản trình diễn)

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

Đầu ra:

Đầu ra HTML


8

Tôi cũng chỉ loanh quanh với việc làm này và đây dường như là lựa chọn tốt nhất cho tôi:

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

Lưu ý rằng điều này sẽ ngăn việc sử dụng độ rộng cột linh hoạt / tự động , vì các ô sẽ không còn căn chỉnh với các ô trong các hàng khác, nhưng định dạng đường viền / màu vẫn hoạt động OK. Giải pháp là cung cấp cho TR và TD một chiều rộng xác định (px hoặc%).

Tất nhiên, bạn có thể tạo bộ chọn tr.myClassnếu bạn chỉ muốn áp dụng nó cho một số hàng nhất định. display: tableTuy nhiên, rõ ràng là không hoạt động với IE 6/7, nhưng có thể có các bản hack khác (hasLayout?) Có thể hoạt động với những điều đó. :-(


6
Giải pháp này không chính xác: "display: table" đặt toàn bộ hàng vào một ô trong bảng --- bạn mất định dạng so với các hàng khác của bảng. Tôi đã thử điều này trong Firefox và Chromium.
Yaakov Belch

Yaakov, tôi nghĩ những gì bạn đang đề cập đến là chiều rộng cột linh hoạt không còn phù hợp với các hàng khác trong bảng (như được thấy trong fiddle: jsfiddle.net/MrKtw ) nhưng định dạng viền / màu vẫn hoạt động tốt. Giải pháp là cung cấp cho TR và TD một chiều rộng được chỉ định (px hoặc%).
Simon East

Simon, để thể hiện ý tôi muốn nói, tôi đã chia nhỏ và thay đổi trò chơi của bạn. Nhìn vào đây: jsfiddle.net/a6DZV --- Tôi áp dụng định dạng "display: table" cho chỉ một hàng. Như bạn thấy, điều này biến hàng này thành một ô của bảng. Nói cách khác: Bạn nhận được kết quả đầu ra giống như lồng các bảng một hàng bên trong một ô của bảng khác (và hiển thị đường viền của bảng bên trong này). Giải pháp của bạn lưu một vài nút trong DOM nhưng không tương thích bằng.
Yaakov Belch

3

Đây là một cách tiếp cận sử dụng các phần tử tbody có thể là cách để làm điều đó. Bạn không thể đặt viền trên tbody (giống như bạn không thể trên tr) nhưng bạn có thể đặt màu nền. Nếu hiệu ứng bạn muốn tạo ra có thể đạt được bằng màu nền trên các nhóm hàng thay vì đường viền, điều này sẽ hoạt động.

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

2

Nhóm các hàng lại với nhau bằng cách sử dụng <tbody>thẻ và sau đó áp dụng kiểu.

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

Và css trong style.css

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

1

Cách duy nhất mà tôi có thể nghĩ ra để làm điều đó là bao quanh mỗi hàng bạn cần một đường viền xung quanh trong một bảng lồng nhau. Điều đó sẽ làm cho đường viền dễ thực hiện hơn nhưng sẽ có khả năng tạo ra các vấn đề về bố cục khác, bạn sẽ phải đặt chiều rộng trên các ô bảng theo cách thủ công, v.v.

Cách tiếp cận của bạn có thể là cách tốt nhất tùy thuộc vào các yêu cầu khác về bố cục của bạn và cách tiếp cận được đề xuất ở đây chỉ là một phương án khả thi.

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

Cảm ơn câu trả lời của bạn; Mặc dù vậy, bạn đã đúng về các vấn đề bố cục - tôi muốn các cột sắp hàng mà không cần thực hiện bằng tay. Còn việc áp dụng một lớp cho thẻ <tr> - điều đó có khả thi không?
Kyle Cronin

Nếu bạn sử dụng một bảng có "table-layout: fixed" và đặt chiều rộng của mỗi cột một cách rõ ràng (bằng cách sử dụng <col> hoặc chỉ đặt chiều rộng của các ô trong hàng đầu tiên), các cột sẽ thẳng hàng với nhau bất kể nội dung. Bạn thậm chí không cần phải lồng các bảng, ba bảng riêng biệt sẽ làm được ví dụ tốt.
bobince

1

Dựa trên yêu cầu của bạn rằng bạn muốn đặt đường viền xung quanh một khối ô MxN tùy ý, thực sự không có cách nào dễ dàng hơn nếu không sử dụng Javascript. Nếu các ô của bạn được cố định, bạn có thể sử dụng phao nhưng điều này có vấn đề vì các lý do khác. những gì bạn đang làm có thể tẻ nhạt nhưng nó ổn.

Được rồi, nếu bạn quan tâm đến giải pháp Javascript, sử dụng jQuery (cách tiếp cận ưa thích của tôi), bạn sẽ nhận được đoạn mã khá đáng sợ này:

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

Tôi sẵn lòng đưa ra các gợi ý về những cách dễ dàng hơn để thực hiện việc này ...


1
Có vẻ như bạn chỉ thêm các lớp vào các thẻ td? Tại sao điều này không thể được thực hiện với một số tập lệnh phía máy chủ, được tạo tĩnh hoặc trường hợp xấu nhất chỉ bằng tay? Có vẻ như tôi lạm dụng JavaScript.
Thomas

3
Trên thực tế, người đăng đã HỎI một giải pháp Javascript. Bạn không thể nói đó là lạm dụng Javascript vì không có đủ thông tin. Ví dụ: các đường viền được thêm vào do người dùng thực hiện thao tác nhấp chuột? Nếu vậy, một giải pháp máy chủ không chính xác.
cletus

Xin lỗi về việc thiếu thông tin. Điều này sẽ được tạo phía máy chủ, vì vậy đúng là tôi chỉ có thể thêm các lớp theo cách thủ công, nhưng tôi thích cách giải pháp JS cung cấp một giao diện đơn giản hơn để làm như vậy. Vì vậy, mặc dù tôi có thể sẽ không sử dụng JS, nhưng đó là một giải pháp tốt để xem.
Kyle Cronin

0

mẹo là với thuộc tính outline nhờ câu trả lời của enigment với một chút sửa đổi

sử dụng lớp học này

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

sau đó trong HTML

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

và kết quả là nhập mô tả hình ảnh ở đây hy vọng điều này sẽ giúp bạn


-5

Một cách dễ dàng hơn là đặt bảng thành điều khiển phía máy chủ. Bạn có thể sử dụng một cái gì đó tương tự như sau:

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

1
OP được yêu cầu cho một dễ dàng hơn cách để làm điều đó
orique

2
Hãy cẩn thận, OP cũng đang yêu cầu một cách dễ dàng hơn để làm điều đó trong HTML / CSS. Tôi không thấy ở đâu trong câu hỏi của anh ấy từ khóa VB hoặc VBA. Tôi khuyên bạn nên xem phần Trợ giúp của chúng tôi: stackoverflow.com/help/how-to-answer Good Luck.
ForceMagic
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.