Oltana.net 23 Mai 2012 à 04:39:25 *
Bienvenue, Invité. Veuillez vous connecter ou vous inscrire.


Connexion avec identifiant et mot de passe
Nouvelles:
Bascule sur SMF faite!
 
 
Accueil Aide Rechercher
Pages: [1]   Bas de page
Imprimer
Auteur Fil de discussion: [ xhtml / css ] Création d'un menu horizontal déroulant  (Lu 906 fois)
Corven
Administrateur
*****
Hors ligne Hors ligne

Sexe: Homme
Messages: 1632



Voir le profil WWW
« le: 14 Avril 2006 à 13:41:19 »

:: [ xhtml / css ] Création d’un menu horizontal avec sous-menu déroulant ::


[MISE A JOUR 21.11.06] Tuto à reprendre complètement pour cause de bug.


Pour ce menu déroulant, nous allons faire en sorte qu’il soit compatible xhtml 1.0 strict, tout du moins pour le fichier html.
En effet nous allons être obligé d’utiliser une astuce que les normes xhtml ne reconnaissent pas, cela pour que le menu fonctionne sous IE 6 et inférieur.

Vous aurez besoin d’un menu horizontal pour commencer, vous pouvez reprendre celui de mon précédent tuto « Création d’un menu horizontal », en tout cas ça sera notre point de départ ici.

Nous voici donc avec notre code de départ :

Code:
<html>
<head>
<style type="text/css">

div#liste_menu ul li { float: left; list-style-type: none; font-family: Verdana; font-size: 11px; font-weight: bold; text-align: center; }
div#liste_menu ul li a { display: block; background-image: url('bouton.gif'); width: 116px; height: 31px; background-repeat: no-repeat; color: #000000; text-decoration: none; padding-top: 3px;}
div#liste_menu ul li a:hover { text-decoration: none; color: red;}

</style>
</head>
<body>

<div id="liste_menu">
   <ul>
      <li><a href="#">Menu 01</a></li>
      <li><a href="#">Menu 02</a></li>
      <li><a href="#">Menu 03</a></li>
      <li><a href="#">Menu 04</a></li>
   </ul>
</div>

</body>
</html>


1°)
Commençons par rajouter du code dans le body.
Pour des raisons de clarté nous allons faire ce menu déroulant que sur le premier onglet,à savoir "menu 01".
Reprennez donc le code suivant à mettre à la place du code présent dans le body:

Code:
<div id="liste_menu">
   <ul>
      <li><a href="#">Menu 01</a>
<ul>
<li><a href="1.do">sous menu 01</a></li>
<li><a href="2.do">sous menu 02</a></li>
<li><a href="3.do">sous menu 03</a></li>
<li><a href="4.do">sous menu 04</a></li>
</ul>

 </li>
      <li><a href="#">Menu 02</a></li>
      <li><a href="#">Menu 03</a></li>
      <li><a href="#">Menu 04</a></li>
   </ul>
</div>


2°)
A cet instant nous avons un sous menu horizontal auquel a été appliqué les règles css du menu.
Nous le voulons vertical et sans les boutons en arrière plan.
Grâce à l'héritage des css nous n'avons pas besoin de remettre toute les propriétés de texte par exemple, juste désactivé celle qui nous gène.
Ici c'est le float: left; que nous passons en float: none; dans une nouvelle ligne de css qui cible la seconde liste.

Code:
div#liste_menu ul li ul li { float: none; }


3°)
Vous remarqué un décalage, corrigé cela en rajoutant une propriété margin-left négative :

Code:
div#liste_menu ul li ul li { float: none; margin-left: -40px; }


4°)
Passons maintenant aux liens.
Le div#liste_menu ul li ul li a:link et le div#liste_menu ul li ul li a:visited devant être identique nous allons les coupler pour gagner une ligne en div#liste_menu ul li ul li a:link, div#liste_menu ul li ul li a:visited.
Rajoutez donc les lignes de css suivantes :

