Présentation du TD

L'objectif du TD est de réaliser une page html présetant un menu déroulant correctement organisé.

Ce TD va permettre de voir les notions suivantes :

  • Organisation d'une page html
  • Utilisation des balises html5
  • Organisation de la page en vue de l'application des CSS
  • Utilisation d'une bibliothèque d'icones
  • Notions de javascript
  • Animations CSS

Organisation de la page html

La première étape consiste à organiser les différentes informations en une page html, les informations sont simples

  • Le titre de la page : Application exemple
  • Un menu organisé de la manière suivante :
    • Un menu accueil
    • Un menu Catégories ayant trois sous-menu :
      • HTML / CSS
      • JavaScript
      • PHP / MySQL
    • Un menu paramètres
<!DOCTYPE html>
<html lang="fr">
	<body>
		<nav>
			<ul>
				<li>
					<a href="#">Accueil</a>
				</li>
				<li>					
					Catégories
					<ul>
						<li><a href="#">HTML & CSS</a></li>
						<li><a href="#">JavaScript</a></li>
						<li><a href="#">PHP & MySQL</a></li>
					</ul>
				</li>
				<li>
					<a href="#">Paramètres</a>
				</li>
			</ul>
		</nav>
		
		<section>
			<header>Application exemple</header>
		</section>

	</body>
</html>

Positionnement des parties

L'objectif de cette partie est de définir deux parties :

  • Une partie gauche de largeur fixe contenant la barre de navigation
  • Une partie droite contenant la zone de travail avec le titre de la page

Html

<!DOCTYPE html>
<html lang="fr">
	<head>
		<meta charset="UTF-8">
		<title>Menu dépliant</title>
		<link rel="stylesheet" href="style.css">
	</head>
	<body>
		<nav class="sidebar">
			<ul>
				<li>
					<a href="#">Accueil</a>
				</li>
				<li>					
					Catégories
					<ul>
						<li><a href="#">HTML & CSS</a></li>
						<li><a href="#">JavaScript</a></li>
						<li><a href="#">PHP & MySQL</a></li>
					</ul>
				</li>
				<li>
					<a href="#">Paramètres</a>
				</li>
			</ul>
		</nav>
		
		<section class="espace_travail">
			<header>Application exemple</header>
		</section>

	</body>
</html>

CSS

*{
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: 'Poppins', sans-serif;
}
.sidebar{
  position: fixed;
  top: 0;
  left: 0;
  height: 100%;
  width: 260px;
  background: #11101d;
  z-index: 100;
}
.espace_travail{
  position: relative;
  background: #E4E9F7;
  height: 100vh;
  left: 260px;
  width: calc(100% - 260px);
}

Disposition du menu

L'objectif de cette partie est de réaliser une première mise en forme du menu pour le présenter de la manière suivante :

Html

<!DOCTYPE html>
<html lang="fr">
	<head>
		<meta charset="UTF-8">
		<title>Menu dépliant</title>
		<link rel="stylesheet" href="style.css">
	</head>
	<body>
		<nav class="sidebar">
		
			<div class="entete">
				<span class="libelle_entete">Menu</span>
			</div>
			
			<ul class="liens-navigation">
				<li>
					<a href="#">Accueil</a>
				</li>
				<li>					
					<a class="menu_deroulant" href="#">Catégories</a>
					<ul class="sous_menu">
						<li><a href="#">HTML & CSS</a></li>
						<li><a href="#">JavaScript</a></li>
						<li><a href="#">PHP & MySQL</a></li>
					</ul>
				</li>
				<li>
					<a href="#">Paramètres</a>
				</li>
			</ul>
		</nav>
		
		<section class="espace_travail">
			<header>Application exemple</header>
		</section>

	</body>
</html>

CSS

*{
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: 'Poppins', sans-serif;
}

/* Positionnement des éléments */
.sidebar{
  position: fixed;
  top: 0;
  left: 0;
  height: 100%;
  width: 260px;
  background: #11101d;
  z-index: 100;
}
.espace_travail{
  position: relative;
  background: #E4E9F7;
  height: 100vh;
  left: 260px;
  width: calc(100% - 260px);
}

/* Aspect du menu*/

/* Disposition de l'entete et aspect */
.sidebar .entete{
  height: 60px;
  width: 100%;
  display: flex;
  align-items: center;
}
.sidebar .entete .libelle_entete{
  font-size: 22px;
  color: #fff;
  font-weight: 600;
}

