เส้นขอบรอบ ๆ แถวที่ระบุในตาราง?


120

ฉันกำลังพยายามออกแบบ HTML / CSS ที่สามารถวางเส้นขอบรอบ ๆ แถวที่ต้องการในตารางได้ ใช่ฉันรู้ว่าฉันไม่ควรใช้ตารางในการจัดวาง แต่ฉันไม่รู้ CSS เพียงพอที่จะแทนที่มันได้ทั้งหมด

อย่างไรก็ตามฉันมีตารางที่มีหลายแถวและคอลัมน์บางส่วนรวมเข้ากับ rowspan และ colspan และฉันต้องการใส่เส้นขอบที่เรียบง่ายรอบ ๆ ส่วนต่างๆของตาราง ตอนนี้ฉันใช้คลาส CSS แยกกัน 4 คลาส (บนล่างซ้ายขวา) ที่ฉันแนบกับ<td>เซลล์ที่อยู่ด้านบนล่างซ้ายและขวาของตารางตามลำดับ

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

มีวิธีใดที่ง่ายกว่าในการทำสิ่งที่ฉันต้องการ? ฉันลองใช้บนและล่างกับ a <tr>แต่ไม่ได้ผล (ป.ล. ฉันยังใหม่กับ CSS ดังนั้นอาจมีวิธีแก้ปัญหาพื้นฐานที่ฉันพลาดไป)

หมายเหตุ:ฉันจำเป็นต้องมีส่วนที่มีขอบหลายส่วน แนวคิดพื้นฐานคือการมีคลัสเตอร์ที่มีขอบหลายอันแต่ละอันมีหลายแถว


9
นอกประเด็น แต่ฉันแค่อยากจะบอกว่าตารางมีความเหมาะสมอย่างยิ่งและแนะนำเมื่อแสดงข้อมูลแบบตาราง ...
md1337

คำตอบ:


114

แล้วไงtr {outline: thin solid black;}? ใช้ได้กับฉันในองค์ประกอบ tr หรือ tbody และดูเหมือนว่าจะเข้ากันได้กับเบราว์เซอร์ส่วนใหญ่รวมถึง IE 8+ แต่ก่อนหน้านี้


ฉันถามเกี่ยวกับการวางเส้นขอบเดียวรอบ ๆ หลายแถวในตารางโดยพื้นฐานแล้วการแบ่งออกเป็นหลายส่วนด้วยสายตา แต่อยู่ในตารางเดียวกันเพื่อให้สิ่งต่างๆจากส่วนต่างๆจัดเรียงกัน
Kyle Cronin

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

โอ้ฉันเห็นคนหลายคน - นั่นได้ผลและเป็นสิ่งที่ฉันไม่ได้พิจารณา โหวตขึ้น :)
Kyle Cronin

ฉันขอแนะนำให้ใช้คุณสมบัติที่ n-child () css แทนการกำหนด tbodys เว้นแต่คุณจะมีข้อมูลไดนามิกที่สวยงามจริงๆ การใช้ nth-child (), nth-last-child () และ not () คุณสามารถเลือกแถว / เซลล์ใดก็ได้ที่คุณต้องการ (ตราบเท่าที่คุณทราบดัชนีสัมพัทธ์ของสิ่งต่างๆในตาราง) ตัวอย่างเช่นคุณสามารถเลือกแถวทั้งหมดยกเว้นแถวบนสุดและแถวล่างสุดโดยมี tr: not (: nth-child (-n + 2)): not (: nth-last-child (1))
BT

1
โปรดสังเกตว่าร่างไม่ได้มีความเป็นไปได้ด้านชายแดนที่เฉพาะเจาะจงขององค์ประกอบ ไม่มี "outline-top" เช่น นี่เป็นวิธีการแก้ปัญหาที่ จำกัด
BT

53

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

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>

เอาท์พุท:

ใส่คำอธิบายภาพที่นี่

แทนที่จะต้องเพิ่มtop, bottom, leftและrightชั้นเรียนทุก<td>สิ่งที่ผมต้องทำคือเพิ่มtop rowไปด้านบน<tr>, bottom rowด้านล่าง<tr>และrowทุก<tr>อย่างในระหว่าง มีอะไรผิดปกติในการแก้ปัญหานี้หรือไม่? มีปัญหาข้ามแพลตฟอร์มที่ฉันควรทราบหรือไม่?


