28218 sujets

CSS et mise en forme, CSS3

Bonjour,
Je développe un site avec Visual Studio Code et SCSS et j'ai un script qui met en place les styles d'un menu vertical. J'ai notamment quatre variables $menuTxt, $menuBg, $menuHover et $menuActu.
Ces variables servent à définir les background et couleurs pour les choix de menu et ça marche parfaitement bien.
Où ça se corse, c'est quand je veux intégrer les options que sont
les thèmes light et dark qui sont repérés par les classes alternatives body.light et body.dark, et aussi
le fait que le site est consulté sur mobile ou desktop ce que repère html.mobile (et html:not(.mobile). Les valeurs sont initialisées dans quatre listes SCSS dont voici un extrait de celle qui correspond à desktop light :

$desktopLightMap: (
	color: #336633,		// Txte principal (vert foncé)
	background: #ffffdd,	// Fond général (jaune très pâle)
	container: #fffff0,		// fond de boîte légèrement plus clair
	...
	menuTxt: #df6,		// texte menu
	menuBg: #121,		// fond menu si pas image
	menuHover: #fc0,		// survol
	menuActu: yellow,		// menu sélectionné
);

J'ai donc écrit ce code placé en tête du module qui gère le fameux menu :

// Initialisation des variables globales qui seront utilisées plus bas (initialisées à n'importe quelle couleur, puisqu'elles sont censées être modifiées par le code ci-dessous).
$menuTxt: red;
$menuBg: red;
$menuHover: red;
$menuActu: red;

// initialise les variables locales $menuTxt, $menuBg, $menuHover et $menuActu
// Vérifier si on est en mode "mobile" ou "desktop" en fonction de html.mobile
html.mobile {
	// ici on est en mode mobile
	body.light {
		// Mode clair en mobile
		$menuTxt: map-get($mobileLightMap, menuTxt);
		$menuBg: map-get($mobileLightMap, menuBg);
		$menuHover: map-get($mobileLightMap, menuHover);
		$menuActu: map-get($mobileLightMap, menuActu);
	}
	body.dark {
		// Mode sombre en mobile
		$menuTxt: map-get($mobileDarkMap, menuTxt);
		$menuBg: map-get($mobileDarkMap, menuBg);
		$menuHover: map-get($mobileDarkMap, menuHover);
		$menuActu: map-get($mobileDarkMap, menuActu);
	}
}
html:not(.mobile) {
	// Ici on est en mode desktop
	body.light {
		// Mode clair en desktop
		$menuTxt: map-get($desktopLightMap, menuTxt);
		$menuBg: map-get($desktopLightMap, menuBg);
		$menuHover: map-get($desktopLightMap, menuHover);
		$menuActu: map-get($desktopLightMap, menuActu);
	}
	body.dark {
		// Mode sombre en desktop
		$menuTxt: map-get($desktopDarkMap, menuTxt);
		$menuBg: map-get($desktopDarkMap, menuBg);
		$menuHover: map-get($desktopDarkMap, menuHover);
		$menuActu: map-get($desktopDarkMap, menuActu);
	}
}

Le problème pour lequel je vous consulte est que, bien que la compil se passe sans erreurs, les contenus de mes variables ne sont pas modifiés après ce passage, et celles-ci contiennent toujours du rouge.
Or il y a forcément une alternative vraie pour html.mobile / html:not(.mobile), et idem pour body.light / body.dark, car HTML initialise body par <body class="light">

Et si je remplace tout ce code par :

	$menuTxt: map-get($desktopLightMap, menuTxt);
	$menuBg: map-get($desktopLightMap, menuBg);
	$menuHover: map-get($desktopLightMap, menuHover);
	$menuActu: map-get($desktopLightMap, menuActu);

(sans les selecteurs html:not(.mobile) { body.light { devant) mes variables sont parfaitement renseignées avec les couleurs attendues.
Mais évidemment tout l'intérêt du code initial est perdu.

Où est ma faute ? Avez-vous une piste ?

Merci de m'avoir lu jusque-là.
Goggi
Modifié par goggi (02 Jul 2025 - 05:30)
À force de chercher (quand on s'en donne le temps), j'ai fini par dégoter dans la formation Sass de Pierre Giraud, l'existence d'un drapeau !global qui, comme son nom l'indique, rend global une variable. Ainsi mon problème semble bien s'être résolu en corrigeant mon code comme suit :

html.pre-mobile {
	// Si on est en mode mobile
	body.light {
		// Mode clair en mobile
		$menuTxt: map-get($mobileLightMap, menuTxt) !global;
		$menuBg: map-get($mobileLightMap, menuBg) !global;
		$menuHover: map-get($mobileLightMap, menuHover) !global;
		$menuActu: map-get($mobileLightMap, menuActu) !global;
	}
	body.dark {
		// Mode sombre en mobile
		$menuTxt: map-get($mobileDarkMap, menuTxt) !global;
		$menuBg: map-get($mobileDarkMap, menuBg) !global;
		$menuHover: map-get($mobileDarkMap, menuHover) !global;
		$menuActu: map-get($mobileDarkMap, menuActu) !global;
	}
}
html:not(.pre-mobile) {
	// Si on est en mode desktop
	body.light {
		// Mode clair en desktop
		$menuTxt: map-get($desktopLightMap, menuTxt) !global;
		$menuBg: map-get($desktopLightMap, menuBg) !global;
		$menuHover: map-get($desktopLightMap, menuHover) !global;
		$menuActu: map-get($desktopLightMap, menuActu) !global;
	}
	body.dark {
		// Mode sombre en desktop
		$menuTxt: map-get($desktopDarkMap, menuTxt) !global;
		$menuBg: map-get($desktopDarkMap, menuBg) !global;
		$menuHover: map-get($desktopDarkMap, menuHover) !global;
		$menuActu: map-get($desktopDarkMap, menuActu) !global;
	}
}

Bien cordialement,
Goggi
Sauf que finalement ça ne marche pas non plus, car les variables Scss ne servent qu'à générer le css final. Donc la solution à mon problème n'est pas au niveau de Scss.
Bonjour,

Vous devriez utiliser les variables natives à CSS (custom properties), largement supportées désormais et qui vous simplifieraient la tâche. Une seule base de code, deux listes déclaratives de variables : une liste pour le thème light, une autre pour le thème dark.

Exemple d'utilisation :
/* Thème clair par défaut */
:root {
  --bg-color: #ffffff;
  --text-color: #222222;
  --link-color: #1a0dab;
}

/* Thème sombre, activé si l'utilisateur a ce mode préféré dans son système */
@media (prefers-color-scheme: dark) {
  :root {
    --bg-color: #121212;
    --text-color: #eeeeee;
  }
}

/* Exemple d'application dans la base de code */
body {
  color: var(--text-color);
  background-color: var(--bg-color);
}

prefers-color-scheme ce n'est pas tout à fait votre demande, c'est une astuce que je vous partage. Bien sûr, libre à vous de lui préférer une classe CSS.
Modifié par Olivier C (02 Jul 2025 - 15:59)