/* Disposition et aspect des liens de navigation */
.sidebar .liens-navigation{
  height: 100%;
  padding: 30px 0 150px 0;
}
.sidebar .liens-navigation li a{
  text-decoration: none;
}
.sidebar .liens-navigation li a {
  font-size: 18px;
  font-weight: 400;
  color: #fff;
}
.sidebar .liens-navigation li .sous_menu{
  padding: 6px 6px 14px 80px;
}

Améliorations esthétiques

L'objectif de cette partie est d'insérer des icones et de mettre en forme le site de manière plus poussée

  • Utiliser les icones FontAwersome
  • Mettre en place une police google

Html

<!DOCTYPE html>
<html lang="fr">
	<head>
		<meta charset="UTF-8">
		<title>Menu dépliant</title>
		<link rel="stylesheet" href="style.css">
		<link rel="stylesheet" href="vendor/fontawesome-free-5.15.4-web/css/all.css">
	</head>
	<body>
		<nav class="sidebar">
		
			<div class="entete">
				<i class="fas fa-chalkboard-teacher"></i>
				<span class="libelle_entete">Menu</span>
			</div>

			<ul class="liens-navigation">
				<li>
					<a href="#">
						<i class="fas fa-home"></i>
						<span class="libelle_lien">Accueil</span>
					</a>
				</li>
				<li>					
					<a class="menu_deroulant" href="#">
						<i class="far fa-list-alt"></i>
						<span class="libelle_lien">Catégories</span>
					</a>
					<ul class="sous_menu">
						<li><a href="#">HTML & CSS</a></li>
						<li><a href="#">JavaScript</a></li>
						<li><a href="#">PHP & MySQL</a></li>
					</ul>
				</li>
				<li>
					<a href="#">
						<i class="fas fa-cog"></i>
						<span class="libelle_lien">Paramètres</span>
					</a>
				</li>
			</ul>
		</nav>
		
		<section class="espace_travail">
			<header class="home-content">
				<i class="fas fa-bars"></i>
				<span class="text">Application exemple</span>
			</header>
		</section>

	</body>
</html>

CSS

@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap');
*{
	margin: 0;
	padding: 0;
	box-sizing: border-box;
	font-family: 'Poppins', sans-serif;
}

/* Positionnement des éléments */
.sidebar{
	position: fixed;
	top: 0;
	left: 0;
	height: 100%;
	width: 260px;
	background: #11101d;
	z-index: 100;
}
.espace_travail{
	position: relative;
	background: #E4E9F7;
	height: 100vh;
	left: 260px;
	width: calc(100% - 260px);
}

/* Aspect du menu*/

/* Disposition de l'entete et aspect */
.sidebar .entete{
	height: 60px;
	width: 100%;
	display: flex;
	align-items: center;
}
.sidebar .entete i{
	font-size: 30px;
	color: #fff;
	height: 50px;
	min-width: 78px;
	text-align: center;
	line-height: 50px;
}
.sidebar .entete .libelle_entete{
	font-size: 22px;
	color: #fff;
	font-weight: 600;
}

/* Disposition et aspect des liens de navigation */
.sidebar .liens-navigation{
	height: 100%;
	padding: 30px 0 150px 0;
	overflow: auto;
}

.sidebar .liens-navigation li a{
	text-decoration: none;
	display: flex;
	align-items: center;
	color: #fff;
}
.sidebar .liens-navigation li a .libelle_lien{
	font-size: 18px;
	font-weight: 400;
}
.sidebar .liens-navigation li i{
	height: 50px;
	min-width: 78px;
	text-align: center;
	line-height: 50px;
	font-size: 20px;
}

/* Affichage des sous menus */
.sidebar .liens-navigation li .sous_menu{
	padding: 6px 6px 14px 80px;
	margin-top: -10px;
	background: #1d1b31;
}
.sidebar .liens-navigation li .sous_menu a{
	font-size: 15px;
	padding: 5px 0;
	white-space: nowrap;
	opacity: 0.6;
}

/* Aspect de l'espace de travail */
.espace_travail header{
	height: 60px;
	display: flex;
	align-items: center;
	color: #11101d;
	font-size: 35px;
}
.espace_travail header .text {
	font-size: 26px;
	font-weight: 600;
}
.espace_travail header i {
	margin: 0 15px;
	cursor: pointer;
}

Menu déroulant

