28111 sujets

CSS et mise en forme, CSS3

Bonjour à tous,

Pour les anciens qui se rappelleront éventuellement : il y a deux ans presque jours pour jour, après avoir codé un menu accordéon, je demandais des avis d'optimisation pour le JS (et un certain Ostara m'en avait mis plein la vue avec son refactoring de mon code).

Depuis j'ai amélioré ce menu accordéon et dernièrement je l'ai encore modifié sur le plan du CSS. Voir ce CodePen : Accordion details/summary

Le truc c'est que, pour ajouter une simple bordure sur les panneaux ouverts, il me faut faire tout un schmilblick afin qu'elle ne reste pas apparente à la fermeture du panneau et aussi afin qu'elle ne disparaisse pas d'un coup avant la fermeture complète :
.accordion > * > :last-child {
  overflow: hidden;
  padding: 0 1em;
  background-color: #444;
  border: 1px solid rgba(255,255,255,0.1);
  border-top: none;
  border-radius: 0.2em;
  box-shadow: 0 1rem 1rem rgba(0,0,0,0.1);
  transition: max-height 0.5s ease-in-out;
}
.accordion > * > :last-child[aria-hidden=true] {
  max-height: 0;
  border-color: transparent; /* "Efface" la bordure, sinon elle apparaît encore lorsque le panneau est fermé. */
  transition: max-height 0.5s ease-in-out, border-color 0.5s cubic-bezier(1, 0, 1, 0); /* @note Fait disparaître la bordure au dernier moment ; mais oblige aussi à répéter la propriété max-height sinon écrasement de cette propriété. */
}

Intuitivement j'ai assez rapidement codé cette solution (transition>border-color>cubic-bezier), mais je trouve que c'est un peu abusé quand même (sortir le bazooka pour une mouche) et pas terrible pour la maintenance du code. Quelqu'un voit-il une solution plus simple ? Quelque fois, quand on a la tête dans le guidon...

Nota bene : le choix des transition CSS plutôt que d'une animation CSS est un partit pris : l'accordéon est ainsi plus réactif, contrairement à celui de Bootstrap par exemple, qui doit finir son action avant d'être à nouveau cliquable. Ma solution n'est pas sans inconvénients, mais cela est le sujet d'un autre débat...
Modifié par Olivier C (21 May 2022 - 09:09)
Salut,
tiens, j'avais aussi posé la question il y a bien deux années pour comment mettre en place ce genre d'accordéon.
Sur le second et troisième exemple de ton codepen, en suivant les aiguilles d'une montre, le panneau ouvert se referme quand on en ouvre un autre, et c'est souhaitable. Sur le premier et le quatrième exemple, on ouvre les panneaux les unes après les autres, ça devient lourd sur une page.
En mode mobile, tu as un ascenseur qui apparaît. Est-ce voulu ?
Ce genre d'accordéon est très utilisé sur les sites proposant des services (Caf, par exemple). Sur le site de la Caf, le changement est brusque, ils devraient regarder ton code et mettre une transition Smiley fache Un panneau ouvert ne se referme pas quand on ouvre l'autre, et les premiers panneaux envoient sur une autre page.

Sinon, bien, je garde en réserve ton code.
Bongota a écrit :
Tiens, j'avais aussi posé la question il y a bien deux années pour comment mettre en place ce genre d'accordéon. [...] Sinon, bien, je garde en réserve ton code.

Bien sûr ! c'est fait pour ça ! Si ça t'intéresse, j'ai aussi des onglets (à peu près) à jour sur CodePen : Tabs.

A une époque, j'avais fait un framework de tous mes trucs (une démo en ligne surtout pour moi-même) qui n'a pas été mis à jour depuis longtemps. Il y avait encore jQuery et, de notable, un générateur embarqué pour fabriquer une polices d'icônes à partir d'SVG placés dans un fichier, ça produisait le CSS à la volée, système obsolète désormais avec les SVG supportés en inline. Les grilles, basées sur flexbox avec des marges négatives, étaient avant-gardistes pour l'époque : Scriptura, Style Guide

