La propriété border-radius de CSS3 et border-collapse: collapse ne se mélange pas. Comment puis-je utiliser border-radius pour créer une table réduite avec des coins arrondis?

Edit-titre Original: Existe-t-il un autre moyen d'atteindre border-collapse:collapse dans CSS (afin d'avoir une table de coin arrondie et réduite)?

Comme il s'avère que le simple fait de réduire les bordures de la table ne résout pas le problème racine, j'ai mis à jour le titre pour mieux refléter la discussion.

J'essaie de faire une table avec des coins arrondis en utilisant le CSS3 border-radius propriété. Les styles de table que j'utilise ressemblent à quelque chose comme ce:

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

Voici le problème. Je veux aussi définir la propriété border-collapse:collapse, et quand cela est défini border-radius ne fonctionne plus. Y a-t-il un moyen basé sur CSS que je peux obtenir le même effet que border-collapse:collapse sans l'utiliser réellement?

Modifications:

J'ai fait une page simple pour démontrer le problème ici (Firefox / Safari uniquement).

Il semble qu'une grande partie du problème est que définir la table pour avoir des coins arrondis n'affecte pas les coins du coin td éléments. Si la table était d'une seule couleur, ce ne serait pas un problème car je pourrais simplement arrondir les coins supérieur et inférieur td pour la première et la dernière rangée respectivement. Cependant, j'utilise différentes couleurs d'arrière-plan pour la table pour différencier les en-têtes et pour le striping, de sorte que les éléments internes td montreraient également leurs coins arrondis.

Résumé des solutions proposées:

Entourant la table avec un autre élément avec des coins ronds ne fonctionne pas parce que les coins carrés de la table " saignent à travers."

Spécifier la largeur de la bordure à 0 ne réduit pas la table.

Bas td coins toujours carrés après avoir défini cellspacing à zéro.

Utiliser JavaScript à la place-fonctionne en évitant le problème.

Solutions Possibles:

Les tables sont générées en PHP, donc je pourrais simplement appliquer une classe différente à chacun des TH/tds externes et styliser chaque coin séparément. Je préfère ne pas le faire ceci, car ce n'est pas très élégant et un peu pénible à appliquer à plusieurs tables, alors gardez des suggestions à venir.

La solution Possible 2 consiste à utiliser JavaScript (jQuery, spécifiquement) pour styliser les coins. Cette solution fonctionne également, mais pas tout à fait ce que je cherche (je sais que je suis pointilleux). J'ai deux réserves:

  1. c'est un site très léger, et je voudrais garder JavaScript au minimum
  2. partie de l'appel que l'utilisation de border-radius a pour moi, c'est une dégradation gracieuse et une amélioration progressive. En utilisant border-radius pour tous les coins arrondis, j'espère avoir un site uniformément arrondi dans les navigateurs compatibles CSS3 et un site uniformément carré dans d'autres (je vous regarde, IE).

Je sais qu'essayer de le faire avec CSS3 aujourd'hui peut sembler inutile, mais j'ai mes raisons. Je voudrais également souligner que ce problème est le résultat de la spécification w3c, pas un mauvais support CSS3, donc toute solution sera toujours pertinente et utile lorsque CSS3 a un support plus répandu.

269
demandé sur vamin 2009-03-10 01:35:07

21 réponses

J'ai compris. Vous avez juste à utiliser des sélecteurs Spéciaux.

Le problème avec l'arrondi des coins de la table était que les éléments td ne devenaient pas également arrondis. Vous pouvez résoudre cela en faisant quelque chose comme ceci:

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

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

Maintenant, tout tourne correctement, sauf qu'il y a toujours le problème de border-collapse: collapse tout casser. Une solution de contournement consiste à définir cellspacing="0" dans le html à la place (merci, Joel ).

197
répondu vamin 2017-05-23 12:10:36

La méthode suivante fonctionne (testée dans Chrome) en utilisant un box-shadow avec un écart de 1px au lieu d'une bordure "réelle".

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;
}
63
répondu cmrd.Kaash 2013-04-18 12:05:25

Si vous voulez une solution CSS uniquement (pas besoin de définir cellspacing=0 dans le HTML) qui permet des bordures 1px (ce que vous ne pouvez pas faire avec la solution border-spacing: 0), je préfère faire ce qui suit:

  • Définir une border-right et border-bottom pour votre table de cellules (td et th)
  • donnez les cellules de la première ligne a border-top
  • Donner les cellules dans le première colonne un border-left
  • à l'aide des sélecteurs first-child et last-child, arrondir les coins appropriés pour les cellules de les quatre coins.

Voir une démo ici.

Étant donné le code HTML suivant:

Voir l'exemple ci-dessous:

   

 .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>
54
répondu NullUserException 2017-08-27 11:49:48

Avez-vous essayé d'utiliser table{border-spacing: 0} au lieu de table{border-collapse: collapse} ???

26
répondu Cesar 2010-10-18 04:16:58

Vous devrez probablement mettre un autre élément autour de la table et le style avec une bordure arrondie.

Le , document de travail spécifie que border-radius ne s'applique pas aux éléments de la table lorsque la valeur de border-collapse est collapse.

23
répondu user59200 2016-02-10 17:37:58

Comme Ian l'a dit, la solution est d'imbriquer la table dans un div et de la définir comme ceci:

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

Avec overflow:hidden, les coins carrés ne saignent pas à travers le div.

11
répondu Chris 2016-02-10 17:01:36

, au meilleur de ma connaissance, la seule manière de le faire serait de modifier toutes les cellules de la sorte:

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

Et puis pour obtenir la bordure en bas et à droite

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

:last-child n'est pas valide dans ie6, mais si vous utilisez border-radius je suppose que vous ne vous en souciez pas.

Modifier:

Après avoir regardé votre page d'exemple, il semble que vous puissiez contourner cela avec l'espacement et le remplissage des cellules.

Les épaisses bordures grises que vous voyez sont en fait l'arrière-plan de la table (vous pouvez le voir clairement si vous changez la couleur de la bordure rouge). Si vous définissez le cellspacing à zéro (ou de manière équivalente: td, th { margin:0; }), les "bordures" grises disparaîtront.

MODIFIER 2:

Je ne peux pas trouver un moyen de le faire avec une seule table. Si vous changez votre ligne d'en-tête en une table imbriquée, vous pourriez éventuellement obtenir l'effet que vous voulez, mais ce sera plus de travail, et non dynamique.

7
répondu Joel 2016-02-10 17:16:33

J'ai essayé une solution de contournement en utilisant les pseudo-éléments :before et :after sur les thead th:first-child et thead th:last-child

En combinaison avec l'emballage de la table avec un <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;
}

Voir jsFiddle

Fonctionne pour moi dans chrome (13.0.782.215) faites-moi savoir si cela fonctionne pour vous dans d'autres navigateurs.

6
répondu adardesign 2011-08-25 20:43:40

J'ai eu le même problème. Supprimer border-collapse entièrement et utiliser: cellspacing="0" cellpadding="0" dans le document html. exemple:

<table class="top_container" align="center" cellspacing="0" cellpadding="0">
5
répondu lars 2016-02-10 16:57:54

Les réponses données ne fonctionnent que lorsqu'il n'y a pas de frontières autour de la table, ce qui est très limitatif!

J'ai une macro dans SASS pour le faire, qui supporte pleinement les frontières internes externes et, obtenant le même style que border-collapse: collapse sans le spécifier réellement.

Testé dans FF / IE8 / Safari / Chrome.

Donne de belles bordures arrondies en CSS pur dans tous les navigateurs mais IE8 (se dégrade gracieusement) puisque IE8 ne supporte pas border-radius : (

Certains les anciens navigateurs peuvent exiger que les préfixes du fournisseur fonctionnent avec border-radius, alors n'hésitez pas à ajouter ces préfixes à votre code si nécessaire.

Cette réponse n'est pas la plus courte - mais elle fonctionne.

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

Pour appliquer ce style, il suffit de changer votre

<table>

Tag à ce qui suit:

<table class="roundedTable">

Et assurez-vous d'inclure les styles css ci-dessus dans votre HTML.

J'espère que cela aide.

4
répondu robbie613 2013-04-18 12:10:53

Pour une table bordée et défilante, utilisez ceci (remplacer les variables, $ textes de départ)

Si vous utilisez thead, tfoot ou th, il suffit de remplacer tr:first-child et tr-last-child et td avec eux.

#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>
4
répondu brauliobo 2013-06-08 15:26:01

Je viens d'écrire un ensemble fou de CSS pour cela qui semble fonctionner parfaitement:

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 !*/
4
répondu Rev 2016-02-10 17:03:23

En fait, vous pouvez ajouter votre table dans un div comme wrapper. puis affectez ces CSS codes à wrapper:

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

table {
  border-collapse: collapse;
}
4
répondu AngelHotxxx 2017-10-24 11:45:08

Solution avec border-collapse: séparé pour la table et l'affichage: inline-table pour tbody et 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;        
}
3
répondu Tommer 2012-11-28 18:32:53

Je suis nouveau avec HTML et CSS et je cherchais aussi une solution pour cela, voici ce que je trouve.

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
}

Je l'essaie, devinez ce que cela fonctionne:)

3
répondu ahmed ghanayem 2015-02-08 21:59:09

Trouvé cette réponse après avoir rencontré le MÊME PROBLÈME, MAIS trouvé que c'est assez simple: il suffit de donner la table overflow: hidden

Pas besoin d'un élément d'habillage. Certes, je ne sais pas si cela aurait fonctionné il y a 7 ans lorsque la question a été initialement posée, mais cela fonctionne maintenant.

3
répondu Akexis 2016-09-27 17:23:10

, j'ai commencé à expérimenter avec "affichage" et j'ai trouvé que: border-radius, border, margin, padding, dans un table sont affichés avec:

display: inline-table;

Par exemple

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

Mais nous devons définir un width de chaque colonne

tr td.first-column {
  width: 100px;
}
tr td.second-column {
  width: 860px;
}
2
répondu Astro 2012-10-19 22:01:28

Voici un exemple récent de la façon d'implémenter une table avec des coins arrondis de http://medialoot.com/preview/css-ui-kit/demo.html . il est basé sur les sélecteurs Spéciaux suggérés par Joel Potter ci-dessus. Comme vous pouvez le voir, il comprend également un peu de magie pour rendre IE un peu heureux. Il comprend des styles supplémentaires pour alterner la couleur des lignes:

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;
}
2
répondu Mac Cowell 2016-02-10 17:00:28

Table avec des coins arrondis et avec des cellules bordées. Utilisation de la solution @Ramon Tayag.

La clé est d'utiliser border-spacing: 0 comme il le souligne.

Solution utilisant 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;
  }
}
1
répondu Pere Pages 2018-08-25 17:17:06

Border-radius est maintenant officiellement pris en charge. Donc, dans tous les exemples ci-dessus, vous pouvez omettre le "-moz-" préfixe.

Une autre astuce consiste à utiliser la même couleur pour les lignes supérieure et inférieure que votre bordure. Avec les 3 couleurs identiques, il se fond et ressemble à une table parfaitement arrondie, même si ce n'est pas physiquement.

-1
répondu Hawk 2011-11-17 00:38:21

Je fais toujours de cette façon en utilisant 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;
    }
  }
}
-1
répondu Diego Mello 2018-05-11 16:54:45