L'objectif de cette partie est de mettre en place le mécanisme permettant d'afficher et de cacher le sous menu

Le script suivant permet d'ajouter la classe afficherMenu aux balises li au dessus des .menu_deroulant cliqués

let m=document.querySelectorAll(".menu_deroulant");
for (var i = 0; i < m.length; i++) {
	m[i].onclick = function(event) {
		event.srcElement.parentElement.parentElement.classList.toggle("afficherMenu");
	};
}
Concrètement, la classe est ajoutée de cette manière :
<li class="afficherMenu">					
	<a class="menu_deroulant" href="#">
		<i class="far fa-list-alt"></i>
		<span class="libelle_lien">Catégories</span>
	</a>
	<ul class="sous_menu">
		<li><a href="#">HTML & CSS</a></li>
		<li><a href="#">JavaScript</a></li>
		<li><a href="#">PHP & MySQL</a></li>
	</ul>
</li>

Js

let m=document.querySelectorAll(".menu_deroulant");
for (var i = 0; i < m.length; i++) {
	m[i].onclick = function(event) {
		event.srcElement.parentElement.parentElement.classList.toggle("afficherMenu");
	};
}

Html

<!DOCTYPE html>
<html lang="fr">
	<head>
		<meta charset="UTF-8">
		<title>Menu dépliant</title>
		<link rel="stylesheet" href="style.css">
		<link rel="stylesheet" href="vendor/fontawesome-free-5.15.4-web/css/all.css">
	</head>
	<body>
		<nav class="sidebar">
		
			<div class="entete">
				<i class="fas fa-chalkboard-teacher"></i>
				<span class="libelle_entete">Menu</span>
			</div>

			<ul class="liens-navigation">
				<li>
					<a href="#">
						<i class="fas fa-home"></i>
						<span class="libelle_lien">Accueil</span>
					</a>
				</li>
				<li>					
					<a class="menu_deroulant" href="#">
						<i class="far fa-list-alt"></i>
						<span class="libelle_lien">Catégories</span>
						<i class="fas fa-chevron-down fleche"></i>
					</a>
					<ul class="sous_menu">
						<li><a href="#">HTML & CSS</a></li>
						<li><a href="#">JavaScript</a></li>
						<li><a href="#">PHP & MySQL</a></li>
					</ul>
				</li>
				<li>
					<a href="#">
						<i class="fas fa-cog"></i>
						<span class="libelle_lien">Paramètres</span>
					</a>
				</li>
			</ul>
		</nav>
		
		<section class="espace_travail">
			<header class="home-content">
				<i class="fas fa-bars"></i>
				<span class="text">Application exemple</span>
			</header>
		</section>

		<script src="script.js"></script>
	</body>
</html>

CSS

@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap');
*{
	margin: 0;
	padding: 0;
	box-sizing: border-box;
	font-family: 'Poppins', sans-serif;
}

/* Positionnement des éléments */
.sidebar{
	position: fixed;
	top: 0;
	left: 0;
	height: 100%;
	width: 260px;
	background: #11101d;
	z-index: 100;
}
.espace_travail{
	position: relative;
	background: #E4E9F7;
	height: 100vh;
	left: 260px;
	width: calc(100% - 260px);
}

/* Aspect du menu*/

/* Disposition de l'entete et aspect */
.sidebar .entete{
	height: 60px;
	width: 100%;
	display: flex;
	align-items: center;
}
.sidebar .entete i{
	font-size: 30px;
	color: #fff;
	height: 50px;
	min-width: 78px;
	text-align: center;
	line-height: 50px;
}
.sidebar .entete .libelle_entete{
	font-size: 22px;
	color: #fff;
	font-weight: 600;
}

/* Disposition et aspect des liens de navigation */
.sidebar .liens-navigation{
	height: 100%;
	padding: 30px 0 150px 0;
	overflow: auto;
}

.sidebar .liens-navigation li a{
	text-decoration: none;
	display: flex;
	align-items: center;
	color: #fff;
}
.sidebar .liens-navigation li a .libelle_lien{
	font-size: 18px;
	font-weight: 400;
}
.sidebar .liens-navigation li i{
	height: 50px;
	min-width: 78px;
	text-align: center;
	line-height: 50px;
	font-size: 20px;
}

