• 4 heures
  • Facile

Ce cours est visible gratuitement en ligne.

Vous pouvez être accompagné et mentoré par un professeur particulier par visioconférence sur ce cours.

J'ai tout compris !

Mis à jour le 08/01/2018

Repoussons les limites des bordures

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

Les bordures forment un point essentiel d'un design Web. Cependant, bien étrangement, il n'est pas possible de faire énormément de choses avec...
Entre choisir la couleur, la taille et le type de bordure, nous étions relativement limités et il fallait souvent avoir recours à différentes techniques peu gracieuses pour faire tout ce qu'on souhaitait.

Mais ça, c'était avant CSS3 qui nous apporte de nouvelles fonctionnalités bien pratiques !

Une image en tant que bordure

Une propriété mal gérée

Dans le cas d'un design complexe, il se peut qu'une simple bordure ne suffise pas à faire notre bonheur. Afin d'être plus versatile que ses ancêtres, CSS3 nous propose désormais d'appliquer une image sur nos bordures !

Le nom de la propriété CSS3 qui nous permet de réaliser ce tour de force s'appelle simplement border-image. La première chose que vous devez savoir à propos de cette propriété est qu'elle est encore mal gérée par les navigateurs... :(

Si Google Chrome l'interprète correctement mais pas dans sa totalité, Firefox, Safari et Opera ont parfois des comportements étranges.
Sans vouloir être médisant, Internet Explorer est de nouveau le vilain petit canard puisqu'il ignore purement et simplement border-image...

Nous allons donc en parler très rapidement, en espérant que son support soit amélioré dans les mois à venir !

Le principe : découpons, cisaillons !

Si cette propriété est supportée de façon bancale, c'est probablement parce qu'elle est complexe à mettre en place.
L'idée principale est de fournir une image (tout comme background-image), de la découper en petits morceaux et d'afficher ces derniers en tant que bordure : que de travail pour nos pauvres navigateurs !

Dans un premier temps, il nous faut donc une image. Première difficulté, celle-ci doit être construite d'une manière bien particulière. Je vous invite à regarder ci-dessous l'image que nous utiliserons pour nos exemples :

Image utilisateur

On ne se moque pas je vous prie, c'est très joli. :-°

Il est nécessaire que vous compreniez la structure de cette image si vous souhaitez comprendre le fonctionnement de border-image.
Première chose évidente, elle est divisée en neuf parties : huit figures entourent une neuvième, verte dans notre exemple, se trouvant au centre.

Imaginez que cette image représente un élément HTML à part entière : la forme centrale serait alors le contenu de notre élément, les huit autres figures seront ses bordures.
C'est de cette façon que border-image analysera cette image : il la découpera pour récupérer chacune des figures et les placer en tant que bordures de l'élément HTML affecté !

Cependant, le navigateur ne peut pas deviner comment il doit s'y prendre pour découper l'image qu'on lui donne : il nous faut donc tout lui dire.
Pour ce faire, voyons (enfin !) comment définir la propriété border-image :

-moz-border-image: url('monImage.png') top right bottom left;
-o-border-image: url('monImage.png') top right bottom left;
-webkit-border-image: url('monImage.png') top right bottom left;
border-image: url('monImage.png') top right bottom left;

/* Comme d'habitude, nous utiliserons par la suite
la version sans préfixe, pour plus de clarté. */

Dans l'exemple ci-dessus, vous pouvez constater la présence de quatre mots-clés : top, right, bottomet left.

Ces mots-clés doivent être remplacés par la taille de la bordure telle qu'elle apparaît sur votre image. Ainsi, top sera remplacé par la taille de la bordure supérieure, right par celle de la bordure de droite, etc.

Pour notre image, voici ce que ça donnerait (en zoomant un peu pour mieux voir) :

Image utilisateur
border-image: url('monImage.png') 16 18 11 10;

Essayer !

Je vous invite grandement à cliquer sur le lien ci-dessus afin de tester notre code afin de voir le rendu généré.

Déjà, notre image étant assez petite, les bordures ne sont pas très visibles : il est possible d'arranger ça avec la propriété border-width :

border-width: 10px;
border-image: url('monImage.png') 16 18 11 10;

Essayer !

Autre surprise si vous n'utilisez pas Google Chrome : il y a notre forme centrale, le rectangle vert, en plein milieu de notre élément HTML. o_O
Ceci est tout simplement un bug : comme je l'ai déjà dit, cette propriété n'est pas très bien supportée. Les normes W3C indiquent pourtant bien que la forme centrale ne doit pas être affichée :

Citation : W3C

This property specifies inward offsets from the top, right, bottom, and left edges of the image, dividing it into nine regions: four corners, four edges and a middle. The middle image part is discarded (treated as fully transparent)

Lien vers la source

Cependant, il faut s'y faire : nous travaillons depuis le début de ce tutoriel sur une technologie amenée à évoluer, il est normal de rencontrer ce genre de comportement non prévu !

Il existe une solution très simple pour ne pas afficher la partie centrale de notre image : la rendre transparente via un logiciel graphique : :p

Image utilisateur

Essayer !

Les différents modes d'affichage : pour des bordures encore plus personnalisées

Si vous avez testé les exemples (et je suis sûr que vous avez testé les exemples, n'est-ce pas ? :-° ), vous avez pu constater que les figures de nos bordures sont étirées : cela ne donne pas un résultat particulièrement hideux, mais ce n'est pas forcément ce qu'on attendait.

border-image nous propose différents modes d'affichages afin de modifier ce comportement, celui par défaut étant stretch.
Cependant, encore une fois, ces modes ne sont pas tous bien gérés par les navigateurs (voire pas du tout !), ce qui nous limite encore beaucoup...

Un mode d'affichage se précise après la série des quatre valeurs que nous définissons : le premier que nous allons voir est repeat:

border-image: url('monImage.png') 16 18 11 10 repeat;

Essayer !

Spécifier ce mot-clé permet donc de répéter les figures le long des bordures plutôt que de les étirer. Le principe est assez simple, il me semble inutile de l'expliquer davantage.

Cependant, vous avez pu constater que les figures sont découpées en plein milieu lorsqu'elles atteignent les coins (cela se voit moins sur Opera). Il est possible de corriger ce comportement avec le mot-clé round : grâce à ce mot-clé, les figures sont un peu étirées afin de ne pas être coupées (mais il ne semble pas être pris en compte par Google Chrome et Safari...)

Essayer !

Le W3C définit un dernier mot-clé, space, qui a le même but que round : éviter que des figures soient coupées. Sa façon de procéder diffère par le fait qu'il ajoute des espaces vides entre les figures plutôt que de les étirer.
Cependant, space n'est pour le moment supporté par aucun navigateur... :(

Sachez qu'il est possible de spécifier deux modes d'affichage : le premier sera alors appliqué aux bordures supérieures et inférieures, tandis que le second affectera les bordures gauches et droites.

border-image: url('monImage.png') 16 18 11 10 stretch repeat;

Essayer !

Arrondissons les angles

Créer des formes à bordures arrondies est probablement la possibilité la plus attendue de CSS3.
La propriété qui nous permet de réaliser facilement ce vieux rêve de designer Web est appelée border-radius : elle est attendue depuis si longtemps qu'elle a été une des premières fonctionnalités de CSS3 à avoir été normalisées !

Ce qui est cool pour nous, c'est que border-radius peut s'utiliser de plusieurs façons : le plus simplement possible en ne fournissant qu'une valeur ou de façon bien plus complexe pour faire des angles biscornus. :D

La façon simple

La manière la plus basique d'utiliser cette propriété est de lui fournir une simple valeur en pixels : ainsi, tous les coins de l'élément affecté seront arrondis selon cette valeur.

border-radius: 30px;

Essayer !

Et c'est tout. :D
Bon, cela dit, c'est bien joli tout ça mais il serait bon de comprendre ce qu'il s'est passé : pourquoi la valeur 30px nous donne ce genre d'arrondis ?

Imaginons que des cercles se trouvent dans chacun des quatre coins de notre élément : l'arrondi se fera selon le périmètre de ces cercles.
Ainsi, si nous reprenons notre exemple, la forme de nos coins sont définis selon le périmètre de cercles ayant un rayon de 30 pixels.

Si ces termes géométriques vous ont perdu, jetez un œil à l'image ci-dessous : elle devrait éclaircir tout ça. :)

Image utilisateur

Ce n'est pas encore parfaitement clair ?
Voyons un autre exemple dans ce cas... Que diriez-vous d'avoir des arrondis différents aux quatre coins ?

border-radius: 30px 10px 100px 50px;

Essayer !

Et la petite image explicative qui va avec :

Image utilisateur

Plutôt simple d'utilisation, n'est-ce pas ? :)

Des arrondis plus complexes

Je viens de vous dire que les coins arrondis suivent toujours le périmètre d'un cercle : ce n'est pas tout à fait vrai... :-°

Les angles arrondis, ça a beau être joli, ça peut vite devenir monotone. border-radius nous propose ainsi une petite fonctionnalité nous permettant de personnaliser au maximum nos coins : l'utilisation d'ellipses en plus des cercles !

Le concept est le même que pour les cercles que nous venons de voir : les arrondis se formeront selon le périmètre des ellipses que nous définirons. Pour ce faire, la syntaxe est un peu particulière :

border-radius: 50px / 30px;

Essayer !

Vous le voyez, le principe est exactement le même que pour les cercles, si ce n'est qu'on précise deux valeurs séparées par le symbole /.
La première valeur définit ainsi la largeur du rayon horizontal de l'ellipse tandis que la seconde indique la hauteur de son rayon vertical.

Image utilisateur

Tout comme les cercles, il est bien entendu possible avec les ellipses de spécifier différents arrondis pour chaque coin.
La manière de faire est similaire à ce qu'on a déjà vu :

border-radius: 50px 10px 100px 80px / 30px 40px 20px 35px;

Essayer !

Les quatre premières valeurs définissent les rayons horizontaux de chacune des quatre ellipses générées (tout d'abord celle située en haut à gauche, puis celle en haut à droite, celle en bas à droite et enfin celle en bas à gauche). On retrouve ensuite notre symbole / puis quatre dernières valeurs décrivant les hauteurs des rayons des ellipses.

C'est flou dans votre tête ? Je vous invite donc à observer cette dernière image explicative, elle devrait bien vous aider à comprendre. :)

Image utilisateur

border-radius et les tableaux...

Si vous avez essayé d'aller plus loin que ce tutoriel en appliquant des coins arrondis sur d'autres éléments que des <div>, vous êtes peut-être tombé sur le cas épineux des tableaux.

Un petit exemple pour bien comprendre le souci :

/* Le tableau en lui-même */
table
{
    width: 80%;  /* Largeur dynamique */
    text-align: center; /* On centre le contenu */
    margin: auto;  /* On centre le tableau */
    margin-top: 100px; /* Histoire de ne pas trop le coller au bord supérieur de l'écran */
    border: 5px solid #000; /* Une bordure classique */
    border-collapse: collapse; /* On colle les cellules entre elles */
    border-radius: 30px; /* Coins arrondis ! */
}
			
/* Les lignes du tableau */
tr{ background-color: #e5f5f9; /* Un léger fond bleu */ }
		
/* Les lignes impaires du tableau */
tr:nth-child(odd){ background-color: #bfe7f1; /* Un fond bleu plus sombre */ }

Essayer !

Et là, badaboum : les coins ne sont pas arrondis ! :(

En effet, lorsqu'un tableau a sa propriété border-collapse définie à collapse, border-radius n'a plus aucun effet...

Voyez le résultat quand on supprime cette propriété :

/* Le tableau en lui-même */
table
{
    width: 80%;  /* Largeur dynamique */
    text-align: center; /* On centre le contenu */
    margin: auto;  /* On centre le tableau */
    margin-top: 100px; /* Histoire de ne pas trop le coller au bord supérieur de l'écran */
    border: 5px solid #000; /* Une bordure classique */
    /* border-collapse: collapse; On commente border-collapse pour ne plus l'utiliser */
    background-color: red; /* Un fond rouge pour bien voir que les cellules ne sont plus collées */
    border-radius: 30px; /* Coins arrondis ! */
}
			
/* Reste du CSS */

Essayer !

Cette fois, c'est bon, notre tableau est bien arrondi mais, comme prévu, les cellules ne sont plus collées les unes aux autres...
Alors comment faire ?

Il existe plusieurs solutions, certaines plus élégantes que d'autres.

La première consiste à ne pas appliquer border-radius sur le tableau, mais plutôt sur sa première et dernière ligne (je vous rappelle que nous avons vu tout un chapitre sur les sélecteurs CSS3 ;) ). Cette solution me parait bien compliquée pour peu de choses.

La seconde solution est largement répandue sur Internet : elle consiste à ajouter directement dans le code HTML l'attribut cellspacing="0" à notre balise <table>. Cette technique fonctionne parfaitement mais elle a un défaut majeur : elle n'est pas valide W3C selon les normes HTML5...

Je vous propose donc une dernière solution, qui non seulement fonctionne et qui est valide W3C mais qui, en plus, se résume à une seule ligne : utiliser la propriété CSS border-spacing !
En lui donnant une valeur de 0, nous indiquons ainsi un espace de 0 pixel entre les cellules, ce qui revient à simuler border-collapse, tout en autorisant border-radius. :D

/* Le tableau en lui-même */
table
{
    width: 80%;  /* Largeur dynamique */
    text-align: center; /* On centre le contenu */
    margin: auto;  /* On centre le tableau */
    margin-top: 100px; /* Histoire de ne pas trop le coller au bord supérieur de l'écran */
    border: 5px solid #000; /* Une bordure classique */
    border-spacing: 0; /* "Simulation" de border-collapse */
    background-color: red; /* Un fond rouge, au cas où... */
    border-radius: 30px; /* Coins arrondis ! */
}
			
/* Reste du CSS */

Essayer !

Mais... Pourquoi les lignes dépassent de la bordure ?

Vous n'êtes probablement pas passés à côté de ce "détail". Ce petit problème s'explique par le fait que nous appliquons des bords arrondis sur le tableau en lui-même, pas sur ce qu'il contient.
Ainsi, les lignes du tableau, qui sont les éléments enfants du tableau, ne sont pas affectées par la propriété : il n'existe pas d'héritage avec border-radius !
Par conséquent, ce souci ne devrait pas s'appliquer qu'aux tableaux, mais à tout élément ayant des enfants...

Une solution simple et élégante est d'utiliser la propriété overflow: hidden; sur le conteneur principal. Pour rappel, cette propriété permet de cacher tout ce qui dépasse de l'élément affecté :

/* Le tableau en lui-même */
table
{
    width: 80%;  /* Largeur dynamique */
    text-align: center; /* On centre le contenu */
    margin: auto;  /* On centre le tableau */
    margin-top: 100px; /* Histoire de ne pas trop le coller au bord supérieur de l'écran */
    border: 5px solid #000; /* Une bordure classique */
    border-spacing: 0; /* "Simulation" de border-collapse */
    overflow: hidden; /* On cache ce qui dépasse */
    border-radius: 30px; /* Coins arrondis ! */
}
			
/* Reste du CSS */

Essayer !

Bon, si vous utilisez Google Chrome, vous devriez être contents. Dans le cas contraire, vous vous demandez sûrement pourquoi rien n'a changé... :euh:
Enfin, pour une raison inconnue, il existe un bug sur tous les navigateurs excepté Google Chrome : overflow: hidden; ne semble pas être pris en compte dans cette situation...

Il existe un moyen de contourner ce problème pour Firefox : il suffit d'appliquer la propriété position: relative; aux lignes du tableau :

/* Reste du CSS */

/* Les lignes du tableau */
tr
{
    background-color: #e5f5f9; /* Un léger fond bleu */
    position: relative;
}
	
/* Reste du CSS */

Essayer !

Malheureusement, cette astuce ne fonctionne pas pour les autres navigateurs...
Pour le moment, la seule solution pour n'oublier personne est donc d'appliquer la première méthode dont je vous ai parlé un peu avant : appliquer les bords arrondis non pas sur le tableau en lui-même, mais sur ses première et dernière lignes... :(

Un petit TP pour s'amuser

Histoire de finir ce chapitre sur une note amusante, je vous invite à exploiter à fond la propriété border-radius.

Juste avec des <div> et du CSS3, je vous invite à essayer de former cette image :

Image utilisateur

En plus gros, bien entendu. :-°

Je vous fournis le code HTML : vous n'avez qu'à appliquer du CSS dessus :

<!DOCTYPE html>
<html lang="fr">
    <head>
        <title>Smiley CSS3</title>
        <meta charset="utf-8" />
        <style>
            html,body
            {
                margin: 0;
                padding: 0;
                background-color: #e3e3e3;
            }
            
            /* Votre code CSS ici */
        </style>
    </head>
    <body>
        <div id="tete">    
            <div id="oeil_gauche" class="oeil">
                <div class="pupille"></div>
            </div>
            <div id="oeil_droit" class="oeil">
                <div class="pupille"></div>
            </div>
            <div id="bouche">
                <div id="interieur_bouche">
                    <div id="langue"></div>
                </div>
            </div>
        </div>
    </body>
</html>

Bien entendu, vous n'êtes pas obligés de réaliser exactement le même smiley que l'image proposée (il contient quelques difficultés pas si simples à résoudre...) : soyez créatifs, faites-vous plaisir !

Pour placer précisément les différents éléments constituant le smiley, je vous conseille d'utiliser la propriété position: absolute; : vous pourrez ainsi tout déplacer au pixel près.

Je vous propose ci-dessous ma solution : si vous avez essayé de faire un smiley différent de celui proposé, elle ne correspondra logiquement pas.

#tete
{
    width: 500px;   /* Je veux faire un GROS smiley =D */
    height: 500px;
    margin: auto;
    margin-top: 30px;
    border: 10px solid #000;
    position: relative;
    background-color: #fedd58;
    border-radius: 250px; /* Pour une tête bien ronde. Notez qu'on
                          aurait pu mettre 50% : je vous laisse
                          comprendre pourquoi */
}

#tete div
{
    /* On met tous les éléments du smiley en absolute */
    position: absolute;
    border: 7px solid #000;
}

.oeil
{
    width: 120px;
    height: 90px;
    background-color: #fff;
    /* Les yeux ne sont pas des cercles parfaits ! */
    border-radius: 70% 58% 12% 12% / 75% 75% 50% 50%;
    top: 115px;
}

#oeil_gauche{left: 30px;}
#oeil_droit{right: 115px;}

.pupille
{
    background-color: #000;
    width: 50px;
    height: 50px;
    border-radius: 50px;
    right: 1px;
    top: 1px;
}

#tete #bouche
{
    /* Ceci permet d'avoir le petit trait qui
    dépasse à gauche de la bouche */
    border: 0;
    border-top: 7px solid #000;
    width: 325px;
    height: 200px;
    top: 285px;
    left: 45px;
}

#tete #interieur_bouche
{
    background-color: #871943;
    right: -20px;
    top: -7px;
    height: 170px;
    width: 320px;
    border-radius: 5% 7% 70% 58% / 12% 50% 75% 115%;
    /* On cache ce qui dépasse de la bouche (la langue, quoi...) */
    overflow: hidden;
}

#tete #langue
{
    border: 0;
    background-color: #fbbfdf;
    height: 150px;
    width: 150px;
    right: 30px;
    bottom: -70px;
    border-radius: 75px;
}

Essayer !

Et voilà, il n'est pas beau notre smiley ? :D
Bon, je l'admets, encore une fois nous avons un souci d'élément qui dépasse : en fonction de votre navigateur, vous verrez ou non la langue dépasser de la bouche, pour un effet vraiment pas joli...

Cependant, vous pouvez constater que seule la moitié du cercle formant la langue n'est visible : overflow: hidden; a donc fonctionné à moitié...

Ceci, mes amis, est un bug similaire à ce qu'on a vu tout à l'heure avec notre tableau, mais ce n'est visiblement pas le même : en effet, cette fois tout fonctionne correctement sur Firefox et Internet Explorer ! o_O

Ce TP est donc un excellent enseignement quant à CSS3 : si dans un premier temps les propriétés semblent bien maîtrisées par tous les navigateurs, on se rend compte en faisant des choses plus avancées que des bugs trainent toujours un peu partout... Utilisez donc tout ce qui nous est offert avec parcimonie !

Ha oui, autre chose : ce TP n'est là que pour un but pédagogique. Il est déconseillé de réaliser ce genre de chose sur un véritable site Web !
Pourquoi ?
Car les <div> n'ont pas été créées pour afficher des dessins de cette façon : d'un point de vue strictement sémantique, c'est tout simplement affreux !

Cela dit, ça reste plutôt rigolo à réaliser, et c'est un bon moyen d'appliquer ce qu'on vient d'apprendre. :)

Comme vous avez pu le constater, les nouveautés sur les bordures sont très intéressantes, malgré des soucis de compatibilité plus ou moins gênants.
Les principaux problèmes arrivent lorsqu'on souhaite utiliser en profondeur une propriété : bien souvent, les navigateurs ne gèrent plus très bien les normes, contrairement à ce qu'ils affirment tous !

La propriété border-image est particulièrement touchée par ces problèmes, il est donc conseillé de l'utiliser de façon la plus basique qui soit.

border-radius, quant à elle, est bien plus épargnée et nous permet de faire de jolies choses de manière tout à fait standard. N'hésitez pas à l'utiliser... Mais pas pour dessiner des smileys, qu'on soit bien d'accord là-dessus. ;)

Cette partie n'est pas encore terminée et d'autres choses sont en prévision !

Il nous reste en effet plusieurs aspects de CSS3 à découvrir, notamment en ce qui concerne les mises en forme des textes.

Ce big-tuto n'est donc pas achevé, loin de là !

En plus de la fin de la première partie, une seconde fera également son apparition : celle-ci traitera des transitions et autres transformations dynamiques :) .

A très bientôt donc pour une mise à jour de ce tutoriel !

Exemple de certificat de réussite
Exemple de certificat de réussite