Attention : ce document a changé d'adresse. L'ancienne adresse était http://www.e-t172.net/articles/round/, la nouvelle est http://articles.e-t172.net/round/.
Plusieurs solutions existent pour arrondir les coins d'un élément bloc en XHTML/CSS dont la largeur et la hauteur sont variables. Malheureusement, aucune n'est parfaite. Aperçu.
| Ceci est un example | ||
<table class="tablesample"> <tr class="top"> <td class="left"></td> <td class="center"></td> <td class="right"></td> </tr> <tr class="middle"> <td class="left"></td> <td class="center">Ceci est un example</td> <td class="right"></td> </tr> <tr class="bottom"> <td class="left"></td> <td class="center"></td> <td class="right"></td> </tr> </table>
.tablesample { width: 250px; border-collapse: collapse; }
.tablesample td { background-color: #F00; padding: 0px; }
.tablesample .top .left, .tablesample .top .right, .tablesample .bottom .left, .tablesample .bottom .right { width: 19px; height: 19px; background-color: #00FF00; }
.tablesample .top .left { background-image: url("corner_top_left.gif"); }
.tablesample .top .right { background-image: url("corner_top_right.gif"); }
.tablesample .bottom .left { background-image: url("corner_bottom_left.gif"); }
.tablesample .bottom .right { background-image: url("corner_bottom_right.gif"); }
| Niveau sémantique | Scandaleux | Détournement de la balise <table> |
|---|---|---|
| Séparation structure / présentation (maintenabilité) | Médiocre | |
| Compatibilité entre les navigateurs | Excellente | Fonctionne avec tous les navigateurs graphiques CSS1. |
| Souplesse et possibilités graphiques | Moyennes | Possibilité de créer un cadre graphique autour du bloc en spécifiant des arrière-plans aux cellules des côtés. Pas de possibilité de débordement sur les coins. |
Technique classique, obsolète et utilisée par les ignorants des normes pour créer des bords arrondis. Le seul avantage de la méthode est sa grande compatibilité.
<div class="floatsample"> <div class="top_left"></div> <div class="top_right"></div> <div class="content">Ceci est un exemple</div> <div class="bottom_left"></div> <div class="bottom_right"></div> </div>
.floatsample { width: 250px; background-color: #00FF00; }
.floatsample .top_left, .floatsample .top_right, .floatsample .bottom_left, .floatsample .bottom_right { height: 19px; background-repeat: no-repeat; }
.floatsample .top_left { width: 19px; float: left; background-image: url("corner_top_left.gif"); }
.floatsample .top_right { background-image: url("corner_top_right.gif"); background-position: right; }
.floatsample .bottom_left { width: 19px; float: left; background-image: url("corner_bottom_left.gif"); }
.floatsample .bottom_right { background-image: url("corner_bottom_right.gif"); background-position: right; }
.floatsample .content { background-color: #FF0000; }
| Niveau sémantique | Excellent | <div> est une balise neutre : aucun problème. |
|---|---|---|
| Séparation structure / présentation (maintenabilité) | Médiocre | Nécéssite que les <div> soient placés dans le document XHTML |
| Compatibilité entre les navigateurs | Bonne | Compatible avec IE6 et Gecko (non vérifié pour les autres) |
| Souplesse et possibilités graphiques | Médiocres | Pas de possibilité de cadre (graphique ou non graphique), pas de possibilité de débordement sur les coins. |
Une méthode satisfaisante bien que nécéssitant la modification du XHTML, si on n'est pas trop exigeant. Les coins gauches sont mis en float pour s'aligner en face des coins droits. Ces derniers ne sont pas mis en float en raison du problème de débordement qui compliquerait les choses, notamment avec les coins du bas. Enfin, notons que la couleur d'arrière-plan n'est pas fixée sur le <div> englobant afin d'éviter un bug de rendu disgrâcieux sous IE. Il faudra donc appliquer la couleur de votre bloc sur chaque <div>, par exemple en faisant .block div { background-color: example; }.
<div class="relsample"> <div class="top_left"></div> <div class="top_right"></div> <div class="content">Ceci est un exemple</div> <div class="bottom_left"></div> <div class="bottom_right"></div> </div>
.relsample { width: 250px; position: relative; background-color: #FF0000; }
.relsample .top_left, .relsample .top_right, .relsample .bottom_left, .relsample .bottom_right { height: 19px; width: 19px; background-repeat: no-repeat; position: absolute; background-color: #00FF00; }
.relsample .top_left { top: 0px; left: 0px; background-image: url("corner_top_left.gif"); z-index: 0; }
.relsample .top_right { top: 0px; right: 0px; background-image: url("corner_top_right.gif"); z-index: 1; }
.relsample .bottom_left { bottom: 0px; left: 0px; background-image: url("corner_bottom_left.gif"); z-index: 2; }
.relsample .bottom_right { bottom: 0px; right: 0px; background-image: url("corner_bottom_right.gif"); z-index: 3; }
.relsample .content { position: relative; padding: 12px; z-index: 4; }
| Niveau sémantique | Excellent | <div> est une balise neutre : aucun problème. |
|---|---|---|
| Séparation structure / présentation (maintenabilité) | Médiocre | Nécéssite que les <div> soient placés dans le document XHTML |
| Compatibilité entre les navigateurs | Bonne | Compatible avec IE6 et Gecko (non vérifié pour les autres) |
| Souplesse et possibilités graphiques | Excellentes | Possibilité de déborder sur les coins pour occuper tout l'espace disponible (voir example) en jouant sur les z-index, possibilité de cadre en bordures CSS (dans ce cas il faut créer un sous-bloc du bloc content, puis lui appliquer un margin, puis définir la bordure sur ce sous-bloc) ou graphique (dans ce cas il faut créer des <div> et les positionner pour couvrir les côtés, puis leur appliquer l'arrière plan qui représentera le cadre, puis superposer les coins à ces côtés avec le z-index). |
Une méthode de même style que la propriété float, mais cette fois ci en utilisant des propriétés de positionnement relativement au conteneur. Avantage principal : les possibilités graphiques sont bien plus intéressantes alors que le XHTML ne bouge quasiment pas par rapport à la méthode précédente.

<div class="alsasample"> <img class="top_right" src="corner_top_right.gif" alt="" /> <div class="content"> Ceci est un example </div> <div class="bottom"><img class="bottom_right" src="corner_bottom_right.gif" alt="" /></div> </div>
.alsasample img { border: none; }
.alsasample { position: relative; padding-top: 19px; width: 250px; background: #FF0000 url("corner_top_left_alsa.gif") left top no-repeat; }
.alsasample .bottom { background: #fff url("corner_bottom_left_alsa.gif") left bottom no-repeat; height: 19px; }
.alsasample .top_right { position: absolute; right: 0; top: 0; height: 19px; }
.alsasample .bottom_right { float: right; height: 19px; }
| Niveau sémantique | Médiocre | Détournement de la balise <img> à des fins esthétiques |
|---|---|---|
| Séparation structure / présentation (maintenabilité) | Médiocre | Nécéssite des modifications du document XHTML |
| Compatibilité entre les navigateurs | Bonne | Compatible avec IE6 et Gecko (non vérifié pour les autres) |
| Souplesse et possibilités graphiques | Maigres | Pas de possibilité de débordement sur les coins pour occuper tout l'espace disponible. Possibilité de tracer un cadre non graphique (ou graphique mais uniquement sur les côtés haut et bas). |
Cette méthode est proposée par Raphaël Goetter sur son site Alsacréations pour créer un cadre aux bordures arrondies en XHTML/CSS. Cette méthode consiste en un mélange de propriétés float et de positions relatives. Malheureusement, elle est moins attrayante que les autres dans le sens où la sémantique n'est pas pleinement respectée, la balise <img> étant exploitée afin d'afficher les coins droits. Notons aussi que l'image d'arrière-plan gauche est très longue afin qu'elle recouvre en permanence le fond, ce qui s'apparente à du bricolage. De plus cette technique n'offre qu'une seule possibilité graphique intéressante. Bref, on lui préfera largement la méthode des positions relatives.
<div class="fullsample">Ceci est un example</div>
.fullsample { width: 250px; border-radius: 10px 10px; -moz-border-radius: 10px; background-color: #F00; padding: 5px; }
Aucune.
| Niveau sémantique | Excellent | Aucune balise détournée |
|---|---|---|
| Séparation structure / présentation (maintenabilité) | Excellent | Fonctionne sur tout bloc sans modification du XHTML |
| Compatibilité entre les navigateurs | Médiocre | Fonctionne uniquement sous Gecko et les navigateurs "avant-gardistes" qui gèrent par avance le CSS3 |
| Souplesse et possibilités graphiques | Moyennes | Possibilité de déborder sur les coins. Possibilité d'appliquer un cadre CSS (mais pas de bordure graphique). |
Cette méthode utilise des propriétés CSS non standard. Le document produit ne sera donc pas valide CSS2. Cette méthode utilise une combinaison de deux propriétés : la propriété propriétaire -moz-border-radius, fonctionnant uniquement sous le moteur Gecko, permettant d'arrondir les bordures avec le rayon spécifié; et une propriété CSS3 (donc encore à l'état de brouillon) qui n'est actuellement prise en compte que par une poignée de navigateurs qui ont choisi de supporter à l'avance CSS3. Notons au passages que Gecko ne lisse pas les coins, ce qui n'est pas fabuleusement esthétique.
Au final, aucune méthode n'est parfaite. Seule la dernière méthode sépare réellement le contenu de la présentation, mais elle trop peu compatible pour être utilisable. Au final, la meilleure solution disponible tous objectifs confondus est la méthode des positions relatives, qui est sémantiquement bonne et dispose de beaucoup de possibilités graphiques tout en gardant une bonne compatibilité.
La méthode CSS Only n'est envisageable que dans le cas où l'arrondissement des blocs présente un plus et ne fait pas partie intégrante du design. On peut alors tolérer que les blocs restent carrés sous IE6 par exemple. Gardez cependant à l'esprit que cette méthode n'est pas grammaticalement valide CSS2.
Ce document a été conçu et écrit par e-t172. Toutes les techniques présentées ici ont été découvertes et testées par moi-même, mis à part la méthode Alsacréations.
Document valide XHTML et valide CSS2 (excepté le rendu de la dernière méthode).