/* Affichage des sous menus */
.sidebar .liens-navigation li .sous_menu{
	padding: 6px 6px 14px 80px;
	margin-top: -10px;
	background: #1d1b31;
	display:none;
}
.sidebar .liens-navigation li .sous_menu a{
	font-size: 15px;
	padding: 5px 0;
	white-space: nowrap;
	opacity: 0.6;
}

/* Aspect de l'espace de travail */
.espace_travail header{
	height: 60px;
	display: flex;
	align-items: center;
	color: #11101d;
	font-size: 35px;
}
.espace_travail header .text {
	font-size: 26px;
	font-weight: 600;
}
.espace_travail header i {
	margin: 0 15px;
	cursor: pointer;
}

/* Gestion du menu déroulant */
.sidebar .liens-navigation li.afficherMenu .sous_menu{
  display: block;
}
.sidebar .liens-navigation li.afficherMenu i.fleche {
  transform: rotate(-180deg);
}

Afficher cacher la sidebar

L'objectif de cette partie est de mettre en place le mécanisme permettant d'afficher et de cacher la sidebar

Le script suivant permet d'ajouter la classe fermer à la balise nav lors du clic sur le burger-button

let sidebar = document.querySelector(".sidebar");
let sidebarBtn = document.querySelector(".fa-bars");
sidebarBtn.addEventListener("click", ()=>{
  sidebar.classList.toggle("fermer");
});

Concrètement, la classe est ajoutée de cette manière :

<body>
		<nav class="sidebar fermer">

Js

let m=document.querySelectorAll(".menu_deroulant");
for (var i = 0; i < m.length; i++) {
	m[i].onclick = function(event) {
		event.srcElement.parentElement.parentElement.classList.toggle("afficherMenu");
	};
}

let sidebar = document.querySelector(".sidebar");
let sidebarBtn = document.querySelector(".fa-bars");
sidebarBtn.addEventListener("click", ()=>{
  sidebar.classList.toggle("fermer");
});

Html

<!DOCTYPE html>
<html lang="fr">
	<head>
		<meta charset="UTF-8">
		<title>Menu dépliant</title>
		<link rel="stylesheet" href="style.css">
		<link rel="stylesheet" href="vendor/fontawesome-free-5.15.4-web/css/all.css">
	</head>
	<body>
		<nav class="sidebar">
		
			<div class="entete">
				<i class="fas fa-chalkboard-teacher"></i>
				<span class="libelle_entete">Menu</span>
			</div>

			<ul class="liens-navigation">
				<li>
					<a href="#">
						<i class="fas fa-home"></i>
						<span class="libelle_lien">Accueil</span>
					</a>
				</li>
				<li>					
					<a class="menu_deroulant" href="#">
						<i class="far fa-list-alt"></i>
						<span class="libelle_lien">Catégories</span>
						<i class="fas fa-chevron-down fleche"></i>
					</a>
					<ul class="sous_menu">
						<li><a href="#">HTML & CSS</a></li>
						<li><a href="#">JavaScript</a></li>
						<li><a href="#">PHP & MySQL</a></li>
					</ul>
				</li>
				<li>
					<a href="#">
						<i class="fas fa-cog"></i>
						<span class="libelle_lien">Paramètres</span>
					</a>
				</li>
			</ul>
		</nav>
		
		<section class="espace_travail">
			<header class="home-content">
				<i class="fas fa-bars"></i>
				<span class="text">Application exemple</span>
			</header>
		</section>

		<script src="script.js"></script>
	</body>
</html>

CSS

@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap');
*{
	margin: 0;
	padding: 0;
	box-sizing: border-box;
	font-family: 'Poppins', sans-serif;
}

/* Positionnement des éléments */
.sidebar{
	position: fixed;
	top: 0;
	left: 0;
	height: 100%;
	width: 260px;
	background: #11101d;
	z-index: 100;
}
.espace_travail{
	position: relative;
	background: #E4E9F7;
	height: 100vh;
	left: 260px;
	width: calc(100% - 260px);
}

/* Aspect du menu*/

/* Disposition de l'entete et aspect */
.sidebar .entete{
	height: 60px;
	width: 100%;
	display: flex;
	align-items: center;
}
.sidebar .entete i{
	font-size: 30px;
	color: #fff;
	height: 50px;
	min-width: 78px;
	text-align: center;
	line-height: 50px;
}
.sidebar .entete .libelle_entete{
	font-size: 22px;
	color: #fff;
	font-weight: 600;
}

