边框半径属性和边框合并属性不兼容。我该如何使用边框半径创建一个带有圆角的合并表格?

410

我正在尝试使用CSS border-radius属性制作一个带圆角的表格。我正在使用的表格样式大致如下:

table {
    -moz-border-radius:10px;
    -webkit-border-radius:10px;
    border-radius:10px
}

这是问题所在。我还想设置border-collapse:collapse属性,但当它被设置后,border-radius不再起作用。有没有一种基于CSS的方法可以实现与border-collapse:collapse相同的效果而不实际使用它?

看起来问题的很大一部分是将表格设置为具有圆角并不影响角落td元素的角落。如果表格都是同一颜色,这就不是一个问题,因为我可以只使第一行和最后一行的顶部和底部td角变圆。然而,我正在使用不同的背景颜色来区分标题和条纹,因此内部td元素也会显示其圆角。

用具有圆角的另一个元素围绕表格不起作用,因为表格的方形角“渗透”了出来。

将边框宽度指定为0不会折叠表格。

在设置cellspacing为零后,下面的td角仍然是方形的。

表格是在PHP中生成的,因此我可以只针对每个外部th/td应用不同的class,并单独设置每个角的样式。我不想这样做,因为它不太优雅,并且在应用于多个表格时有点繁琐,请继续提出建议。

我希望不使用JavaScript来实现这一点。


3
你可以将表格放入一个div中,给这个div设置border-radius和"overflow: hidden"属性。我测试过了,这样做很有效,除非你需要在具有固定宽度/高度或者祖先元素具有固定宽度/高度的div中进行滚动或扩展。 - Ian
28个回答

313

我已经想通了。你只需要使用一些特殊的选择器。

将表格的角落设计成圆形的问题是元素没有被设计成圆形。您可以通过像这样做来解决:

td {border-radius: 10px;}

table tr:last-child td:first-child {
    border: 2px solid orange;
    border-bottom-left-radius: 10px;
}
    
table tr:last-child td:last-child {
    border: 2px solid green;
    border-bottom-right-radius: 10px;
}
<table>
  <tbody>
    <tr>
      <td>1</td>
      <td>2</td>
    </tr>
    <tr>
      <td>3</td>
      <td>4</td>
    </tr>
  </tbody>
</table>

现在一切都正常了,除了 border-collapse: collapse 仍然会破坏一切。

解决方法是添加 border-spacing: 0 并在表格上保留默认的 border-collapse: separate


114
为何要费心调整 HTML 呢?不如将 border-spacing: 0; 添加为边框样式如何? - Ramon Tayag
3
我在设置表格的背景颜色时遇到了问题,想要设置 TR 标签而不是 TD 标签的背景颜色。如果你需要给表格设置条纹状的颜色,一定要将背景颜色设置为 TD 而非 TR。 - Will Shaver
1
只需像Ramon建议的那样添加 border-spacing: 0; 就可以解决我的问题。确保将 border-radiusborder-spacing 样式添加到 <th><td> 元素中,而不是 <thead><tbody> - Gavin
2
我正在使用Bootstrap,并且通过Ramon的建议找到了解决方案,就像这样:border-spacing: 0; border-collapse: separate; - Caner SAYGIN
1
此解决方案无法解决圆角边框折叠的 TD。 - neoswf
显示剩余4条评论

153

以下方法适用于使用Chrome (已测试),它使用具有1px扩展的box-shadow而不是“真正”的边框。

    table {
        border-collapse: collapse;
        border-radius: 30px;
        border-style: hidden; /* hide standard table (collapsed) border */
        box-shadow: 0 0 0 1px #666; /* this draws the table border  */ 
    }

    td {
        border: 1px solid #ccc;
    }
<table>
  <thead>
    <tr>
      <th>Foo</th>
      <th>Bar</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Baz</td>
      <td>Qux</td>
    </tr>
    <tr>
      <td>Life is short</td>
      <td rowspan="3">and</td>
    </tr>
    <tr>
      <td>Love</td>
    </tr>
    <tr>
      <td>is always over</td>
    </tr>
    <tr>
      <td>In the</td>
      <td>Morning</td>
    </tr>
  </tbody>
