CSS3 propriedade border-radius e border-collapse: colapso não se misturam. Como posso usar border-radius para criar uma tabela em colapso com cantos arredondados?

StackOverflow https://stackoverflow.com/questions/628301

Pergunta

Editar - Título original: Existe uma forma alternativa para alcançar border-collapse:collapse em CSS (a fim de ter, uma mesa de canto arredondado desmoronou)

?

Uma vez que se constata que simplesmente ficando bordas da tabela ao colapso não resolve a raiz do problema, eu atualizei o título para refletir melhor a discussão.

Eu estou tentando fazer uma tabela com cantos arredondados usando a propriedade CSS3 border-radius. Os estilos de tabela que estou usando algo parecido com isto:

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

Aqui está o problema. Eu também quero definir a propriedade border-collapse:collapse, e quando isso é conjunto border-radius não funciona mais. Existe uma maneira baseada em CSS eu posso conseguir o mesmo efeito que border-collapse:collapse sem realmente usá-lo?

Edições:

Eu fiz uma página simples para demonstrar o problema aqui (Firefox / Safari apenas) .

Parece que uma grande parte do problema é que a configuração da tabela para ter cantos arredondados não afetam os cantos dos elementos canto td. Se a tabela era de uma cor só, isso não seria um problema desde que eu poderia apenas fazer o topo e cantos td fundo arredondado para a primeira e última linha respectivamente. No entanto, estou usando diferentes cores de fundo para a tabela para diferenciar as rubricas e para striping, então os elementos td internas iria mostrar seus cantos arredondados também.

Resumo das soluções propostas:

Em torno da mesa com outro elemento com cantos arredondados não funciona porque cantos quadrados da tabela "sangrar através de".

A especificação de largura fronteira para 0 não fechar a tabela.

cantos td fundo ainda praça depois de definir cellspacing a zero.

Usando obras de JavaScript em vez-, evitando o problema.

soluções possíveis:

As tabelas são geradas em PHP, então eu poderia simplesmente aplicar uma classe diferente para cada um dos exterior th / tds e estilo cada canto separadamente. Eu prefiro não fazer isso, já que não é muito elegante e um pouco de dor para aplicar a várias tabelas, por isso, manter sugestões vinda.

Solução possível 2 é usar JavaScript (jQuery, especificamente) para estilizar os cantos. Esta solução também funciona, mas ainda não é o que eu estou procurando (eu sei que eu sou exigente). Eu tenho duas reservas:

  1. este é um local muito leve, e eu gostaria de manter o JavaScript para o mínimo indispensável
  2. parte do apelo que o uso de border-radius tem para mim é graciosa degradação e melhoria progressiva. Ao usar border-radius para todos os cantos arredondados, espero ter um site consistentemente arredondada em navegadores CSS3-capaz e um site quadradas em outros (eu estou olhando para você, IE).

Eu sei que tentar fazer isso com CSS3 hoje pode parecer desnecessária, mas eu tenho minhas razões. Eu também gostaria de salientar que este problema é resultado da especificação W3C, não fraco suporte CSS3, portanto, qualquer solução ainda será relevante e útil quando CSS3 tem suporte mais difundido.

Foi útil?

Solução

Eu percebi isso. Você apenas tem que usar alguns seletores especiais.

O problema com arredondamento dos cantos da mesa era de que os elementos td não também tornar-se arredondado. Você pode resolver isso, fazendo algo parecido com isto:

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

table tr:last-child td:last-child {
    border-bottom-right-radius: 10px;
}

Agora tudo rodadas corretamente, exceto que ainda há a questão da border-collapse: collapse quebrando tudo. A solução é definir cellspacing="0" no html vez (graças, Joel ).

Outras dicas

Os seguintes método funciona (testado no Chrome) usando um box-shadow com um spread de 1px em vez de uma fronteira "real".

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

Se você quer uma solução apenas de CSS (sem necessidade de cellspacing=0 conjunto no HTML) que permite a 1px fronteiras (que você não pode fazer com a solução border-spacing: 0), eu prefiro fazer o seguinte:

  • Defina um border-right e border-bottom para suas células da tabela (td e th)
  • Dê as células na primeira linha a border-top
  • Dê as células na primeira coluna a border-left
  • Usando os seletores first-child e last-child, arredondar os cantos apropriados para as células da tabela nos quatro cantos.

Veja uma demonstração aqui.

Dado o seguinte HTML:

Veja o exemplo abaixo:

   

 .custom-table{margin:30px;}
    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 th:last-child{
    border-top:solid 1px      #bbb;}
    table tr th:first-child,
    table tr td:first-child {
        border-left: 1px solid #bbb;
        
    }
    table tr th:first-child,
    table tr td:first-child {
        border-left: 1px solid #bbb;
    }
    table tr th {
        background: #eee;
        text-align: left;
    }
    
    table.Info tr th,
    table.Info tr:first-child td
    {
        border-top: 1px solid #bbb;
    }
    
    /* top-left border-radius */
    table tr:first-child th:first-child,
    table.Info tr:first-child td:first-child {
        border-top-left-radius: 6px;
    }
    
    /* top-right border-radius */
    table tr:first-child th:last-child,
    table.Info tr:first-child td: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 class="custom-table">
    <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>

Você já tentou usar table{border-spacing: 0} vez de table{border-collapse: collapse} ???

Você provavelmente vai ter que colocar um outro elemento ao redor da mesa e estilo que com uma borda arredondada.

O projecto trabalhando especifica que border-radius não se aplicam aos elementos da tabela quando o valor de border-collapse é collapse.

Como Ian disse, a solução é o ninho tabela dentro de uma div e configurá-lo assim:

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

Com overflow:hidden, os cantos quadrados não vai sangrar através da div.

Para o melhor de meu conhecimento, a única maneira que você poderia fazer seria para modificar todas as células assim:

table td {
  border-right-width: 0px;
  border-bottom-width: 0px;
}

E, em seguida, para obter a fronteira na parte de trás inferior e direita

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

:last-child não é válido no IE6, mas se você estiver usando border-radius eu suponho que você não se importa.

EDIT:

Depois de olhar para a sua página de exemplo, parece que você pode ser capaz de contornar isso com espaçamento de célula e estofamento.

As bordas cinzas grossas que você está vendo são realmente o fundo da tabela (você pode ver isso claramente, se você mudar a cor da borda para o vermelho). Se você definir o cellspacing para zero (ou equivalentemente: td, th { margin:0; }). "Fronteiras" cinza desaparecerá

EDIT 2:

Não consigo encontrar uma maneira de fazer isso com apenas uma mesa. Se você mudar sua linha de cabeçalho para uma tabela aninhada, você pode, eventualmente, ser capaz de obter o efeito desejado, mas vai ser mais trabalho, e não dinâmico.

Eu tentei uma solução alternativa usando o pseudo elementos :before e :after na thead th:first-child e thead th:last-child

Em combinação com envolvendo a tabela, com um <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

funciona para mim em cromo (13.0.782.215) Deixe-me saber se isso funciona para você em outros navegadores.

Eu tive o mesmo problema. remover border-collapse inteiramente e usar: cellspacing="0" cellpadding="0" no documento html. exemplo:

<table class="top_container" align="center" cellspacing="0" cellpadding="0">

Na verdade, você pode adicionar seu table dentro de um div como sua embalagem. e depois atribuir esses códigos CSS para fardos:

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

table {
  border-collapse: collapse;
}

As respostas dadas único trabalho quando não há fronteiras ao redor da mesa, o que é muito limitante!

Eu tenho uma macro no SASS para fazer isso, que apoia plenamente e fronteiras internas externas, alcançando o mesmo estilo como border-collapse: colapso sem realmente especificando-a.

Testado em FF / IE8 / Safari / Chrome.

Dá fronteiras arredondados agradáveis ??em CSS puro em todos os navegadores, mas IE8 (degrada graciosamente) desde IE8 não suporta border-radius: (

Alguns navegadores mais antigos podem exigir fornecedor prefixos ao trabalho com border-radius, tão à vontade para adicionar esses prefixos em seu código, conforme necessário.

Esta resposta não é o mais curto -. Mas funciona

.roundedTable {
  border-radius: 20px / 20px;
  border: 1px solid #333333;
  border-spacing: 0px;
}
.roundedTable th {
  padding: 4px;
  background: #ffcc11;
  border-left: 1px solid #333333;
}
.roundedTable th:first-child {
  border-left: none;
  border-top-left-radius: 20px;
}
.roundedTable th:last-child {
  border-top-right-radius: 20px;
}
.roundedTable tr td {
  border: 1px solid #333333;
  border-right: none;
  border-bottom: none;
  padding: 4px;
}
.roundedTable tr td:first-child {
  border-left: none;
}

Para aplicar este estilo simplesmente mudar a sua

<table>

tag com o seguinte:

<table class="roundedTable">

e não se esqueça de incluir os estilos CSS acima em seu HTML.

Espero que isso ajude.

Para uma tabela delimitada e de rolagem, use este (substitua variáveis, textos $ partida)

Se você usar thead, tfoot ou th, basta substituir tr:first-child e tr-last-child e td com eles.

#table-wrap {
  border: $border solid $color-border;
  border-radius: $border-radius;
}
table {
  border-collapse: collapse;
  border-spacing: 0;
}
table td { border: $border solid $color-border; }
table td:first-child { border-left: none; }
table td:last-child { border-right: none; }
table tr:first-child td { border-top: none; }
table tr:last-child td { border-bottom: none; }
table tr:first-child td:first-child { border-top-left-radius: $border-radius; }
table tr:first-child td:last-child { border-top-right-radius: $border-radius; }
table tr:last-child td:first-child { border-bottom-left-radius: $border-radius; }
table tr:last-child td:last-child { border-bottom-right-radius: $border-radius; }

HTML:

<div id=table-wrap>
  <table>
    <tr>
       <td>1</td>
       <td>2</td>
    </tr>
    <tr>
       <td>3</td>
       <td>4</td>
    </tr>
  </table>
</div>

Eu só escreveu um conjunto louco de CSS para este que parece funcionar perfeitamente:

table {
  border-collapse: separate;
  border-spacing: 0;
  width: 100%;
}
table td,
table th {
  border-right: 1px solid #CCC;
  border-top: 1px solid #CCC;
  padding: 3px 5px;
  vertical-align: top;
}
table td:first-child,
table th:first-child {
  border-left: 1px solid #CCC;
}
table tr:last-child td,
table tr:last-child th {
  border-bottom: 1px solid #CCC;
}
table thead + tbody tr:first-child td {
  border-top: 0;
}
table thead td,
table th {
  background: #EDEDED;
}

/* complicated rounded table corners! */
table thead:first-child tr:last-child td:first-child {
  border-bottom-left-radius: 0;
}
table thead:first-child tr:last-child td:last-child {
  border-bottom-right-radius: 0;
}
table thead + tbody tr:first-child td:first-child {
  border-top-left-radius: 0;
}
table thead + tbody tr:first-child td:last-child {
  border-top-right-radius: 0;
}
table tr:first-child td:first-child,
table thead tr:first-child td:first-child {
  border-top-left-radius: 5px;
}
table tr:first-child td:last-child,
table thead tr:first-child td:last-child {
  border-top-right-radius: 5px;
}
table tr:last-child td:first-child,
table thead:last-child tr:last-child td:first-child {
  border-bottom-left-radius: 5px;
}
table tr:last-child td:last-child,
table thead:last-child tr:last-child td:last-child {
  border-bottom-right-radius: 5px;
}

/* end complicated rounded table corners !*/

Solução com border-collapse: separada para mesa e display:. Inline-mesa para tbody e thead

table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0px;
  background: transparent;   
}
table thead {
  display: inline-table;
  width: 100%;
  background: #fc0 url(../images/bg-heading.png) repeat-x 0% 0;
  -webkit-border-top-left-radius: 7px;
  -moz-border-radius-topleft: 7px;
  -webkit-border-top-right-radius: 7px;
  -moz-border-radius-topright: 7px;
    border-radius: 7px 7px 0px 0px;
  padding: 1px;
  padding-bottom: 0;
}