/* Disposition et aspect des liens de navigation */
.sidebar .liens-navigation{
	height: 100%;
	padding: 30px 0 150px 0;
	overflow: auto;
}

.sidebar .liens-navigation li a{
	text-decoration: none;
	display: flex;
	align-items: center;
	color: #fff;
}
.sidebar .liens-navigation li a .libelle_lien{
	font-size: 18px;
	font-weight: 400;
}
.sidebar .liens-navigation li i{
	height: 50px;
	min-width: 78px;
	text-align: center;
	line-height: 50px;
	font-size: 20px;
}

/* Affichage des sous menus */
.sidebar .liens-navigation li .sous_menu{
	padding: 6px 6px 14px 80px;
	margin-top: -10px;
	background: #1d1b31;
	display:none;
}
.sidebar .liens-navigation li .sous_menu a{
	font-size: 15px;
	padding: 5px 0;
	white-space: nowrap;
	opacity: 0.6;
}

/* Aspect de l'espace de travail */
.espace_travail header{
	height: 60px;
	display: flex;
	align-items: center;
	color: #11101d;
	font-size: 35px;
}
.espace_travail header .text {
	font-size: 26px;
	font-weight: 600;
}
.espace_travail header i {
	margin: 0 15px;
	cursor: pointer;
}

/* Gestion du menu déroulant */
.sidebar .liens-navigation li.afficherMenu .sous_menu{
  display: block;
}
.sidebar .liens-navigation li.afficherMenu i.fleche {
  transform: rotate(-180deg);
}

/* Gestion de la fermeture de la sidebar */
.sidebar.fermer{
  width: 78px;
}
.sidebar.fermer ~ .espace_travail{
  left: 78px;
  width: calc(100% - 78px);
}
.sidebar.fermer .libelle_entete {
	display:none;
}

/* Gestion de l'affichage des sous menus barre fermée */
.sidebar.fermer .liens-navigation li .sous_menu .libelle_lien{
  font-size: 18px;
  opacity: 1;
  display: block;
}
.sidebar.fermer .liens-navigation li .sous_menu{
  position: absolute;
  left: 100%;
  top: -10px;
  margin-top: 0;
  padding: 10px 20px;
  border-radius: 0 6px 6px 0;
  opacity: 0;
  display: block;
  pointer-events: none;
}
.sidebar.fermer .liens-navigation li:hover .sous_menu{
  top: 0;
  opacity: 1;
  pointer-events: auto;
}
.sidebar .liens-navigation li{
  position: relative;
}
.sidebar.fermer .liens-navigation{
  overflow: visible;
}
.sidebar.fermer .liens-navigation li a .libelle_lien, .sidebar.fermer .liens-navigation li a .fleche {
  display:none;
}

Ajout des animations

L'objectif de cette partie est d'ajouter des animations css lors des transitions

Js

let m=document.querySelectorAll(".menu_deroulant");
for (var i = 0; i < m.length; i++) {
	m[i].onclick = function(event) {
		event.srcElement.parentElement.parentElement.classList.toggle("afficherMenu");
	};
}

let sidebar = document.querySelector(".sidebar");
let sidebarBtn = document.querySelector(".fa-bars");
sidebarBtn.addEventListener("click", ()=>{
  sidebar.classList.toggle("fermer");
});

Html

<!DOCTYPE html>
<html lang="fr">
	<head>
		<meta charset="UTF-8">
		<title>Menu dépliant</title>
		<link rel="stylesheet" href="style.css">
		<link rel="stylesheet" href="vendor/fontawesome-free-5.15.4-web/css/all.css">
	</head>
	<body>
		<nav class="sidebar">
		
			<div class="entete">
				<i class="fas fa-chalkboard-teacher"></i>
				<span class="libelle_entete">Menu</span>
			</div>

			<ul class="liens-navigation">
				<li>
					<a href="#">
						<i class="fas fa-home"></i>
						<span class="libelle_lien">Accueil</span>
					</a>
				</li>
				<li>					
					<a class="menu_deroulant" href="#">
						<i class="far fa-list-alt"></i>
						<span class="libelle_lien">Catégories</span>
						<i class="fas fa-chevron-down fleche"></i>
					</a>
					<ul class="sous_menu">
						<li><a href="#">HTML & CSS</a></li>
						<li><a href="#">JavaScript</a></li>
						<li><a href="#">PHP & MySQL</a></li>
					</ul>
				</li>
				<li>
					<a href="#">
						<i class="fas fa-cog"></i>
						<span class="libelle_lien">Paramètres</span>
					</a>
				</li>
			</ul>
		</nav>
		
		<section class="espace_travail">
			<header class="home-content">
				<i class="fas fa-bars"></i>
				<span class="text">Application exemple</span>
			</header>
		</section>

		<script src="script.js"></script>
	</body>