Code:
div#liste_menu ul li ul li a {  }
div#liste_menu ul li ul li a:link, div#liste_menu ul li ul li a:visited { }
div#liste_menu ul li ul li a:hover {  }


5°)
Ajoutons les propriétés maintenant.
Nous allons transformer la balise <a> en élément block grâce au display pour lui donner une dimension en px, retirer l'image de fond et ajouter une couleur de fond.

Code:
div#liste_menu ul li ul li a { display: block; width: 116px; height: 15px; background-image: none; background-color: #EEEEEE; }


6°)
Dans la ligne div#liste_menu ul li ul li a:link, div#liste_menu ul li ul li a:visited on ne mettra rien, enfin on ne changera rien des propriétés acquises par l'héritage.
Si vous le désirez, vous pouvez changer de police, de taille de police, de couleur etc grâce aux propiétés du font que vous retrouverez un peu plus haut dans ce tuto.
Laissons donc la ligne vide :

Code:
div#liste_menu ul li ul li a:link, div#liste_menu ul li ul li a:visited { }
Vous pouvez la retirer mais pour des raisons pédagogique je l'a laisse.


7°)
Ensuite, l'attribut a:hover à définir.
On enlève l'image de fond, on rajoute une couleur à la place et on grossit le texte pour qu'au passage de la souris on ait un petit effet de loupe.
Vous obtenez la ligne suivante:

Code:
div#liste_menu ul li ul li a:hover { color: #FFFFFF; background-image: none; background-color: #FF9900; font-size: 12px; }


8°)
Notre sous-menu est maintenant fait, reste qu'à le faire disparaitre et apparaitre au passage de la souris.
Pour ce faire, masquons le sous menu lorsqu'il n'est pas survolé; rajoutez cette ligne que nous mettrons au tout début du css :

Code:
body div#liste_menu ul li ul { display: none; }


9°)
Puis il nous faut le faire réapparaitre lorsque le menu est survolé, cela se fait grâce à cette ligne :

Code:
div#liste_menu ul li:hover ul, div#liste_menu ul li ul:hover { display: block; }
Petite explication :
- div#liste_menu ul li:hover ul fait en sorte d'afficher le sous-menu lorsque le menu est survolé.
- div#liste_menu ul li ul:hover fait en sorte de garder l'affichage lorque nous quittons le menu pour naviguer dans le sous-menu.


10°)
Ca y est notre menu fonctionne ! Mais pas sous IE6 et inférieur ! Or ce navigateur reste encore le plus utilisé, nous devons donc faire en sorte que cela fonctionne.
Pour l'instant on va laisser de côté le critère "compatible xhtml 1.0 strict", mais ne vous inquiètez pas, au final nos fichier html le sera !
C'est maintenant qu'une astuce arrive ! Elle n'est pas du tout de moi, j'aurais été incapable de la mettre au point !
Tout est expliqué à cette adresse : http://http://www.xs4all.nl/~peterned/hovercraft.html.
En résumé, IE6 et inférieur ne comprend pas l'attribut :hover sur une autre balise que <a>, nous allons donc faire en sorte qu'il l'accepte.
Pour cela, créez un fichier nommé csshover.htc.
Ouvrez le et insérez ce code :

Code:
<attach event="ondocumentready" handler="parseStylesheets" />
<script>
/**
 * Whatever:hover - V1.42.060206 - hover & active
 * ------------------------------------------------------------
 * (c) 2005 - Peter Nederlof
 * Peterned - http://www.xs4all.nl/~peterned/
 * License  - http://creativecommons.org/licenses/LGPL/2.1/
 *
 * Whatever:hover is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * Whatever:hover is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * Credits and thanks to:
 * Arnoud Berendsen, Martin Reurings, Robert Hanson
 *
 * howto: body { behavior:url("csshover.htc"); }
 * ------------------------------------------------------------
 */