เพิ่งทำการทดสอบผ่านเบราว์เซอร์และดูเหมือนว่า IE (ทุกเวอร์ชัน) ไม่ชอบแอตทริบิวต์ลูกคนแรกและลูกคนสุดท้าย : - /
Kyle Cronin

1
ลักษณะเช่น IE 7 และ 8 สนับสนุนแรกเด็ก แต่การสนับสนุนไม่มีสุดท้ายเด็ก (!) msdn.microsoft.com/en-us/library/cc351024(VS.85).aspx
mechanical_meat

cellspacingแอตทริบิวต์จะเลิกใน HTML5 ดูเหมือนว่า CSS table { border-collapse: collapse; border-spacing: 0; }จะเป็นหนทางไปแล้ว
Stefan van den Akker

36

หากคุณตั้งค่าborder-collapseสไตล์เป็นcollapseบนตารางหลักคุณควรจะสามารถกำหนดสไตล์tr: (สไตล์เป็นแบบอินไลน์สำหรับการสาธิต)

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

เอาท์พุท:

เอาต์พุต HTML


8

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

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

โปรดทราบว่าวิธีนี้จะป้องกันการใช้ความกว้างของคอลัมน์แบบไหล / อัตโนมัติเนื่องจากเซลล์จะไม่จัดแนวเดียวกับเซลล์ในแถวอื่น ๆ อีกต่อไป แต่การจัดรูปแบบเส้นขอบ / สียังคงใช้ได้ วิธีแก้ปัญหาคือให้ TR และ TD มีความกว้างที่ระบุ (px หรือ%)