</html>

CSS

@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap');
*{
	margin: 0;
	padding: 0;
	box-sizing: border-box;
	font-family: 'Poppins', sans-serif;
}

/* Positionnement des éléments */
.sidebar{
	position: fixed;
	top: 0;
	left: 0;
	height: 100%;
	width: 260px;
	background: #11101d;
	z-index: 100;
	/* Transition lors des mouvements de la sidebar */
	transition: all 0.5s ease;
}
.sidebar:not(.fermer) {
	overflow:hidden; 
	/* Car sinon le texte dépasse lors de l'animation afficher du menu 
	 * Si nous le faisons sur tout la sidebar, la popup menu fermé n'apparait plus
	 */
}
.espace_travail{
	position: relative;
	background: #E4E9F7;
	height: 100vh;
	left: 260px;
	width: calc(100% - 260px);
	/* Transition lors du contenu au redimentionnement de la sidebar */
	transition: all 0.5s ease;
}

/* Aspect du menu*/

/* Disposition de l'entete et aspect */
.sidebar .entete{
	height: 60px;
	width: 100%;
	display: flex;
	align-items: center;
}
.sidebar .entete i{
	font-size: 30px;
	color: #fff;
	height: 50px;
	min-width: 78px;
	text-align: center;
	line-height: 50px;
}
.sidebar .entete .libelle_entete{
	font-size: 22px;
	color: #fff;
	font-weight: 600;
}

/* Disposition et aspect des liens de navigation */
.sidebar .liens-navigation{
	height: 100%;
	padding: 30px 0 150px 0;
	overflow: auto;
}

.sidebar .liens-navigation li a{
	text-decoration: none;
	display: flex;
	align-items: center;
	color: #fff;
}
.sidebar .liens-navigation li a .libelle_lien{
	font-size: 18px;
	font-weight: 400;
}
.sidebar .liens-navigation li i{
	height: 50px;
	min-width: 78px;
	text-align: center;
	line-height: 50px;
	font-size: 20px;
	/* Transition lors du retournement de la flèche à côté de la catégorie */
	transition: all 0.3s ease;
}

/* Affichage des sous menus */
.sidebar .liens-navigation li .sous_menu{
	padding: 6px 6px 14px 80px;
	margin-top: -10px;
	background: #1d1b31;
	display:none;
	
}
.sidebar .liens-navigation li .sous_menu a{
	font-size: 15px;
	padding: 5px 0;
	white-space: nowrap;
	opacity: 0.6;
}

/* Aspect de l'espace de travail */
.espace_travail header{
	height: 60px;
	display: flex;
	align-items: center;
	color: #11101d;
	font-size: 35px;
}
.espace_travail header .text {
	font-size: 26px;
	font-weight: 600;
}
.espace_travail header i {
	margin: 0 15px;
	cursor: pointer;
}

/* Gestion du menu déroulant */
.sidebar .liens-navigation li.afficherMenu .sous_menu{
	display: block;
}
.sidebar .liens-navigation li.afficherMenu i.fleche {
	transform: rotate(-180deg);
}

/* Gestion de la fermeture de la sidebar */
.sidebar.fermer{
	width: 78px;
}
.sidebar.fermer ~ .espace_travail{
	left: 78px;
	width: calc(100% - 78px);
}
.sidebar.fermer .libelle_entete {
	display:none;
}

/* Gestion de l'affichage des sous menus barre fermée */
.sidebar.fermer .liens-navigation li .sous_menu .libelle_lien{
	font-size: 18px;
	opacity: 1;
	display: block;
}
.sidebar.fermer .liens-navigation li .sous_menu{
	position: absolute;
	left: 100%;
	top: -10px;
	margin-top: 0;
	padding: 10px 20px;
	border-radius: 0 6px 6px 0;
	opacity: 0;
	display: block;
	pointer-events: none;
}
.sidebar.fermer .liens-navigation li:hover .sous_menu{
	top: 0;
	opacity: 1;
	pointer-events: auto;
	transition: all 0.4s ease;
}
.sidebar .liens-navigation li{
	position: relative;
}
.sidebar.fermer .liens-navigation{
	overflow: visible;
}
.sidebar.fermer .liens-navigation li a .libelle_lien, .sidebar.fermer .liens-navigation li a .fleche {
	display:none;
}

