Envoyer un mail à l’auteur
xavier at ultra-fluide.com
Cet article a pour origine notre participation à un concours de code (dont nous sommes fier d'avoir été le lauréat) pour lequel il s'agissait de reproduire, sans image, cette oeuvre de Mondrian (ce lien ouvre une fenêtre popup). Les curieux trouveront sur ces pages le règlement et le résultat de ce concours.
Le challenge était donc de représenter des segments obliques séparant des aplats de couleurs par du code web compatible avec les principaux navigateurs. L'une des solutions, la plus simple probablement, consiste à exploiter les bordures d'éléments blocks CSS.
Nous présentons et exploitons dans cet article la ligne oblique apparaissant à la rencontre des bordures encadrant les éléments blocks CSS. Un élément block est un rectangle, et ses bords lorsqu'ils sont tracés se rejoignent sur une intersection oblique. En jouant sur la taille du rectangle, les épaisseurs des différents bords ainsi que leurs couleurs, un nombre infini d'effets peuvent être obtenus.
Lorsque l'épaisseur des bords horizontaux et verticaux est identique l'oblique est à 45 degrés. L'élément choisi pour notre exemple est l'élément paragraphe <p> mais n'importe quel élément acceptant des bordures et ayant implicitement ou explicitement la propriété {display : block} conviendra.
Voici un premier élément block avec des bords de 60 pixels d'épaisseur. | |
élément block
|
|
Lorsque l'élément est vide, et que les bords se touchent. | |
|
|
En modifiant l'ordre des couleurs. | |
|
|
Partant des exemples précédents, il est possible d'obtenir des segments d'inclinaisons variables en jouant sur le rapport des épaisseurs des bordures. Ensuite la superposition de segment permet d'atteindre n'importe quelle forme géométrique.
La bordure du bas a une épaisseur nulle. | |
|
|
Les bordures du bas et de droite ont une épaisseur nulle. | |
|
|
Les bordures du bas et de droite ont une épaisseur nulle. Le bord gauche est 2 fois plus épais que le bord haut : le segment se rapproche de l'horizontale. | |
|
|
Les bordures du bas et de droite ont une épaisseur nulle. Le bord haut est 2 fois plus épais que le bord gauche : le segment se rapproche de la verticale. | |
|
|
En superposant 2 blocks et en utilisant la propriété
transparent pour la couleur de bordure on peut obtenir le tracé d'un
filet oblique. Malheureusement, IE ne reconnaît pas la propriété transparent pour une bordure (la propriété transparent a été introduite avec la norme CSS 2 en 1998). Pour IE la valeur transparent est traduite par la couleur noire, cet exemple ne fonctionne donc pas sous IE. |
|
|
|
Une publicité pour Renault en HTML + CSS ? (Ne fonctionne pas sous IE, voir l'explication donnée à l'exemple précédent) | |
|
|
Modèle à représenter (ce lien ouvre une fenêtre popup).
Les bordures d'éléments block conviennent bien pour représenter ce Mondrian : les aplats de couleur sont simplement délimités entre eux par des obliques à 45 degrés.
Un élément block permet de tracer l'intersection de 2 obliques. Il suffit donc de 6 éléments blocks (id de a à f dans le code ci-dessous). L'élément id=z sert de cadre à l'ensemble. Enfin l'ajout d'un dernier élément block ne présentant aucun effet visuel permet d'obtenir la compatibilité avec Internet Explorer (bug apparaissant sur les éléments vides, peut également être corrigé avec {font-size:0}).
Pour ce concours il était en plus demandé d'optimiser le code, c'est à dire de minimiser le nombre de caractères utilisés. Nous avons donc retiré l'ensemble des balises n'étant pas strictement indispensables (<html>, <head>, <title>...).
<style>
#z{overflow:hidden;height:490px;width:615px;margin-left:-155px}
div{position:absolute}
#a{border:230px solid;border-color:#f00 #f00 #000 #ffd;top:40px}
#b{border:140px solid;border-color:#ffd #f00 #f00 #ff0;top:-370px;
left:-90px}
#c{border:160px solid;border-color:#f00 #00a #ffd #f00;top:140px;
left:20px}
#d{border:100px solid;border-color:#00a #00a #dda #ffd}
#e{border:80px solid;border-color:#f00 #ffd #000 #000;top:-100px;
left:-260px}
#f{border:120px solid;border-color:#ffd #ffd #f00 #f00;top:-480px}
</style>
<div id="z"><div id="a"><div id="b"><div id="c">
<div id="d"><div id="e"><div id="f"><div>
Afin de réduire encore le nombre de caractères utiles au codage de ce "Mondrian", nous avons cherché à factoriser ce code : en effet dans le CSS comme dans le HTML il est visible qu'une structure de code se répète à chaque élément div. Chaque répétition diffère néanmoins d'une autre de par les valeurs numériques désignant le positionnement, les couleurs et la taille de la div.
Nous avons donc définit une fonction javascript qui pose la structure
commune, et accepte les paramètres numériques nécessaires. Ainsi la structure
répétée en HTML et CSS n'est écrite qu'une fois en javascript lors de la
définition de la fonction (function f(w,t,r,b,l,y,x)).
Ensuite la répétition s'obtient en appelant la fonction autant de fois que
nécessaire (7 fois dans notre exemple, pour les 7 div "identiques"). La
répétition de l'appel à la fonction (16 caractères environ) est beaucoup plus
économique que la répétition de la structure complète (plus de 70
caractères).
La div qui sert de cadre est atypique, elle donc écrite indépendamment.
En définitive voici le code que nous avons utilisé :
<script>
r='f00';n='000';c='ffd';b='00a';p='position:absolute;';
function f(w,t,r,b,l,y,x){
return '<div style="'+p+'border:'+w+
'0px solid;border-color:#'+t+' #'+r+' #'+b+' #'+l+';top:'+y+
'0;left:'+x+'0">'
}
document.write('<div style="overflow:hidden;'+p+
'height:490;width:615;margin-left:-155">'
+f(23,r,r,n,c,4)+f(14,c,r,r,'ff0',-37,-9)+f(16,r,b,c,r,14,2)
+f(10,b,b,'dda',c)+f(8,r,c,n,n,-10,-26)+f(12,c,c,r,r,-48)+f())
</script>
De multiples formes géométriques :
http://www.infimum.dk/HTML/slantinfo.html
Un pavage d'hexagones en guise de menu chez Tantek :
http://tantek.com/map.html
Un peu d'animation dans tout ça (CSS + javascript) :
http://www.infimum.dk/HTML/rotatingBox.html
Agence de communication Ultra-Fluide : 01 47 70 23 32 - contact at ultra-fluide.com - 44 rue Richer 75009 Paris.