Bon, à la base, j'ai voulu utiliser la technique décrite dans l'article Onion Skinned Drop Shadows sur A List Apart. Je l'ai un peu modifiée pour pouvoir utiliser des PNGs avec de la transparence alpha; seul le coin en bas à droite est encore un PNG sans transparence. Enfin c'est pas ça l'important.
L'important, c'est que la technique proposée a un inconvénient : elle nécessite d'ajouter des DIVs non sémantiques. Et ça, c'est Mal :-)
On va donc utiliser un peu de Javascript pour les ajouter, pour éviter d'avoir un code tout sale !
ombrage.js
function insertShadowDiv (elt, className) {
if (elt.hasAttribute('id')) { var id = elt.getAttribute('id') + "_ext"; } var classext = className + '_ext'; var classmid = className + '_mid'; var classint = className + '_int'; var parent = elt.parentNode; var extdiv = document.createElement('div'); extdiv.setAttribute('class', classext); if (id) { extdiv.setAttribute('id', id); } var middiv = document.createElement('div'); middiv.setAttribute('class', classmid); var intdiv = document.createElement('div'); intdiv.setAttribute('class', classint); middiv.appendChild(intdiv); extdiv.appendChild(middiv); parent.replaceChild(extdiv, elt); intdiv.appendChild(elt); } function createShadows(className) { var elements = document.getElementsByClassName(className); for (var i = 0; i < elements.length ; i++) { insertShadowDiv(elements[i], className); } } /* tiré de * http://daniel.glazman.free.fr/weblog/newarchive/2003_06_01_glazblogarc.html#s95320189 */ document.getElementsByClassName = function (needle) { function _GetElementsByClass(outArray, seed, needle) { while (seed) { if (seed.nodeType == Node.ELEMENT_NODE) { if (seed.hasAttribute("class")) { var c = " " + seed.className + " "; if (c.indexOf(" " + needle + " ") != -1) outArray.push(seed); } _GetElementsByClass(outArray, seed.firstChild, needle) } seed = seed.nextSibling; } } var outArray = new Array(); _GetElementsByClass(outArray, document.documentElement, needle); return outArray; }
Fichier HTML utilisant ce code
Dans le fichier suivant, on peut remplacer present_ombre par ce qu'on veut, à condition de le remplacer aux deux endroits. Ici, tous les éléments de cette classe se verront rajouter les div imbriqués par le code Javascript.
<html> <head> ... <script type='text/javascript' src='js/ombrage.js'></script> ... </head> <body onload='createShadows("present_ombre"); return true'> ... <div class='present_ombre' id='friends_rss'> ... </div> ... </body> </html>
Fichier de style CSS associé
On voit que le code JavaScript a utilisé des noms de classes dérivant du nom de la classe initiale. C'est ici l'exemple utilisé sur la page d'accueil. Par ailleurs, si l'élement de la classe initiale avait un id, le DIV le plus extérieur prendra également un id, du type id_ext (par exemple, dans l'exemple ci-dessus: friends_rss_ext). En effet, certains styles nécessitent d'être appliqués sur le DIV extérieur, par exemple le style float, alors que d'autres doivent être appliqués sur le bloc intérieur.
.present_ombre_ext { background-image: url(../images/ombrage/shadow_right.png); background-repeat: no-repeat; background-position: 100% -12px; } .present_ombre_mid { background-image: url(../images/ombrage/shadow_bottom.png); background-repeat: no-repeat; background-position: -12px 100%; } .present_ombre_int { background-image: url(../images/ombrage/shadow_br.png); background-repeat: no-repeat; background-position: bottom right; padding-right: 9px; padding-bottom: 9px; }
CSS pour Internet Explorer Windows
En fait, pour Internet Explorer Windows, on supprime les images de fond, car il ne sait pas appliquer correctement les PNGs avec transparence non binaire. C'est l'effet des trois premières directives.
Par ailleurs, il semble qu'il ne sait pas non plus gérer correctement le bout de code Javascript, donc en fait, les DIVs supplémentaires ne sont pas insérés... Donc on doit penser à appliquer aussi les styles du bloc extérieur sur l'id du bloc intérieur.
/* hack IE sauf IE Mac */ /* \*/ * html .present_ombre_ext { background-image: none; } * html .present_ombre_mid { background-image: none; } * html .present_ombre_int { background-image: none; position: relative; /* pour forcer le reflow ... */ } * html #friends_rss { styles de #friends_rss_ext } /* */
14 réactions
1 De zahn - 12/05/2005, 10:05
au final tu te retrouves quand même avec des divs sémantique javascript ou pas. C est juste pour pour avoir un code HTML de base plus clair ?
2 De zahn - 12/05/2005, 10:06
divs non sémantiques voulais-je dire
3 De Julien Wajsberg - 12/05/2005, 10:09
Ben au final, tu as des DIVs non sémantiques, mais personne les voit, à part le navigateur :-) Ça apparait même pas dans la source.
4 De Thom - 12/05/2005, 10:32
excuse moi, je trouve ça vraiment "con" ce "nouveau" truc d'ajouter avec le javascript le "sale code". Comme si le seul objet de tout les standards étaient d'obtenir un code propre, toutes les techniques de hack étant bonnes à prendre.
ça fait vraiment rustine et ça me semble même aller à l'encontre de l'esprit. ça s'appuie sur du JavaScript déjà, ça rajoute une couche "forme-HTML" au dessus du Fond-HTML/Forme-CSS même si elle reste invisible.
Pour l'instant, perso, je tente de faire avec les standards et les limites de leur support actuelsl quitte à brider la créativité (mais est-ce un mal de se limiter aux standards ?).
5 De Julien Wajsberg - 12/05/2005, 10:43
Ça ne reste pas moins standard ainsi. En effet, j'utilise :
Le support des standards est un faux problème. On peut être en XHTML1 Strict et toujours utiliser une mise en page avec des tableaux, des balises non sémantiques, et des <br /> partout.
Voyons les buts que je me fixe lorsque je crée une page (nous n'avons peut-être pas les mêmes):
Bon, je viens de voir qu'en désactivant uniquement le JS, on avait un problème; faudra que je creuse ça...
6 De zahn - 12/05/2005, 13:13
ok compris. En plus ca evite de copier coller 1000 fois le même html tout moche à chaque div à ombrer. Et si tu dois changer/parametrer completement ton ombrage c est plus simple à maintenir. A part ça je vois pas du tout d'ombrage sur la apge d'accueil avec IE6
7 De Félash - 12/05/2005, 13:15
Oué, IE6 ne gère pas les PNGs transparents correctement, donc j'ai désactivé. Tant pis pour eux :) (cf la fin du billet)
8 De ben - 12/05/2005, 14:58
Oue Thom a bien raison : Flash a fait n'importe quoi !
9 De Thom - 13/05/2005, 09:57
pour reprendre les arguments de hier soir :
- ça fout en l'air la séparation HTML Fond / CSS Forme, donc l' "objectif" des standards à mes yeux
- ça détourne l'utlisation prévue du Javascript
- ça part du postulat que les navigateurs alternatifs ne supportent pas le Javascript
- ça facilite pas du tout la maintenance, contrairement à ce que dit Zahn
- ça peut devenir la bonne excuse pour (re)faire n'importe quoi en HTML en disant "non mais attend c'est standard"
10 De Félash - 13/05/2005, 10:07
Mais comme je l'ai dit, les standards n'ont jamais empêcher personne de faire n'importe quoi en HTML (pour moi, "n'importe quoi" correspondant à "non sémantique").
pourquoi ça ne facilite pas la maintenance ? Une fois qu'on a notre bout de js qui fonctionne, où est le probleme ?
L'idée des behaviours de IE est pas si mauvaise en fait...
11 De Thom - 13/05/2005, 10:27
ouais mais c'est bien ce qu'on pointait du doigt hier : les standards servent à assurer le support et c'est une bonne chose mais derrière se cachent d'autres voeux pieux comme la séparation du fond et de la forme, le balisage sémantique... Et quand je cherche à faire selon les standards, j'essaie en fait non pas d'avoir seulement un code qui valide mais bien d'aller plus loin dans ces directions...
ça ne facilite pas la maintenance parce que c'est un fichier en plus tout simplement, (un code à connaître en plus aussi) et que ça fait intervenir et le code HTML et les CSS !
12 De Félash - 13/05/2005, 10:38
Ah, tu te rappelles d'hier toi ? (gratuit :p)
Hé bien je me dis que ce bout de code javascript fait partie de la forme; et c'est bien séparé du reste (code html + autres scripts js éventuels).
Ça peut arriver de segmenter des fichiers CSS aussi, non ? En quoi est-ce différent pour toi ? Juste la différence de langage ? Le fait que le JS ait été inventé pour déterminer un comportement ? Et en quoi un comportement n'est-il pas de la forme, finalement ? :-)
Finalement, ce bout de javascript fait partie de la forme, mais il est bien séparé du fond. La forme n'est plus l'apanage du CSS (et les xslt dans tout ça ? :-).
13 De zahn - 13/05/2005, 11:32
hmm c est le fait de déporter l'ombrage dans du javascript ou le fait de mettre des ombrages qui t embete Thom ?
Parce que pour ce qui est de mettre ça dans le javascript ca simplifie clairement la maintenance par rapport à la situation où tu as tout dans le même fichier html avec la même structure d'ombrage répétée n fois. Et pour la sémantique Juju a clairement montré que ça ne lui portait pas préjudice. Ou alors peut-être juste que tu veux jouer avec lui en le contredisant :-)
14 De Oncle Ho - 18/05/2005, 11:11
Comment peut on tant reagir sur un tel sujet???
Thom en parlant de polemiques sans fond et de position universellement indefendables, entre le devoir d'ingerence, le conflit israelo palestinien et le match Flodor/vico tu aurais pu ajouter la semantique du code javascript de Felash... Ou alors c'est parce que dans le fond j'y comprend rien... comme pour les chips.