From d52afe5cc37ce1e88772e7cb7a40b54bbbebda83 Mon Sep 17 00:00:00 2001 From: polo Date: Thu, 13 Nov 2025 20:19:48 +0100 Subject: =?UTF-8?q?classe=20CSS=20drop-left=20pour=20ouvrir=20des=20sous-m?= =?UTF-8?q?enus=20=C3=A0=20gauche,=20normes=20de=20responsive=20design:=20?= =?UTF-8?q?480,=20768=20et=201024px?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/css/head.css | 23 ++++++++++----- public/css/nav.css | 85 ++++++++++++++++++++++++++++++----------------------- public/js/main.js | 27 +++++++++++++---- 3 files changed, 87 insertions(+), 48 deletions(-) diff --git a/public/css/head.css b/public/css/head.css index 4df68ba..b5acfec 100644 --- a/public/css/head.css +++ b/public/css/head.css @@ -47,7 +47,7 @@ header h2 font-size: medium; /* défaut = x-large */ margin: 10px; } -@media screen and (max-width: 1000px){ +@media screen and (max-width: 1024px){ header h1, header h2 { margin: 8px; @@ -119,8 +119,12 @@ header a border-radius: 10px; padding: 5px; } +.header_content +{ + padding: 20px 0; +} -@media screen and (max-width: 1000px){ +@media screen and (max-width: 1024px){ .header_content { padding: 15px 0; @@ -130,20 +134,25 @@ header a max-width: 160px; } } -@media screen and (max-width: 800px){ +@media screen and (max-width: 768px){ .header_content { - grid-template-columns: 2fr 1fr; /* on vire la colonne de gauche et on permet au deux autres de "se pousser" si besoin */ - padding: 10px; + /*grid-template-columns: 2fr 1fr;*/ /* on vire la colonne de gauche et on permet au deux autres de "se pousser" si besoin */ + /*padding: 10px;*/ + display: block; + max-width: 65%; + margin: auto; } .header_left_col { display: none; } } -@media screen and (max-width: 600px){ +@media screen and (max-width: 480px){ .header_content { - display: block; + /*display: block;*/ + max-width: 100%; + padding: 10px; } } \ No newline at end of file diff --git a/public/css/nav.css b/public/css/nav.css index a9bddf2..4c276be 100644 --- a/public/css/nav.css +++ b/public/css/nav.css @@ -1,7 +1,7 @@ /*-- menu principal --*/ /* version horizontale */ -@media screen and (min-width: 601px){ +@media screen and (min-width: 769px){ .nav_button{ display: none; } @@ -32,21 +32,28 @@ border-top: 3px solid #13aff0; } /* élément du menu survolé, le positionnement relatif en fait la référence du positionnement suivant */ - .drop-right .sub-menu + .drop-right .sub-menu, .drop-left .sub-menu { position: absolute; /* positionnement par rapport au précédent "position" en CSS */ - left: 100%; top: -3px; /* la bordure bleue fait 3px */ } + .drop-right .sub-menu{ + left: 100%; + } + .drop-left .sub-menu{ + right: 100%; + } /* 1er sous-menu, poitionnement pour ne pas aggrandir l'élément parent */ - nav > ul > li > ul - { + nav > ul > li > ul{ position: absolute; /* retire du flux, positionnement par rapport à la fenêtre */ margin-top: 5px; margin-left: -5px; } + nav > ul > li > ul:has(.drop-left){ + right: 0; + } - @media screen and (max-width: 1000px){ /* entre 601 et 1000 */ + @media screen and (max-width: 1024px){ /* entre 769 et 1024 */ .nav_main p { font-size: 90%; @@ -54,33 +61,31 @@ } @media (pointer: fine){ - .nav_main > ul > li:hover - { + .nav_main > ul > li:hover{ background-color: white; } .drop-right > a > p:after{ content: " ▶"; } + .drop-left > a > p:before{ + content: "◀ "; + } } } -@media screen and (max-width: 450px){ +@media screen and (max-width: 480px){ .sub-menu p{ font-size: 90%; } } -@media screen and (min-width: 1000px){ - nav > ul > li > ul{ - margin-left: -7px; /* annuler le déplacement dû au padding: 7px; dans ".nav_main li" */ - margin-top: 7px; - } +@media screen and (min-width: 1025px){ .nav_main li{ padding: 7px; } } /* version petits écrans */ -@media screen and (max-width: 600px){ +@media screen and (max-width: 768px){ #nav_zone{ display: flex; flex-direction: column; @@ -119,31 +124,40 @@ padding-left: 25px; padding-right: 5px; } - /*nav > ul > li > ul{ margin-left: 0; }*/ + @media (pointer: fine){ .nav_main > ul > li:hover{ background-color: yellow; } - .drop-right > a > p:after{ + .drop-right > a > p:after, .drop-left > a > p:after{ content: ' ▼'; } } + + @media (pointer: coarse){ + .drop-down.open, .drop-right.open, .drop-left.open{ + border-radius: 5px; + } + } } -.nav_main -{ +.nav_main{ border: 2px solid #13aff0; text-wrap: nowrap; } .sub-menu{ box-shadow: 1px 1px 3px black; } +.sub-menu:has(.drop-left), .sub-menu:has(.drop-left) .sub-menu{ + box-shadow: -1px 1px 3px black; +} ul{ - margin: 0; + margin-top: 0; + margin-bottom: 0; } .nav_main p @@ -166,15 +180,15 @@ li:not(.current){ background-color: initial; font-weight: initial; } +.drop-down.open, .drop-down:hover{ + position: relative; /* permet d'aligner son enfant en position absolue à droite avec un right: 0; */ +} /* sous-menus avec PC + souris mettre ici tous les blocs avec :hover, les navigateurs mobiles "simulent" les :hover, cassant le JS utilisé ici */ -@media (pointer: fine) /* fine => précision de la souris */ -{ - .drop-down:hover > .sub-menu, - .drop-right:hover > .sub-menu - { +@media (pointer: fine){ /* fine => précision de la souris */ + .drop-down:hover > .sub-menu, .drop-right:hover > .sub-menu, .drop-left:hover > .sub-menu{ display: block; } .sub-menu li:hover /* écrase le fond blanc placé en même temps */ @@ -187,7 +201,7 @@ mettre ici tous les blocs avec :hover, les navigateurs mobiles "simulent" les :h content: ' ▼'; font-size: x-small; } - .drop-right > a > p:after + .drop-right > a > p:after, .drop-left > a > p:before { font-size: x-small; } @@ -203,22 +217,21 @@ mettre ici tous les blocs avec :hover, les navigateurs mobiles "simulent" les :h font-size: x-small; vertical-align: text-bottom; } +.sub-menu{ + display: none; + background-color: white; + font-size: 95%; +} /* écran tactile */ -@media (pointer: coarse) /* coarse = grossier = précision écran tactile */ -{ +@media (pointer: coarse){ /* coarse = grossier = précision écran tactile */ .sub-menu-toggle{ display: inline-block; /* visible sur écran tactile */ } - .drop-down.open > .sub-menu, .drop-right.open > .sub-menu{ + .drop-down.open > .sub-menu, .drop-right.open > .sub-menu, .drop-left.open > .sub-menu{ display: block; } - .drop-down.open, .drop-right.open{ + .drop-down.open, .drop-right.open, .drop-left.open{ background-color: yellow; } -} -.sub-menu{ - display: none; - background-color: white; - font-size: 95%; -} +} \ No newline at end of file diff --git a/public/js/main.js b/public/js/main.js index 7020971..c8e10b0 100644 --- a/public/js/main.js +++ b/public/js/main.js @@ -59,6 +59,21 @@ function toggleTouchMenu(){ } } +function makeDropLeftMenuEntries(){ + // détection d'éléments de 1er niveau possédant un menu déroulant possédant un menu déroulant + document.getElementById('nav_zone').querySelector('.nav_main').querySelectorAll('.drop-down:has(.drop-right)').forEach(drop_down => { + const rect = drop_down.getBoundingClientRect(); // coordonnées spatiales + + // il se situe dans la moitié droite + if((rect.width / 2 + rect.left) > (window.innerWidth / 2)){ // centre de l'élément > largeur de la fenêtre? + drop_down.querySelectorAll('.drop-right').forEach(drop_right => { + drop_right.classList.remove('drop-right'); + drop_right.classList.add('drop-left'); + }); + } + }); +} + // exécuté à la fin du chargement de la page document.addEventListener('DOMContentLoaded', () => { @@ -70,17 +85,18 @@ document.addEventListener('DOMContentLoaded', () => { // fermer les autres sous-menus de même niveau // :scope pour pouvoir utiliser > pour restreindre aux frères directs - li.parentElement.querySelectorAll(':scope > .drop-down, :scope > .drop-right').forEach(sibling => { + li.parentElement.querySelectorAll(':scope > .drop-down, :scope > .drop-right, :scope > .drop-left').forEach(sibling => { if(sibling !== li){ sibling.classList.remove('open'); // fermer sous-menus frères - sibling.querySelectorAll('.drop-right').forEach(desc => { + sibling.querySelectorAll('.drop-right, .drop-left').forEach(desc => { desc.classList.remove('open'); // fermer sous-menus neveux }); } }); - if(!li.classList.toggle('open')){ // ouvrir ou fermer ce sous-menu - li.querySelectorAll('.drop-right').forEach(desc => { + // ouvrir ou fermer un sous-menu + if(!li.classList.toggle('open')){ + li.querySelectorAll('.drop-right, .drop-left').forEach(desc => { desc.classList.remove('open'); // fermer sous-menus enfants }); } @@ -88,6 +104,7 @@ document.addEventListener('DOMContentLoaded', () => { }); navHeight(); // hauteur de