แน่นอนคุณสามารถสร้างตัวเลือกได้tr.myClassหากคุณต้องการใช้กับบางแถวเท่านั้น เห็นได้ชัดว่าใช้display: tableไม่ได้กับ IE 6/7 แต่อาจมีแฮ็กอื่น ๆ (hasLayout?) ที่อาจใช้งานได้ :-(


6
วิธีแก้ปัญหานี้ไม่ถูกต้อง: "display: table" ทำให้ทั้งแถวเป็นเซลล์ตารางเดียว --- คุณจะสูญเสียการจัดรูปแบบเมื่อเทียบกับแถวอื่น ๆ ของตาราง ฉันลองสิ่งนี้ใน Firefox และ Chromium
Yaakov Belch

Yaakov ฉันคิดว่าสิ่งที่คุณอ้างถึงคือความกว้างของคอลัมน์ของไหลไม่สอดคล้องกับแถวอื่น ๆ ในตารางอีกต่อไป (ดังที่เห็นในซอนี้: jsfiddle.net/MrKtw ) แต่การจัดรูปแบบเส้นขอบ / สียังใช้งานได้ดี วิธีแก้ปัญหาคือให้ TR และ TD มีความกว้างที่ระบุ (px หรือ%)
Simon East

Simon เพื่อแสดงให้เห็นว่าฉันหมายถึงอะไรฉันแยกและเปลี่ยนเสียงซอของคุณ ดูสิ่งนี้: jsfiddle.net/a6DZV --- ฉันใช้การจัดรูปแบบ "display: table" กับแถวเดียวเท่านั้น อย่างที่คุณเห็นสิ่งนี้จะเปลี่ยนแถวนี้ให้เป็นเซลล์เดียวของตารางได้อย่างมีประสิทธิภาพ กล่าวอีกนัยหนึ่ง: คุณจะได้ผลลัพธ์เดียวกันกับการซ้อนตารางแถวเดียวภายในเซลล์ของตารางอื่น (และแสดงเส้นขอบของตารางด้านในนี้) โซลูชันของคุณบันทึกไม่กี่โหนดใน DOM แต่ไม่สามารถทำงานร่วมกันได้
Yaakov Belch

3

นี่คือวิธีการโดยใช้องค์ประกอบ tbody ที่อาจเป็นวิธีการทำ คุณไม่สามารถกำหนดเส้นขอบบน tbody ได้ (เหมือนกับที่คุณทำไม่ได้บน tr) แต่คุณสามารถกำหนดสีพื้นหลังได้ หากเอฟเฟกต์ที่คุณต้องการบรรลุสามารถรับได้ด้วยสีพื้นหลังในกลุ่มของแถวแทนที่จะใช้เส้นขอบสิ่งนี้จะได้ผล

<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

จัดกลุ่มแถวเข้าด้วยกันโดยใช้<tbody>แท็กแล้วใช้สไตล์

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

และ css ใน style.css

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

1

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

แนวทางของคุณอาจเป็นแนวทางที่ดีที่สุดขึ้นอยู่กับข้อกำหนดการจัดวางอื่น ๆ ของคุณและแนวทางที่แนะนำนี่เป็นเพียงทางเลือกที่เป็นไปได้

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

ขอบคุณสำหรับคำตอบ; คุณพูดถูกเกี่ยวกับปัญหาเลย์เอาต์ - ฉันต้องการให้คอลัมน์เรียงแถวโดยไม่ต้องทำด้วยมือ แล้วการนำคลาสไปใช้กับแท็ก <tr> เป็นไปได้หรือไม่?
Kyle Cronin

หากคุณใช้ตารางที่มี "เค้าโครงตาราง: คงที่" และกำหนดความกว้างของแต่ละคอลัมน์อย่างชัดเจน (โดยใช้ <col> หรือเพียงแค่ตั้งค่าความกว้างของเซลล์ในแถวแรก) คอลัมน์จะเรียงแถวกันโดยไม่คำนึงถึงเนื้อหา คุณไม่จำเป็นต้องซ้อนตารางด้วยซ้ำสามตารางที่แยกจากกันจะทำตัวอย่างได้ดี
bobince

1

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

ตกลงถ้าคุณสนใจโซลูชัน Javascript โดยใช้ jQuery (แนวทางที่ฉันต้องการ) คุณจะได้โค้ดที่ค่อนข้างน่ากลัวนี้:

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

ยินดีจะรับคำแนะนำเกี่ยวกับวิธีที่ง่ายกว่านี้ ...


1
ดูเหมือนว่าคุณเพิ่งเพิ่มคลาสให้กับแท็ก td? เหตุใดจึงไม่สามารถทำได้กับสคริปต์ฝั่งเซิร์ฟเวอร์ที่สร้างขึ้นแบบคงที่หรือกรณีที่เลวร้ายที่สุดเพียงทำด้วยมือ ดูเหมือนว่าฉันจะใช้ JavaScript ในทางที่ผิด
Thomas

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

ขออภัยที่ไม่มีข้อมูล สิ่งนี้จะถูกสร้างขึ้นในฝั่งเซิร์ฟเวอร์ดังนั้นจึงเป็นเรื่องจริงที่ฉันสามารถเพิ่มในคลาสด้วยตนเองได้ แต่ฉันชอบวิธีที่โซลูชัน JS มีอินเทอร์เฟซที่ง่ายกว่าให้ทำ ดังนั้นในขณะที่ฉันอาจจะไม่ใช้ JS แต่ก็เป็นทางออกที่ดีที่จะเห็น
Kyle Cronin

0

เคล็ดลับคือด้วยคุณสมบัติเค้าร่างด้วยคำตอบของปริศนาที่มีการปรับเปลี่ยนเล็กน้อย

ใช้คลาสนี้

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

จากนั้นใน HTML

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

และผลลัพธ์คือ ใส่คำอธิบายภาพที่นี่ หวังว่านี่จะช่วยคุณได้


-5

วิธีที่ง่ายกว่าคือทำให้ตารางเป็นตัวควบคุมฝั่งเซิร์ฟเวอร์ คุณสามารถใช้สิ่งที่คล้ายกับสิ่งนี้:

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 ขอวิธีที่ง่ายกว่านี้
orique

2
โปรดระวัง OP ยังขอวิธีที่ง่ายกว่าในการทำ HTML / CSS ฉันไม่เห็นคำถามของเขาเกี่ยวกับคำหลัก VB หรือ VBA ฉันขอแนะนำให้คุณดูส่วนความช่วยเหลือของเรา: stackoverflow.com/help/how-to-answer Good Luck
ForceMagic
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.