improved responsive framework
This commit is contained in:
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
@@ -44,13 +44,13 @@ gsap.registerPlugin(ScrollTrigger);
|
|||||||
console.log('gsap_mm', gsap_mm);
|
console.log('gsap_mm', gsap_mm);
|
||||||
|
|
||||||
// Frontière mobile ↔ tablette : source unique = _breakpoints.scss,
|
// Frontière mobile ↔ tablette : source unique = _breakpoints.scss,
|
||||||
// publiée en variable CSS --bp-mobile par _base.scss. Plus de littéral
|
// publiée en variable CSS --bp-tablette (début inclusif de la zone
|
||||||
// ici — le couple mq(mobile)/mq-above(mobile) du CSS est exclusif par
|
// tablette) par _base.scss. Plus de littéral ici — même requête que
|
||||||
// construction, le JS doit l'être aussi (bug « à 768px pile », review #94).
|
// $desktop-et-tablette, complément de $mobile (max-width: 767.98px) :
|
||||||
const bpMobile = getComputedStyle(document.documentElement)
|
// le JS est exclusif du CSS mobile (bug « à 768px pile », review #94).
|
||||||
.getPropertyValue('--bp-mobile').trim() || '767px';
|
const bpTablette = getComputedStyle(document.documentElement)
|
||||||
// Condition desktop STRICTEMENT au-dessus de la zone mobile, complémentaire du CSS.
|
.getPropertyValue('--bp-tablette').trim() || '768px';
|
||||||
const desktopQuery = `(min-width: calc(${bpMobile} + 1px))`;
|
const desktopQuery = `(min-width: ${bpTablette})`;
|
||||||
|
|
||||||
// Instance Lenis partagée : initPageFull en a besoin pour resynchroniser la
|
// Instance Lenis partagée : initPageFull en a besoin pour resynchroniser la
|
||||||
// plage de scroll après avoir gonflé le spacer (voir ensureScrollForTitle).
|
// plage de scroll après avoir gonflé le spacer (voir ensureScrollForTitle).
|
||||||
|
|||||||
@@ -8,19 +8,26 @@
|
|||||||
// Aucun CSS émis. LA seule maison des seuils de largeur du thème.
|
// Aucun CSS émis. LA seule maison des seuils de largeur du thème.
|
||||||
//
|
//
|
||||||
// ─── Modèle ──────────────────────────────────────────────────────────────────
|
// ─── Modèle ──────────────────────────────────────────────────────────────────
|
||||||
// Thème desktop-first. Trois familles de variables :
|
// Thème desktop-first. Chaque valeur de $bp est le DÉBUT d'une zone (sa
|
||||||
|
// première largeur, inclusive). Une zone finit à « début suivant − 0.02px »
|
||||||
|
// ($fin) : syntaxe min-/max-width classique, compatible partout (la syntaxe
|
||||||
|
// d'intervalle « width < X » exige Safari ≥ 16.4). Le 0.02px (convention
|
||||||
|
// Bootstrap) réduit le trou entre deux zones aux largeurs fractionnaires
|
||||||
|
// (zoom, DPR non entier) à l'intervalle ]767.98, 768[ — en pratique jamais.
|
||||||
|
//
|
||||||
|
// narrow < 432 ≤ mobile < 768 ≤ tablette < 1024 ≤ desktop
|
||||||
//
|
//
|
||||||
// 1. Zones imbriquées vers le bas — « cette zone et tout ce qui est
|
// 1. Zones imbriquées vers le bas — « cette zone et tout ce qui est
|
||||||
// plus étroit » :
|
// plus étroit » :
|
||||||
// @media #{$tablette}{ ... } ≤ 1023 (contient mobile)
|
// @media #{$tablette}{ ... } < 1024 (contient mobile)
|
||||||
// @media #{$mobile}{ ... } ≤ 767 (contient narrow)
|
// @media #{$mobile}{ ... } < 768 (contient narrow)
|
||||||
// @media #{$narrow}{ ... } ≤ 431
|
// @media #{$narrow}{ ... } < 432
|
||||||
//
|
//
|
||||||
// 2. Le grand format — desktop + tablette ensemble (≥ 768) :
|
// 2. Le grand format — desktop + tablette ensemble (≥ 768) :
|
||||||
// @media #{$desktop-et-tablette}{ ... }
|
// @media #{$desktop-et-tablette}{ ... }
|
||||||
// C'est le complément EXACT de $mobile (aucune largeur ne matche les
|
// C'est le complément de $mobile (aucune largeur ne matche les deux) :
|
||||||
// deux) : pour les composants écrits en deux blocs explicites
|
// pour les composants écrits en deux blocs explicites (grand format /
|
||||||
// (grand format / mobile).
|
// mobile).
|
||||||
//
|
//
|
||||||
// 3. Formats seuls — exactement une zone, ni plus ni moins :
|
// 3. Formats seuls — exactement une zone, ni plus ni moins :
|
||||||
// @media #{$seulement-desktop}{ ... } ≥ 1024
|
// @media #{$seulement-desktop}{ ... } ≥ 1024
|
||||||
@@ -29,41 +36,46 @@
|
|||||||
// (seulement-narrow ≡ $narrow : rien en dessous.)
|
// (seulement-narrow ≡ $narrow : rien en dessous.)
|
||||||
//
|
//
|
||||||
// ─── Disciplines ────────────────────────────────────────────────────────────
|
// ─── Disciplines ────────────────────────────────────────────────────────────
|
||||||
// 1. Jamais de nombre brut égal à un seuil : interpoler une variable de zone.
|
// 1. Jamais de nombre brut égal à un seuil : interpoler une requête nommée.
|
||||||
// 2. Une valeur découverte pendant le pass responsive s'écrit brute avec un
|
// 2. Une valeur découverte pendant le pass responsive s'écrit brute avec un
|
||||||
// commentaire et se consolide ICI quand 2+ composants convergent dessus.
|
// commentaire et se consolide ICI quand 2+ composants convergent dessus.
|
||||||
// 3. Le JS consomme ces seuils par les variables CSS --bp-* (posées dans
|
// 3. Le JS consomme ces seuils par les variables CSS --bp-* (posées dans
|
||||||
// _base.scss) : plus jamais de littéral dans main.js. Le bug « à 768px
|
// _base.scss) : plus jamais de littéral dans main.js. Le bug « à 768px
|
||||||
// pile » de la review venait d'un chevauchement CSS/JS — les zones sont
|
// pile » de la review (#94) venait d'un chevauchement CSS/JS — les zones
|
||||||
// exclusives par construction, le JS doit l'être aussi.
|
// sont exclusives par construction, le JS doit l'être aussi.
|
||||||
// 4. Un futur leshed.breakpoints.yml (images responsives) doit reprendre
|
// 4. Un futur leshed.breakpoints.yml (images responsives) doit reprendre
|
||||||
// exactement ces valeurs.
|
// exactement ces valeurs.
|
||||||
|
// 5. L'ancrage du layout (1112px) n'est pas un seuil : il est calculé dans
|
||||||
|
// _variables.scss ($layout-anchor).
|
||||||
|
|
||||||
@use "sass:map";
|
@use "sass:map";
|
||||||
|
|
||||||
$bp: (
|
$bp: (
|
||||||
// Ancre du layout (contenu + padding proportionnels) — référencée par _fluid.
|
// Début de la zone mobile ; en dessous : narrow (accueil) — découverte
|
||||||
layout: 1112px,
|
// à re-valider au pass 1 (432 = l'iPhone Pro Max à 430 reste narrow).
|
||||||
// Frontière tablette ↔ desktop : la zone desktop commence À 1024 (inclusive).
|
mobile: 432px,
|
||||||
|
// Début de la zone tablette = fin du mobile. 768 pile est tablette :
|
||||||
|
// c'est la frontière CSS/JS du bug #94.
|
||||||
|
tablette: 768px,
|
||||||
|
// Début de la zone desktop.
|
||||||
desktop: 1024px,
|
desktop: 1024px,
|
||||||
// Frontière mobile ↔ tablette : la zone mobile finit À 767 (inclusive).
|
|
||||||
// 767 et pas 768 : à 768 pile, l'ancien couple max-width:768/min-width:769
|
|
||||||
// laissait la requête mobile cohabiter avec le JS desktop — review #94.
|
|
||||||
mobile: 767px,
|
|
||||||
// Zone étroit (accueil) — découverte à re-valider au pass 1.
|
|
||||||
narrow: 431px,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Dernière largeur d'une zone : juste avant le début de la suivante.
|
||||||
|
@function fin($zone-suivante) {
|
||||||
|
@return map.get($bp, $zone-suivante) - 0.02px;
|
||||||
|
}
|
||||||
|
|
||||||
// ─── Zones imbriquées vers le bas ────────────────────────────────────────────
|
// ─── Zones imbriquées vers le bas ────────────────────────────────────────────
|
||||||
// Dérivées de $bp : changer un seuil recalcule tout (CSS, --bp-*, JS).
|
// Dérivées de $bp : changer un seuil recalcule tout (CSS, --bp-*, JS).
|
||||||
$tablette: "(max-width: calc(#{map.get($bp, desktop)} - 1px))";
|
$tablette: "(max-width: #{fin(desktop)})";
|
||||||
$mobile: "(max-width: #{map.get($bp, mobile)})";
|
$mobile: "(max-width: #{fin(tablette)})";
|
||||||
$narrow: "(max-width: #{map.get($bp, narrow)})";
|
$narrow: "(max-width: #{fin(mobile)})";
|
||||||
|
|
||||||
// Le grand format : desktop + tablette — complément exact de $mobile.
|
// Le grand format : desktop + tablette — complément de $mobile.
|
||||||
$desktop-et-tablette: "(min-width: calc(#{map.get($bp, mobile)} + 1px))";
|
$desktop-et-tablette: "(min-width: #{map.get($bp, tablette)})";
|
||||||
|
|
||||||
// ─── Formats seuls ───────────────────────────────────────────────────────────
|
// ─── Formats seuls ───────────────────────────────────────────────────────────
|
||||||
$seulement-desktop: "(min-width: #{map.get($bp, desktop)})";
|
$seulement-desktop: "(min-width: #{map.get($bp, desktop)})";
|
||||||
$seulement-tablette: "(min-width: calc(#{map.get($bp, mobile)} + 1px)) and (max-width: calc(#{map.get($bp, desktop)} - 1px))";
|
$seulement-tablette: "(min-width: #{map.get($bp, tablette)}) and (max-width: #{fin(desktop)})";
|
||||||
$seulement-mobile: "(min-width: calc(#{map.get($bp, narrow)} + 1px)) and (max-width: #{map.get($bp, mobile)})";
|
$seulement-mobile: "(min-width: #{map.get($bp, mobile)}) and (max-width: #{fin(tablette)})";
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
header{
|
header{
|
||||||
.field_dates{
|
.field_dates{
|
||||||
@include event-date-time(5em);
|
@include event-date-time(3.5em);
|
||||||
span.date-sep{
|
span.date-sep{
|
||||||
display: block;
|
display: block;
|
||||||
width: 1em;
|
width: 1em;
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
|
|
||||||
@use "sass:math";
|
@use "sass:math";
|
||||||
@use "fluid" as *;
|
@use "fluid" as *;
|
||||||
@use "../abstracts/breakpoints" as *;
|
|
||||||
|
|
||||||
@mixin event-date-time($ref: 10em){
|
@mixin event-date-time($ref: 7em){
|
||||||
display: flex;
|
display: flex;
|
||||||
position: relative;
|
position: relative;
|
||||||
// Métriques propres aux dates : elles dépendaient avant du bloc de masquage
|
// Métriques propres aux dates : elles dépendaient avant du bloc de masquage
|
||||||
@@ -16,9 +15,6 @@
|
|||||||
// dérivent de --ref : le bloc entier rétrécit en lock-step, sans désaligner
|
// dérivent de --ref : le bloc entier rétrécit en lock-step, sans désaligner
|
||||||
// la grille par rapport à la typo. NB : les em sont convertis via px() sur
|
// la grille par rapport à la typo. NB : les em sont convertis via px() sur
|
||||||
// hypothèse d'un contexte de 16px.
|
// hypothèse d'un contexte de 16px.
|
||||||
@media #{$mobile}{
|
|
||||||
$ref:calc($ref * 0.7);
|
|
||||||
}
|
|
||||||
--ref: #{fluid-clamp(px($ref), $min: math.div(px($ref), 1.5))};
|
--ref: #{fluid-clamp(px($ref), $min: math.div(px($ref), 1.5))};
|
||||||
time{
|
time{
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|||||||
@@ -11,13 +11,13 @@
|
|||||||
// → la taille vaut 5rem tant que le viewport tient le layout complet
|
// → la taille vaut 5rem tant que le viewport tient le layout complet
|
||||||
// (contenu + padding latéral), suit la largeur du viewport en dessous,
|
// (contenu + padding latéral), suit la largeur du viewport en dessous,
|
||||||
// plancher $min.
|
// plancher $min.
|
||||||
// Le point de passage est dérivé de $layout-anchor : recalage
|
// Le point de passage est dérivé de $layout-anchor (_variables.scss) :
|
||||||
// automatique si le plafond du layout ou son padding changent.
|
// recalage automatique si le plafond du layout ou son padding changent.
|
||||||
|
// Les bornes sont émises en rem : elles suivent la taille de police
|
||||||
|
// choisie par l'utilisateur (identiques au px près avec <html> à 16px).
|
||||||
|
|
||||||
@use "sass:math";
|
@use "sass:math";
|
||||||
@use "sass:map";
|
|
||||||
@use "variables" as *;
|
@use "variables" as *;
|
||||||
@use "breakpoints" as *;
|
|
||||||
|
|
||||||
$root: 16px; // taille de police de <html>
|
$root: 16px; // taille de police de <html>
|
||||||
|
|
||||||
@@ -32,20 +32,20 @@ $root: 16px; // taille de police de <html>
|
|||||||
@error "px() : px, rem ou em attendu, reçu #{$size}";
|
@error "px() : px, rem ou em attendu, reçu #{$size}";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Largeur d'ancrage des clamps : le viewport auquel le layout est plein —
|
// Convertit px, rem ou em en rem (même hypothèse de base 16px que px()).
|
||||||
// 1080px de contenu + 2 × 16px de padding = 1112px. Vit dans $bp.layout
|
@function to-rem($size) {
|
||||||
// (_breakpoints.scss, la seule maison des largeurs) — alias local pour les
|
@return math.div(px($size), $root) * 1rem;
|
||||||
// signatures de fonctions ci-dessous.
|
}
|
||||||
$layout-anchor: map.get($bp, layout);
|
|
||||||
|
|
||||||
// La valeur vw qui vaut exactement $size quand le viewport fait $at.
|
// La valeur vw qui vaut exactement $size quand le viewport fait $at
|
||||||
|
// ($layout-anchor par défaut : 1080 de contenu + 2 × padding = 1112px).
|
||||||
@function vw-at($size, $at: $layout-anchor) {
|
@function vw-at($size, $at: $layout-anchor) {
|
||||||
@return math.div(px($size), $at) * 100 * 1vw;
|
@return math.div(px($size), $at) * 100 * 1vw;
|
||||||
}
|
}
|
||||||
|
|
||||||
// $size au-dessus de $at, fluide en dessous, plancher $min.
|
// $size au-dessus de $at, fluide en dessous, plancher $min.
|
||||||
@function fluid-clamp($size, $at: $layout-anchor, $min: 0px) {
|
@function fluid-clamp($size, $at: $layout-anchor, $min: 0px) {
|
||||||
@return clamp(#{px($min)}, #{vw-at($size, $at)}, #{px($size)});
|
@return clamp(#{to-rem($min)}, #{vw-at($size, $at)}, #{to-rem($size)});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tokens dérivés : tailles de référence passées en fluide. Le plancher est
|
// Tokens dérivés : tailles de référence passées en fluide. Le plancher est
|
||||||
|
|||||||
@@ -1,10 +1,22 @@
|
|||||||
|
@use "sass:math";
|
||||||
|
|
||||||
$layout_width: 1080px;
|
$layout_width: 1080px;
|
||||||
// Padding et gap proportionnels : sous l'ancrage du layout (voir _fluid.scss,
|
|
||||||
// $layout-anchor), TOUT rétrécit ensemble (typo fluide, gouttières, colonnes) —
|
|
||||||
// les clamps vw restent exacts à toutes les largeurs. Les vw sont calés pour
|
|
||||||
// valoir exactement les bornes hautes à l'ancrage (1112px) : au-dessus, le
|
|
||||||
// design desktop est identique à l'ancien 1em/2em fixe.
|
|
||||||
$layout_padding: clamp(0.75rem, 1.4388vw, 1rem);
|
|
||||||
$default_fwght: 200;
|
$default_fwght: 200;
|
||||||
$header_height: 70px;
|
$header_height: 70px;
|
||||||
$colsgap: clamp(1.5rem, 2.8777vw, 2rem);
|
|
||||||
|
// Bornes hautes du padding latéral et de la gouttière : leur valeur au-dessus
|
||||||
|
// de l'ancrage du layout (design desktop = l'ancien 1em/2em fixe).
|
||||||
|
$layout_padding_max: 1rem;
|
||||||
|
$colsgap_max: 2rem;
|
||||||
|
|
||||||
|
// Ancrage du layout : le viewport auquel le layout est plein — contenu +
|
||||||
|
// 2 × padding latéral (1080 + 2 × 16 = 1112px). Calculé, pas écrit : changer
|
||||||
|
// $layout_width ou $layout_padding_max recale tous les clamps vw (padding,
|
||||||
|
// gouttière, typo fluide de _fluid.scss). Hypothèse : <html> à 16px.
|
||||||
|
$layout-anchor: $layout_width + 2 * math.div($layout_padding_max, 1rem) * 16px;
|
||||||
|
|
||||||
|
// Padding et gap proportionnels : sous l'ancrage, TOUT rétrécit ensemble
|
||||||
|
// (typo fluide, gouttières, colonnes) — les clamps vw restent exacts à toutes
|
||||||
|
// les largeurs. Le vw vaut exactement la borne haute à l'ancrage.
|
||||||
|
$layout_padding: clamp(0.75rem, math.div(math.div($layout_padding_max, 1rem) * 16px, $layout-anchor) * 100vw, $layout_padding_max);
|
||||||
|
$colsgap: clamp(1.5rem, math.div(math.div($colsgap_max, 1rem) * 16px, $layout-anchor) * 100vw, $colsgap_max);
|
||||||
|
|||||||
@@ -9,12 +9,12 @@
|
|||||||
@use "../abstracts/breakpoints" as *;
|
@use "../abstracts/breakpoints" as *;
|
||||||
|
|
||||||
// Seuils publiés en variables CSS : le JS (gsap.matchMedia) les lit au lieu
|
// Seuils publiés en variables CSS : le JS (gsap.matchMedia) les lit au lieu
|
||||||
// de littéraux — contrat de valeur unique, voir _breakpoints.scss.
|
// de littéraux — contrat de valeur unique, voir _breakpoints.scss. Chaque
|
||||||
|
// valeur est le début (inclusif) de sa zone.
|
||||||
:root{
|
:root{
|
||||||
--bp-layout: #{map.get($bp, layout)};
|
|
||||||
--bp-desktop: #{map.get($bp, desktop)};
|
|
||||||
--bp-mobile: #{map.get($bp, mobile)};
|
--bp-mobile: #{map.get($bp, mobile)};
|
||||||
--bp-narrow: #{map.get($bp, narrow)};
|
--bp-tablette: #{map.get($bp, tablette)};
|
||||||
|
--bp-desktop: #{map.get($bp, desktop)};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -11,9 +11,14 @@
|
|||||||
|
|
||||||
|
|
||||||
div.views-archives-projets{
|
div.views-archives-projets{
|
||||||
display: flex;
|
// Design : 4 colonnes ou 2, jamais 3 — grille explicite qui bascule au
|
||||||
flex-direction: row;
|
// seuil mobile. Une dernière rangée incomplète ne s'étire pas.
|
||||||
flex-wrap: wrap;
|
display: grid;
|
||||||
|
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||||
|
gap: $colsgap;
|
||||||
|
@media #{$mobile}{
|
||||||
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
article.node-type-projet.view-mode-tableau_liste{
|
article.node-type-projet.view-mode-tableau_liste{
|
||||||
@@ -27,25 +32,6 @@ div.views-archives-projets{
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// DESKTOP + TABLETTE (≥ 768) — gouttière + rangées de 4.
|
|
||||||
@media #{$desktop-et-tablette}{
|
|
||||||
gap: $colsgap;
|
|
||||||
div.views-row{
|
|
||||||
flex: 1 0 calc(25% - $colsgap);
|
|
||||||
width: calc(25% - $colsgap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MOBILE (≤ 767) : 2 par ligne.
|
|
||||||
@media #{$mobile}{
|
|
||||||
gap: $colsgap;
|
|
||||||
div.views-row{
|
|
||||||
flex: 1 0 calc(50% - $colsgap);
|
|
||||||
width: calc(50% - $colsgap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
form#views-exposed-form-archives-page-1{
|
form#views-exposed-form-archives-page-1{
|
||||||
div.bef-links{
|
div.bef-links{
|
||||||
|
|||||||
Reference in New Issue
Block a user