</table>


6
这是我唯一有效的方法。不过,很难在表格边框上获得正确的颜色。 - Thomas Ahle
3
如果您的表格与周围区域具有不同的背景颜色,则它是不可用的。 - g.pickardou
5
可以通过在表格元素上添加 'overflow: hidden' 来解决该问题。 - Val
box-shadow 会使表格变大,因此边缘被裁剪掉了。 - Ray
它非常难以使用,特别是如果您需要使用圆角边框tds。它可能只适用于圆形表或圆形trs。 - neoswf

93

如果您想要一个仅使用CSS的解决方案(无需在HTML中设置cellspacing=0),并且允许1像素的边框(这是使用border-spacing: 0解决方案无法实现的),我更喜欢采用以下方法:

  • 为表格单元格(tdth)设置border-rightborder-bottom
  • 第一行中的单元格设置border-top
  • 第一列中的单元格设置border-left
  • 使用first-childlast-child选择器,对四个角落的表格单元格进行相应的圆角处理。

在此处查看演示。

假设有以下HTML:

See example below:

   

table {
  border-collapse: separate;
  border-spacing: 0;
  min-width: 350px;
}
table tr th,
table tr td {
  border-right: 1px solid #bbb;
  border-bottom: 1px solid #bbb;
  padding: 5px;
}

table tr th:first-child,
table tr td:first-child {
  border-left: 1px solid #bbb;
}
table tr th {
  background: #eee;
  text-align: left;
  border-top: solid 1px #bbb;
}

/* top-left border-radius */
table tr:first-child th:first-child {
  border-top-left-radius: 6px;
}

/* top-right border-radius */
table tr:first-child th:last-child {
  border-top-right-radius: 6px;
}

/* bottom-left border-radius */
table tr:last-child td:first-child {
  border-bottom-left-radius: 6px;
}

/* bottom-right border-radius */
table tr:last-child td:last-child {
  border-bottom-right-radius: 6px;
}
<div>
    <table>
        <tr>
            <th>item1</th>
            <th>item2</th>
        </tr>
        <tr>
            <td>item1</td>
            <td>item2</td>
        </tr>
        <tr>
            <td>item1</td>
            <td>item2</td>
        </tr>
        <tr>
            <td>item1</td>
            <td>item2</td>
        </tr>
    </table>
</div>


1
请写出包含(永久)代码的答案。如果有很多代码需要回答,只需发布相关部分以及为什么它们是相关的解释。 - Samuel Harmer
4
这是一个很好的解决方案,但有些难以理解。我重新编写了一些样式规则,并添加了代码说明,希望这可以帮助你更好地理解。 - Michael Martin-Smucker
也要对表格应用半径,否则当你为表格本身应用背景时,它看起来很奇怪。 - goat
“table.Info” 类与任何东西有什么关系? - Pylinux

36
你尝试过使用table{border-spacing: 0}代替table{border-collapse: collapse}吗?

谢谢,这让我能够做我需要做的事情(其中包括顶部一系列TH元素,位于包含所有下方TD的“圆角”框之外)。 - RonLugge
17
border-spacing: 0 的问题在于,你无法使用1像素的边框,因为边框会重叠而不是合并。 - Michael Martin-Smucker
3
border-collapse: separate; border-spacing: 0; border-radius: 10px; overflow: hidden;的效果正好符合我的需求。 - Milad.Nozari

27
你可能需要在表格周围放置另一个元素,并使用圆角边框样式化该元素。
这份工作草案规定,当border-collapse的值为collapse时,border-radius不适用于表格元素。 (参考链接)