table tbody {
  border: 1px solid #ddd;
  display: inline-table;
  width: 100%;
  border-top: none;        
}

Eu sou novo com HTML e CSS e eu também estava à procura de solução para isso, aqui o que eu acho.

table,th,td {
   border: 1px solid black;
   border-spacing: 0
}
/* add border-radius to table only*/
table {
   border-radius: 25px    
}
/* then add border-radius to top left border of left heading cell */
th:first-child {
   border-radius: 25px 0 0 0
}
/* then add border-radius to top right border of right heading cell */
th:last-child {
   border-radius: 0 25px 0 0
}
/* then add border-radius to bottom left border of left cell of last row */
tr:last-child td:first-child {
   border-radius: 0 0 0 25px
}
/* then add border-radius to bottom right border of right cell of last row */
tr:last-child td:last-child {
   border-radius: 0 0 25px 0
}

Eu experimentá-lo, acho que o que funciona:)

Você achou esta resposta depois de correr para o mesmo problema, mas descobriu que é bastante simples: basta dar o estouro da tabela: escondido

Não é necessário um elemento de envolvimento. Concedido, eu não sei se isso teria funcionado 7 anos atrás, quando a questão foi inicialmente solicitado, mas funciona agora.

Tabela com cantos arredondados e com células com contornos. Usando @Ramon Tayag solução.

A chave é usar border-spacing: 0 como ele aponta.

Solução usando SCSS .

$line: 1px solid #979797;
$radius: 5px;

table {
  border: $line;
  border-radius: $radius;
  border-spacing: 0;
  th,
  tr:not(:last-child) td {
    border-bottom: $line;
  }
  th:not(:last-child),
  td:not(:last-child) {
    border-right: $line;
  }
}

Eu comecei a experimentar com "display" e eu achei que: border-radius, border, margin, padding, num table são exibidos com:

display: inline-table;

Por exemplo

table tbody tr {
  display: inline-table;
  width: 960px; 
  -webkit-border-radius: 5px;
  -moz-border-radius: 5px;
  border-radius: 5px;
}

Mas precisamos definir um width de cada coluna