Gestion de l'accessibilité

L'objectif de cette partie est de rendre accessible le menu, plusieurs problèmes rencontrés :

  • La navigation au clavier se fait mal
  • L'affichage du sous menu ne se fait qu'avec la souris

Nous allons utiliser le site Accede-web

Js

let m=document.querySelectorAll(".menu_deroulant");
for (var i = 0; i < m.length; i++) {
	m[i].addEventListener("click", ()=>{
		if(event.currentTarget.getAttribute("aria-expanded") == "true"){
			event.currentTarget.setAttribute("aria-expanded", "false");
		}
		else {
			event.currentTarget.setAttribute("aria-expanded", "true");
		}
		
	});
	
}

let sidebar = document.querySelector(".sidebar");
let sidebarBtn = document.querySelector("#reduction-sidebar");
sidebarBtn.addEventListener("click", ()=>{
	if(event.currentTarget.ariaExpanded == "true"){
		event.currentTarget.setAttribute("aria-expanded", "false");
	}
	else {
		event.currentTarget.setAttribute("aria-expanded", "true");
	}
	sidebar.classList.toggle("fermer");
});

let s=document.querySelectorAll(".sous_menu");
for (var i = 0; i < s.length; i++) {
	s[i].addEventListener("keyup", ()=>{
		if(event.keyCode === 27){
			event.currentTarget.parentElement.querySelector('button').focus();
		}
	});
}

let b=document.querySelectorAll(".liens-navigation li button");
for (var i = 0; i < b.length; i++) {
	b[i].addEventListener("keyup", function( event ) {
		if(event.keyCode === 13){
			if(event.currentTarget.parentElement.classList.contains("actif")){
				event.currentTarget.parentElement.classList.remove("actif");
			}
			else {
				event.currentTarget.parentElement.classList.add("actif");
			}
		}
	});
}

Html

<!DOCTYPE html>
<html lang="fr">
	<head>
		<meta charset="UTF-8">
		<title>Menu dépliant</title>
		<link rel="stylesheet" href="style.css">
		<link rel="stylesheet" href="vendor/fontawesome-free-5.15.4-web/css/all.css">
	</head>
	<body>
		<nav id="menu-principal" class="sidebar" role="navigation" aria-label="Menu principal">
		
			<div class="entete">
				<i class="fas fa-chalkboard-teacher"></i>
				<span class="libelle_entete">Menu</span>
			</div>

			<ul class="liens-navigation">
				<li>
					<a href="#">
						<i aria-hidden="true" class="fas fa-home"></i>
						<span class="libelle_lien">Accueil</span>
					</a>
				</li>
				<li>					
					<button class="menu_deroulant" aria-controls="sous_menu_categories">
						<i aria-hidden="true" class="far fa-list-alt"></i>
						<span class="libelle_lien">Catégories</span>
						<i aria-hidden="true" class="fas fa-chevron-down fleche"></i>
					</button>
					<ul id="sous_menu_categories" class="sous_menu">
						<li><a href="#">HTML & CSS</a></li>
						<li><a href="#">JavaScript</a></li>
						<li><a href="#">PHP & MySQL</a></li>
					</ul>
				</li>
				<li>
					<a href="#">
						<i aria-hidden="true" class="fas fa-cog"></i>
						<span class="libelle_lien">Paramètres</span>
					</a>
				</li>
			</ul>
		</nav>
		
		<section class="espace_travail">
			<header class="home-content">
				<button id="reduction-sidebar" class="vide" type="button" aria-label="Menu affichage de la navigation" aria-expanded="true" aria-controls="menu-principal">
					<i class="fas fa-bars"></i>
				</button>
				<span class="text">Application exemple</span>
			</header>
		</section>

		<script src="script.js"></script>
	</body>
</html>

CSS

@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap');
*{
	margin: 0;
	padding: 0;
	box-sizing: border-box;
	font-family: 'Poppins', sans-serif;
}