1
这也是我考虑的事情,但如果我创建一个 div 来包围表格并将其设置为具有圆角,那么方形表格角仍会溢出。请参见新发布的示例。 - vamin
我找到的最好的折衷方案是在表格中添加THEAD块,并将灰色背景应用于它(在表格本身上使用#eee)。标题单元格溢出TABLE边框后面而不是前面。然后,我增加了表格边框为3像素以隐藏溢出部分。 - user59200
3
“bleed through” - 如果你使用 overflow:hidden; 就不会出现这种情况。 - Brian McCutchon
所以在这种情况下,每个人都可以使用我在这些页面底部提供的解决方案http://b2n.ir/table-radius - AmerllicA

22

正如Ian所说,解决方案是将表格嵌套在一个div中并进行如下设置:

.table_wrapper {
  border-radius: 5px;
  overflow: hidden;
}

使用overflow:hidden,正方形的角落不会溢出到 div 中。


4
请注意,任何想要使用 overflow: hidden 的人都应该知道,任何弹出框/工具提示都将被包装器尺寸裁剪。 - user776686

8
据我所知,您唯一能够做到的方法就是修改所有单元格,像这样:
table td {
  border-right-width: 0px;
  border-bottom-width: 0px;
}

然后要将底部和右侧的边框还原

table tr td:last-child {
  border-right-width: 1px;
}
table tr:last-child td {
  border-bottom-width: 1px;
}

:last-child在ie6中无效,但如果您正在使用border-radius,我认为您不会介意。

编辑:

经过查看您的示例页面,似乎您可以通过单元格间距和填充来解决此问题。

您看到的浓灰色边框实际上是表格的背景(如果将边框颜色更改为红色,则可以清楚地看到这一点)。如果将cellspacing设置为零(或等效地:td,th { margin:0; }),灰色“边框”将消失。

编辑2:

我找不到只使用一个表格就能实现这个效果的方法。如果您将标题行更改为嵌套表格,则可能能够获得所需的效果,但这需要更多的工作,并且不具备动态性。


我已经添加了一个cellspacing=0的例子,情况明显改善了。不想要的边框消失了,但是底部的角仍然会溢出。 - vamin
再次感谢您的帮助。这些表格是在PHP中生成的,所以如果没有提出优雅的解决方案,我会给每个角落的th/td分配一个类并单独设置样式。 - vamin

8

以下是一种方法:

div {
  border: 2px solid red;
  overflow: hidden;
  border-radius: 14px;
  transform: rotate(0deg);
}
table {
  border-spacing: 0;
  background-color: blue;
  height: 100%;
  width: 100%;
}
<div>
  <table>
    <tr>
      <td><br></td> 
    </tr>
  </table>
</div>

或者

    div {
      ...
      overflow: hidden;
      border-radius: 14px;
      position: relative;
      z-index: 1;
    }
        
        

这是唯一对我有效的解决方案(在Safari中,标题具有背景并且位置为sticky)。谢谢! - Dziad Borowy

7

实际上,您可以将表格放置在一个div中作为其包装器。然后,将这些CSS代码分配给包装器:

.table-wrapper {
  border: 1px solid #f00;
  border-radius: 5px;
  overflow: hidden;
}

table {
  border-collapse: collapse;
}

6
我尝试了一种解决方法,使用伪元素:before:afterthead th:first-childthead th:last-child上。
结合将表格包裹在一个<div class="radius borderCCC">中。
table thead th:first-child:before{ 
    content:" ";
    position:absolute;
    top:-1px;
    left:-1px;
    width:15px;
    height:15px;
    border-left:1px solid #ccc;
    border-top:1px solid #ccc; 
    -webkit-border-radius:5px 0px 0px;
}
table thead th:last-child:after{ 
    content:" "; 
    position:absolute; 
    top:-1px;
    right:-1px; 
    width:15px;
    height:15px;
    border-right:1px solid #ccc;
    border-top:1px solid #ccc;
    -webkit-border-radius:0px 5px 0px 0px;
}

请查看jsFiddle

在我的chrome浏览器(13.0.782.215)中可以运行。如果在其他浏览器中也能运行,请告诉我。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接