Il est grand temps de renouveller ce framework qui date de 6 ans...

Mais ce n'est plus qu'une question de jours avant que je fasse une mise à jour énorme (js vanilla, du flexbox toujours, mais aussi grid layout pour les templates). Je repars presque de zéro sur un repository privé que je vais rendre public dans quelques temps. Le fait est que je n'ai plus le temps que j'avais auparavant pour me consacrer à mon hoby favori qu'est le dev', du coup je me concentre exclusivement sur un framework pour Express.js et Postgres, loin d'être terminé côté back, mais qui a déjà le mérite d'être quasiment achevé côté front, et qui sera la base de cette démo qui viendra remplacer la précédente.

Bongota a écrit :
Sur le second et troisième exemple de ton codepen, en suivant les aiguilles d'une montre, le panneau ouvert se referme quand on en ouvre un autre, et c'est souhaitable. Sur le premier et le quatrième exemple, on ouvre les panneaux les unes après les autres, ça devient lourd sur une page.

C'est voulu : l'accordéon se calque sur le comportement par défaut des éléments html details/summary sur lesquels il s'appuie, il faut ajouter l'option `data-singletab='true'`, comme indiquée, pour obtenir la fermeture des onglets frères. La page de démonstration montre toutes les options possibles (comme aussi un onglet ouvert par défaut avec `open='open'`).
Bongota a écrit :
En mode mobile, tu as un ascenseur qui apparaît. Est-ce voulu ?

Dans le sens horizontal ? Si la réponse est oui ce serait un problème. Le seul accordéon non encore finalisé est le quatrième, avec la note explicative en dessous.
Modifié par Olivier C (21 May 2022 - 11:10)
Dans le sens vertical. En mode mobile, c'est un peu inutile, non ?
J'ai testé avec le module adaptatif de Firefox, je vais le faire avec un vrai mobile.
Sur un mobile SAMSUNG Galaxy S6 il n'y a pas l'ascenseur. Ce n'est pas la première fois que le module adaptatif de Firefox me joue des tours.
Et c'est responsive Smiley smile
Modifié par Bongota (21 May 2022 - 11:54)
Je n'en doutais pas vraiment : cet accordéon a deux ans, le système de grille au moins autant. J'ai testé ce code en long, en large et en travers depuis tout ce temps. Smiley cligne

Mais j'en reviens à ma question initiale à propos de la bordure du panneau. Si quelqu'un a une idée...
Modifié par Olivier C (21 May 2022 - 13:01)
Modérateur
Bonjour,

Si c'est pour cacher la couleur de la bordure, elle peut-être dessinée à l'interieur avec un box-shadow au lieu d'une vertitable bordure :

ex
& > * > :last-child
    overflow hidden
    padding 0 1em
    background-color _color0
    border 1px solid _accordionColor3
    border-top none
    border-bottom none
    border-radius _r2
    box-shadow 0 1rem 1rem rgba(0, 0, 0, .1), inset 0 -1px 0 _accordionColor3
    transition max-height _accordionTime1 ease-in-out
    &[aria-hidden=true] // @note Cette spécificité empêche le lancement d'une animation au chargement de la page via le JS.
      max-height 0      
      transition max-height _accordionTime1 ease-in-out


cdt
Modifié par gcyrillus (21 May 2022 - 12:21)
Meilleure solution
Ah bah mince, ça marche nickel ! Pourquoi n'y ai-je pas pensé ? J'utilise souvent cette technique en plus... La tête dans le guidon j'vous dis...

Le code définitif :
.accordion > * > :last-child {
  /* ... */
  box-shadow: 0 1rem 1rem rgba(0,0,0,0.1), inset 0 -1px 0 1px rgba(255,255,255,0.1);
  /* ... */
}

Merci à toi gcyrillus, c'est plus propre comme cela. Sujet résolu.
Modifié par Olivier C (21 May 2022 - 12:59)