tr td.first-column {
  width: 100px;
}
tr td.second-column {
  width: 860px;
}

Aqui está um exemplo recente de como implementar uma tabela com arredondado cantos de http://medialoot.com/preview/css-ui-kit/demo.html . É baseado em seletores especiais sugeridos por Joel Potter acima. Como você pode ver, ele também inclui um pouco de magia para fazer IE um pouco feliz. Ele inclui alguns estilos extra para alternar a cor das linhas:

table-wrapper {
  width: 460px;
  background: #E0E0E0;
  filter: progid: DXImageTransform.Microsoft.gradient(startColorstr='#E9E9E9', endColorstr='#D7D7D7');
  background: -webkit-gradient(linear, left top, left bottom, from(#E9E9E9), to(#D7D7D7));
  background: -moz-linear-gradient(top, #E9E9E9, #D7D7D7);
  padding: 8px;
  -webkit-box-shadow: inset 0px 2px 2px #B2B3B5, 0px 1px 0 #fff;
  -moz-box-shadow: inset 0px 2px 2px #B2B3B5, 0px 1px 0 #fff;
  -o-box-shadow: inset 0px 2px 2px #B2B3B5, 0px 1px 0 #fff;
  -khtml-box-shadow: inset 0px 2px 2px #B2B3B5, 0px 1px 0 #fff;
  box-shadow: inset 0px 2px 2px #B2B3B5, 0px 1px 0 #fff;
  -webkit-border-radius: 10px;
  /*-moz-border-radius: 10px; firefox doesn't allow rounding of tables yet*/
  -o-border-radius: 10px;
  -khtml-border-radius: 10px;
  border-radius: 10px;
  margin-bottom: 20px;
}
.table-wrapper table {
  width: 460px;
}
.table-header {
  height: 35px;
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 14px;
  text-align: center;
  line-height: 34px;
  text-decoration: none;
  font-weight: bold;
}
.table-row td {
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 14px;
  text-align: left;
  text-decoration: none;
  font-weight: normal;
  color: #858585;
  padding: 10px;
  border-left: 1px solid #ccc;
  -khtml-box-shadow: 0px 1px 0px #B2B3B5;
  -webkit-box-shadow: 0px 1px 0px #B2B3B5;
  -moz-box-shadow: 0px 1px 0px #ddd;
  -o-box-shadow: 0px 1px 0px #B2B3B5;
  box-shadow: 0px 1px 0px #B2B3B5;
}
tr th {
  border-left: 1px solid #ccc;
}
tr th:first-child {
 -khtml-border-top-left-radius: 8px;
  -webkit-border-top-left-radius: 8px;
  -o-border-top-left-radius: 8px;
  /*-moz-border-radius-topleft: 8px; firefox doesn't allow rounding of tables yet*/
  border-top-left-radius: 8px;
  border: none;
}
tr td:first-child {
  border: none;
}
tr th:last-child {
  -khtml-border-top-right-radius: 8px;
  -webkit-border-top-right-radius: 8px;
  -o-border-top-right-radius: 8px;
  /*-moz-border-radius-topright: 8px; firefox doesn't allow rounding of tables yet*/
  border-top-right-radius: 8px;
}
tr {
  background: #fff;
}
tr:nth-child(odd) {
  background: #F3F3F3;
}
tr:nth-child(even) {
  background: #fff;
}
tr:last-child td:first-child {
  -khtml-border-bottom-left-radius: 8px;
  -webkit-border-bottom-left-radius: 8px;
  -o-border-bottom-left-radius: 8px;
  /*-moz-border-radius-bottomleft: 8px; firefox doesn't allow rounding of tables yet*/
  border-bottom-left-radius: 8px;
}
tr:last-child td:last-child {
  -khtml-border-bottom-right-radius: 8px;
  -webkit-border-bottom-right-radius: 8px;
  -o-border-bottom-right-radius: 8px;
  /*-moz-border-radius-bottomright: 8px; firefox doesn't allow rounding of tables yet*/
  border-bottom-right-radius: 8px;
}

Eu sempre faço desta forma usando Sass

table {
  border-radius: 0.25rem;
  thead tr:first-child th {
    &:first-child {
      border-top-left-radius: 0.25rem;
    }
    &:last-child {
      border-top-right-radius: 0.25rem;
    }
  }
  tbody tr:last-child td {
    &:first-child {
      border-bottom-left-radius: 0.25rem;
    }
    &:last-child {
      border-bottom-right-radius: 0.25rem;
    }
  }
}

border-radius é agora suportado oficialmente. Assim, em todos os exemplos acima, você pode soltar o "-moz-" prefixo.

Outro truque é usar a mesma cor para a parte superior e linhas inferiores como é a sua fronteira. Com todas as 3 cores o mesmo, se mistura e se parece com uma mesa perfeitamente arredondado, mesmo que não esteja fisicamente.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top