web-dev-qa-db-fra.com

La propriété border-radius et border-collapse de CSS3: ne pas mélanger. Comment utiliser border-radius pour créer une table réduite aux angles arrondis?

Éditer - Titre original: Existe-t-il un autre moyen d’obtenir border-collapse:collapse dans CSS (afin d’avoir une valeur arrondie, arrondie table d'angle)?

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

J'essaie de créer un tableau avec des angles arrondis à l'aide de la propriété CSS3border-radius. Les styles de table que j'utilise ressemblent à ceci:

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

Voici le problème. Je souhaite également définir la propriété border-collapse:collapse. Lorsque cette option est définie, border-radius ne fonctionne plus. Existe-t-il un moyen basé sur CSS pour obtenir le même effet que border-collapse:collapse sans l'utiliser?

Modifications:

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

Il semble qu’une grande partie du problème réside dans le fait que définir des angles arrondis sur la table n’affecte pas les angles des éléments td. Si la table était d'une seule couleur, cela ne poserait pas de problème, car je pourrais simplement arrondir les coins supérieurs et inférieurs td pour la première et la dernière ligne respectivement. Cependant, j'utilise différentes couleurs d'arrière-plan pour le tableau afin de différencier les en-têtes et les bandes, de sorte que les éléments intérieurs td affichent également leurs coins arrondis.

Résumé des solutions proposées:

Entourer la table avec un autre élément aux coins arrondis ne fonctionne pas, car les coins carrés de la table "traversent".

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

En bas td les coins restent carrés après la remise à zéro de l'espacement des cellules.

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

Solutions possibles:

Les tableaux sont générés en PHP, je pourrais donc simplement appliquer une classe différente à chacun des th/tds extérieurs et styliser chaque coin séparément. Je préférerais ne pas le faire car ce n'est pas très élégant et c'est un peu pénible à appliquer à plusieurs tables, alors continuez à faire des suggestions.

La solution possible 2 consiste à utiliser JavaScript (jQuery, en particulier) pour styliser les coins. Cette solution fonctionne également, mais pas tout à fait ce que je recherche (je sais que je suis difficile). J'ai deux réserves:

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

Je sais qu'essayer de faire cela avec CSS3 aujourd'hui peut sembler inutile, mais j'ai mes raisons. Je tiens également à souligner que ce problème découle de la spécification w3c, et non d’un support médiocre de CSS3. Toute solution restera donc pertinente et utile lorsque le support de CSS3 sera plus étendu.

292
vamin

Je l'ai compris. Vous devez juste utiliser des sélecteurs spéciaux.

Le problème avec les angles arrondis de la table était que les éléments td ne devenaient pas également arrondis. Vous pouvez résoudre ce problème 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 se passe bien, sauf qu'il reste le problème de border-collapse: collapse tout casser. Une solution de contournement consiste à définir cellspacing="0" dans le code HTML à la place (merci, Joel ).

215
vamin

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

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;
}
76
cmrd.Kaash

Si vous voulez une solution uniquement en CSS (inutile de définir cellspacing=0 dans le code HTML) qui autorise les bordures 1px (ce que vous ne pouvez pas utiliser avec la solution border-spacing: 0], je préfère effectuer les opérations suivantes: :

  • Définissez un border-right et border-bottom pour vos cellules de tableau (td et th)
  • Donnez aux cellules de la première ligne un border-top
  • Donnez aux cellules de la première colonne un border-left
  • À l'aide des sélecteurs first-child et last-child, arrondissez les coins appropriés pour les cellules du tableau dans 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>
57
vxsx

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

27
Cesar

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

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

23
user59200

Comme Ian l'a dit, la solution consiste à imbriquer la table dans une div et à la définir comme suit:

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

Avec overflow:hidden, les coins carrés ne traverseront pas le div.

14
Chris

À ma connaissance, le seul moyen de le faire serait de modifier toutes les cellules de la manière suivante:

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

Et puis pour obtenir la frontière 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.

EDIT:

Après avoir examiné votre page d'exemple, il semble que vous puissiez peut-être contourner ce problème avec l'espacement et le remplissage des cellules.

Les épaisses bordures grises que vous voyez sont en réalité l’arrière-plan du tableau (vous pouvez le voir clairement si vous changez la couleur de la bordure en rouge). Si vous réglez le nombre de cellules à zéro (ou l'équivalent: td, th { margin:0; }), les "bordures" grises disparaîtront.

EDIT 2:

Je ne peux pas trouver un moyen de faire cela avec une seule table. Si vous modifiez votre ligne d'en-tête en une table imbriquée, vous pourrez peut-être obtenir l'effet souhaité, mais ce sera plus de travail et non dynamique.

7
Joel

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

En combinaison avec le wrapping 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 les autres navigateurs.

6
adardesign

En fait, vous pouvez ajouter votre table à l’intérieur d’un div comme enveloppe. puis assignez ces codes CSS au wrapper:

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

table {
  border-collapse: collapse;
}
5
AmerllicA

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

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

Utilisez ceci pour un tableau avec bordure et défilement (remplacez les variables, $ textes de départ)

Si vous utilisez thead, tfoot ou th, il vous 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
brauliobo

Je viens juste 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
JacobTheDev

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

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

Testé dans FF/IE8/Safari/Chrome.

Donne de jolies bordures arrondies en CSS pur dans tous les navigateurs sauf IE8 (se dégrade gracieusement), car IE8 ne prend pas en charge border-radius :(

Certains les anciens navigateurs peuvent nécessiter des préfixes de vendeurs pour fonctionner 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, changez simplement votre

<table>

balise à la suivante:

<table class="roundedTable">

et veillez à inclure les styles CSS ci-dessus dans votre code HTML.

J'espère que cela t'aides.

4
robbie613

J'ai trouvé cette réponse après avoir rencontré le même problème, mais c'est assez simple: il suffit de donner le débordement de la table: hidden

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

3
Akexis

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

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

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;
  }
}
_
3
Pere Pages

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 ça marche :)

3
ahmed ghanayem

Solution avec border-collapse: séparer pour la table et afficher: 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
Tommer

Voici un exemple récent de la manière de mettre en œuvre une table avec des angles arrondis à partir 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 constater, cela inclut également de la magie pour rendre un peu plus heureux IE. Il inclut 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
Mac Cowell

J'ai commencé à expérimenter avec "display" 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 une width de chaque colonne

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

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;
    }
  }
}
0
Diego Mello