var csshoverReg = /(^|\s)(([^a]([^ ]+)?)|(a([^#.][^ ]+)+)):(hover|active)/i,
currentSheet, doc = window.document, hoverEvents = [], activators = {
onhover:{on:'onmouseover', off:'onmouseout'},
onactive:{on:'onmousedown', off:'onmouseup'}
}

function parseStylesheets() {
if(!/MSIE (5|6)/.test(navigator.userAgent)) return;
window.attachEvent('onunload', unhookHoverEvents);
var sheets = doc.styleSheets, l = sheets.length;
for(var i=0; i<l; i++)
parseStylesheet(sheets[i]);
}
function parseStylesheet(sheet) {
if(sheet.imports) {
try {
var imports = sheet.imports, l = imports.length;
for(var i=0; i<l; i++) parseStylesheet(sheet.imports[i]);
} catch(securityException){}
}

try {
var rules = (currentSheet = sheet).rules, l = rules.length;
for(var j=0; j<l; j++) parseCSSRule(rules[j]);
} catch(securityException){}
}

function parseCSSRule(rule) {
var select = rule.selectorText, style = rule.style.cssText;
if(!csshoverReg.test(select) || !style) return;

var pseudo = select.replace(/[^:]+:([a-z-]+).*/i, 'on$1');
var newSelect = select.replace(/(\.([a-z0-9_-]+):[a-z]+)|(:[a-z]+)/gi, '.$2' + pseudo);
var className = (/\.([a-z0-9_-]*on(hover|active))/i).exec(newSelect)[1];
var affected = select.replace(/:(hover|active).*$/, '');
var elements = getElementsBySelect(affected);
if(elements.length == 0) return;

currentSheet.addRule(newSelect, style);
for(var i=0; i<elements.length; i++)
new HoverElement(elements[i], className, activators[pseudo]);
}

function HoverElement(node, className, events) {
if(!node.hovers) node.hovers = {};
if(node.hovers[className]) return;
node.hovers[className] = true;
hookHoverEvent(node, events.on, function() { node.className += ' ' + className; });
hookHoverEvent(node, events.off, function() { node.className = node.className.replace(new RegExp('\\s+'+className, 'g'),''); });
}
function hookHoverEvent(node, type, handler) {
node.attachEvent(type, handler);
hoverEvents[hoverEvents.length] = {
node:node, type:type, handler:handler
};
}

function unhookHoverEvents() {
for(var e,i=0; i<hoverEvents.length; i++) {
e = hoverEvents[i];
e.node.detachEvent(e.type, e.handler);
}
}

function getElementsBySelect(rule) {
var parts, nodes = [doc];
parts = rule.split(' ');
for(var i=0; i<parts.length; i++) {
nodes = getSelectedNodes(parts[i], nodes);
} return nodes;
}
function getSelectedNodes(select, elements) {
var result, node, nodes = [];
var identify = (/\#([a-z0-9_-]+)/i).exec(select);
if(identify) {
var element = doc.getElementById(identify[1]);
return element? [element]:nodes;
}

var classname = (/\.([a-z0-9_-]+)/i).exec(select);
var tagName = select.replace(/(\.|\#|\:)[a-z0-9_-]+/i, '');
var classReg = classname? new RegExp('\\b' + classname[1] + '\\b'):false;
for(var i=0; i<elements.length; i++) {
result = tagName? elements[i].all.tags(tagName):elements[i].all;
for(var j=0; j<result.length; j++) {
node = result[j];
if(classReg && !classReg.test(node.className)) continue;
nodes[nodes.length] = node;
}
}

return nodes;
}
</script>


11°)
Vous pouvez fermer ce fichier et retournez dans le fichier html.
Maintenant il faut appeler ce fichier .htc.

Créez pour cela une nouvelle ligne css que vous mettrez en tout premier, c'est à dire juste en dessous du <style type="text/css">.

Code:
body { behavior: url(csshover.htc); }


12°)
Voilà, notre menu est censé fonctionner sous internet explorer. Vous pouvez peut être avoir une alerte de ça part en haut de la fenêtre, normal car ce qu'il y a dans le fichier csshover.htc est du javascript, reconnu comme potentiellement mais ici rien à craindre vous pouvez donc autoriser le contenu.


13°)
Nous y voilà donc ! Votre menu est totalement fonctionnel !
Cependant on peut l'optimiser facilement !
Que faire de plus ?
C'est de l'ordre esthétique mais c'est plus joli ainsi.
Lorsque vous survolez le menu, le sous-menu s'affiche et l'image du menu change.
Quand vous commencez à naviguer dans le sous-menu, l'image du menu redevient celle d'origine, pas terrible ça non ? Vaudrait mieux que l'image de survol reste quand on navigue ...
Nous allons remédiez à cela !


14°)
Alors, nous allons modifier un brin le contenu du body.
Nous avons une architecture comme cela:

Code:
<a href="#">Menu 01</a>
<ul>
<li><a href="1.do">sous menu 01</a></li>
<li><a href="2.do">sous menu 02</a></li>
<li><a href="3.do">sous menu 03</a></li>
<li><a href="4.do">sous menu 04</a></li>
</ul>

Rajoutez une balise <div> juste avant la balise <a href="#"> ainsi qu'une balise </div> juste après le </ul>.
Rajoutez aussi une class="t" dans la balise <a href="#">.
Au final vous avez cela à la place du précédent code :

Code:
<div>
<a href="#" class="t">Menu 01</a>
<ul>
<li><a href="1.do">sous menu 01</a></li>
<li><a href="2.do">sous menu 02</a></li>
<li><a href="3.do">sous menu 03</a></li>
<li><a href="4.do">sous menu 04</a></li>
</ul>
</div>


15°)
Une légère modification est à faire dans une ligne existante dans la partie css.
Repérez la ligne suivante :

Code:
div#liste_menu ul li a:hover { text-decoration: none; color: red; background-image: url('bouton_on.gif'); }

Remplacez-là par celle-ci :

Code:
div#liste_menu ul li div:hover a.t { text-decoration: none; color: red; background-image: url('bouton_on.gif'); }







:://::\\:: Résumé :://::\\::

Nous avons donc le fichier html et son css suivant :

Code:
<html>
<head>
<style type="text/css">
body { behavior: url(csshover.htc); }
body div#liste_menu ul li ul { display: none; }

div#liste_menu ul li { float: left; list-style-type: none; font-family: Verdana; font-size: 11px; font-weight: bold; text-align: center; }
div#liste_menu ul li a { display: block; background-image: url('bouton.gif'); width: 116px; height: 31px; background-repeat: no-repeat; color: #000000; text-decoration: none; padding-top: 3px;}
div#liste_menu ul li div:hover a.t { text-decoration: none; color: red; background-image: url('bouton_on.gif'); }


div#liste_menu ul li ul li { margin-left: -40px; float: none;  }
div#liste_menu ul li ul li a { display: block; background-image: none; background-color: #EEEEEE; width: 116px; height: 15px; }
div#liste_menu ul li ul li a:link, div#liste_menu ul li ul li a:visited {  }
div#liste_menu ul li ul li a:hover { color: #FFFFFF; background-image: none; background-color: #FF9900; font-size: 12px; }


div#liste_menu ul li:hover ul, div#liste_menu ul li ul:hover { display: block; }
</style>
</head>
<body>

<div id="liste_menu">
   <ul>
<li>
<div>
<a href="#" class="t">Menu 01</a>
<ul>
<li><a href="1.do">sous menu 01</a></li>
<li><a href="2.do">sous menu 02</a></li>
<li><a href="3.do">sous menu 03</a></li>
<li><a href="4.do">sous menu 04</a></li>
</ul>
</div>
</li>
   </ul>
</div>

</body>
</html>

Il vous suffit de faire un simple copier/coller pour rajouter des onglets à votre menu.


Nous avons aussi le fichier csshover.htc que vous reprendrez à l'étape 10.




Reste à aborder la compatibilité xhtml 1.0 strict

A suivre : "Création d'un menu horizontal déroulant avec sous-menu multiples".

:: corven ::
Journalisée

[size=84]Intel E6600 @ 2,4ghz - Asus P5B Deluxe Wifi/AP - Asus 7600GT Silent/2DHT - G.Skill Extreme Serie PK 4*1go PC6400 - Hitachi T7K250 250go & 160go - Seasonic S12 600Watts - Noctua NH-U12F + 2* Noctua NF-S12 1200 - Nec 3520A - Gigabyte Triton Black - 2* Viewsonic VX2025WM - Logitech Media Keyboard Elite - Logitech G5 - Koss UR40 - Onduleur MGE 675VA // MACBOOK PRO 2008 @2,4ghz[/size]
Corven
Administrateur
*****
Hors ligne Hors ligne

Sexe: Homme
Messages: 1632



Voir le profil WWW
« Répondre #1 le: 14 Avril 2006 à 18:23:11 »

Voilà tuto terminé à 98,54% ... si quelqu'un pouvait le tester pour me dire si ça va ...  Tr&egrave;s souriant
Journalisée

[size=84]Intel E6600 @ 2,4ghz - Asus P5B Deluxe Wifi/AP - Asus 7600GT Silent/2DHT - G.Skill Extreme Serie PK 4*1go PC6400 - Hitachi T7K250 250go & 160go - Seasonic S12 600Watts - Noctua NH-U12F + 2* Noctua NF-S12 1200 - Nec 3520A - Gigabyte Triton Black - 2* Viewsonic VX2025WM - Logitech Media Keyboard Elite - Logitech G5 - Koss UR40 - Onduleur MGE 675VA // MACBOOK PRO 2008 @2,4ghz[/size]
superjun
Posteur assidu
****
Hors ligne Hors ligne

Messages: 137



Voir le profil
« Répondre #2 le: 15 Avril 2006 à 13:30:32 »

Hello,
Terrible l'astuce CSS pour faire un menu comme ça... J'y avais jamais pensé, et meme jamais imaginé qu'on puisse faire comme ça (je croyais que :hover devait obligatoirement se mettre à la fin)

Une petite chose, je crois que c'est possible de détecter le navigateur en CSS...
En utilisant une petite astuce avec PHP :
Il faut créer un espace <style> à l'intérieur de la page et inclure le fichier htc par ici, au lieu de la feuille de style externe.
Avec ça, en utilisant la superglobale $_SERVER de PHP (c'est possible que ce soit dans une autre), il est possible de détecter le navigateur du client, et d'afficher ou non la partie <style> qui inclut le htc externe.
Ainsi, le htc n'est inclus que si c'est IE qui visite Sourire

Si toi y en a pas comprendre, toi y en a me demander  Cool
Journalisée


What isn't remembered never happened...
Zap1206
Posteur assidu
****
Hors ligne Hors ligne

Messages: 315



Voir le profil WWW
« Répondre #3 le: 16 Avril 2006 à 11:32:00 »

Tous les navigateurs n'envoient pas leur nom et certains le changent. Par contre IE comprend des balises qu'aucun autre navigateur ne comprend :
Code:
<if>
Blabla
<endif>


Plus d'infos (pour indentifier les versions par exemple) ici : http://www.dithered.com/css_filters/htm ... ts_ie.html

Edit : Arf il veut pas le forum; regardez direct sur la page.
Journalisée

Pages: [1]   Haut de page
Imprimer
Oltana.net  |  Tutoriels  |  Grimoire  |  Fil de discussion: [ xhtml / css ] Création d'un menu horizontal déroulant
 
Aller à:  

Powered by SMF 1.1.15 | SMF © 2006-2009, Simple Machines