/* Positionnement des éléments */
.sidebar{
	position: fixed;
	top: 0;
	left: 0;
	height: 100%;
	width: 260px;
	background: #11101d;
	z-index: 100;
	/* Transition lors des mouvements de la sidebar */
	transition: all 0.5s ease;
}
.sidebar:not(.fermer) {
	overflow:hidden; 
	/* Car sinon le texte dépasse lors de l'animation afficher du menu 
	 * Si nous le faisons sur tout la sidebar, la popup menu fermé n'apparait plus
	 */
}
.espace_travail{
	position: relative;
	background: #E4E9F7;
	height: 100vh;
	left: 260px;
	width: calc(100% - 260px);
	/* Transition lors du contenu au redimentionnement de la sidebar */
	transition: all 0.5s ease;
}

/* Aspect du menu*/

/* Disposition de l'entete et aspect */
.sidebar .entete{
	height: 60px;
	width: 100%;
	display: flex;
	align-items: center;
}
.sidebar .entete i{
	font-size: 30px;
	color: #fff;
	height: 50px;
	min-width: 78px;
	text-align: center;
	line-height: 50px;
}
.sidebar .entete .libelle_entete{
	font-size: 22px;
	color: #fff;
	font-weight: 600;
}

/* Disposition et aspect des liens de navigation */
.sidebar .liens-navigation{
	height: 100%;
	padding: 30px 0 150px 0;
	overflow: auto;
}

.sidebar .liens-navigation li a, .sidebar .liens-navigation li button{
	text-decoration: none;
	display: flex;
	align-items: center;
	color: #fff;
}
.sidebar .liens-navigation li a .libelle_lien{
	font-size: 18px;
	font-weight: 400;
}
.sidebar .liens-navigation li i{
	height: 50px;
	min-width: 78px;
	text-align: center;
	line-height: 50px;
	font-size: 20px;
	/* Transition lors du retournement de la flèche à côté de la catégorie */
	transition: all 0.3s ease;
}

/* Affichage des sous menus */
.sidebar .liens-navigation li .sous_menu{
	padding: 6px 6px 14px 80px;
	margin-top: -10px;
	background: #1d1b31;
	display:none;
	
}
.sidebar .liens-navigation li .sous_menu a{
	font-size: 15px;
	padding: 5px 0;
	white-space: nowrap;
	opacity: 0.6;
}

/* Aspect de l'espace de travail */
.espace_travail header{
	height: 60px;
	display: flex;
	align-items: center;
	color: #11101d;
	font-size: 35px;
}
.espace_travail header .text {
	font-size: 26px;
	font-weight: 600;
}

/* Gestion du menu déroulant */
.sidebar .liens-navigation li button[aria-expanded="true"] ~ .sous_menu{
	display: block;
}
.sidebar .liens-navigation li button[aria-expanded="true"] i.fleche {
	transform: rotate(-180deg);
}

/* Gestion de la fermeture de la sidebar */
.sidebar.fermer{
	width: 78px;
}
.sidebar.fermer ~ .espace_travail{
	left: 78px;
	width: calc(100% - 78px);
}
.sidebar.fermer .libelle_entete {
	display:none;
}

/* Gestion de l'affichage des sous menus barre fermée */
.sidebar.fermer .liens-navigation li .sous_menu .libelle_lien{
	font-size: 18px;
	opacity: 1;
	display: block;
}
.sidebar.fermer .liens-navigation li .sous_menu {
	position: absolute;
	left: 100%;
	top: -10px;
	margin-top: 0;
	padding: 10px 20px;
	border-radius: 0 6px 6px 0;
	opacity: 0;
	display: none;
	pointer-events: none;
}
.sidebar.fermer .liens-navigation li:hover .sous_menu, .sidebar.fermer .liens-navigation li.actif .sous_menu {
	top: 0;
	opacity: 1;
	display: block;
	pointer-events: auto;
	transition: all 0.4s ease;
}
.sidebar .liens-navigation li {
	position: relative;
}
.sidebar.fermer .liens-navigation{
	overflow: visible;
}
.sidebar.fermer .liens-navigation li a .libelle_lien, .sidebar.fermer .liens-navigation li a .fleche, .sidebar.fermer .liens-navigation li button .libelle_lien, .sidebar.fermer .liens-navigation li button .fleche {
	display:none;
}

/* Bouton pour régler les problèmes d'accessibilité */
.vide {
	border:none;
	background:none;
	margin: 0 15px;
	cursor: pointer;
	font-size: inherit;
}
.menu_deroulant {
	border:none;
	background:inherit;
	font:inherit;
	cursor: pointer;
}