28172 sujets

CSS et mise en forme, CSS3

Mesdames, Messieux, bonjour,

Voici quelques mois que je m'arrache les cheveux sur un soucis qui va finir par me rendre chauve.

Le contexte est tel que sur une page qui contient mon contenu principal. Des informations annexes, en rapports avec ce contenu, sont accessibles par le biais d'un menu.

Au clic les informations secondaires apparaissent en premier plan, couvrant ainsi le contenu principal.

Jusqu'ici tout va bien.

Le contenu secondaire, qui peut occuper plus de 100vh, peut se faire défiler vers le bas (la largeur est fixée). Il en est de même pour le contenu principal.

Le hic est que dans cette circonstance j'obtiens deux barres de défilement vertical et c'est bien là mon problème.

Je trouve inconfortable pour l'utilisateur de se retrouver avec deux barres de défilement côte-à-côtes car d'une part cela pourrait prêter à confusion et d'autre part cela empiète sur la largeur disponible pour le contenu. Certes sur écran d'ordinateur la gêne n'est que minime mais sur mobile ?! Si je pouvais gagner ces quelques pixels en largeur ça n'en serait que mieux, n'est-ce pas ?

** Ma requête serait d'avoir au moins une piste à explorer pour endiguer le phénomène. Je ne comprends absolument pas comment je peux me dépatouiller avec ça. **

Pour dire je ne sais même pas s'il existe une solution en Css et malheureusement je n'ai aucune connaissance en JavaScript.

J'ai préparé une maquette sur Codepen qui reprend trait pour trait ce que je viens de vous énoncer.

En clair je nage en plein brouillard et ai vraiment besoin de vos lumières car la mienne est éteinte.


Au plaisir de vous lire.
Smiley smile
Modifié par Greg_Lumiere (14 Sep 2016 - 09:27)
Modérateur
Hello,

Je vois directement une solution mais c'est en passant par JS, ok pour toi ? (je veux bien faire l'exemple si tu veux).

Plutôt que d'utiliser :target c'est d'avoir 1 function qui va se jouer au click et qui va "toggle" juste ajouter une class .active sur body :
1) pour afficher ton contenu secondaire qui vient superposer le contenu principale
2) pouvoir définir le overflow à hidden de manière ponctuelle sur ton body et ainsi supprimer ton scroll principale.

Est-ce que c'est bien clair ?

Regarde par exemple comment fait Bootstrap quand il ouvre une modal... (un exemple parmi tant d'autres)
Bien vu Yordi

J'allais dire la même chose. Passer par JS pour rendre le toggle body principal overflow-y: hidden;
Yordi a écrit :

Je vois directement une solution mais c'est en passant par JS, ok pour toi ?
Bien sûr, s'agissant d'une fonction de "confort" cela ne me gène car même avec JS désactivé la page reste pratiquable.

Yordi a écrit :

Plutôt que d'utiliser :target c'est d'avoir 1 function qui va se jouer au click et qui va "toggle" juste ajouter une class .active sur body :
1) pour afficher ton contenu secondaire qui vient superposer le contenu principale
2) pouvoir définir le overflow à hidden de manière ponctuelle sur ton body et ainsi supprimer ton scroll principale.

Est-ce que c'est bien clair ?
Oui, sur la théorie je vois bien ce à quoi tu fais allusion.
Concernant l'affichage de la modale (ha y est je sais enfin ce que ça veut dire lol) je préfère confier cette tâche au Css.
Par contre l'idée d'ajouter une classe est superbe. Détecter l’évènement pour ensuite faire appliquer une classe à un élément en fonction d'un déclencheur me permettra en plus de pouvoir compléter la fonction au fil du temps tout en gardant le projet maintenable.

Yordi a écrit :

Regarde par exemple comment fait Bootstrap quand il ouvre une modal... (un exemple parmi tant d'autres)
Alors là c'est du lourd ! Je constate que Boostrap gère le sujet de A à Z (affichage + partie JS).
Toutefois je me refuse à l'utilisation de Boostrap car :
- ça implique d'importer une grosse librairie pour de petits besoins (je n'utilise déjà pas la partie css)
- ça implique aussi de revoir complètement l'implémentation de mon code ; ce n'est pas une mince affaire car l'exemple Codepen n'est qu'une bribes de mon projet global
- Boostrap ne répond pas à mes critère philosophiques qui sont de me centrer sur l'utilisateur ; c'est pourquoi je maximise le code html et css et évite au maximum le recours au JS ainsi qu'aux bibliothèques/librairie et frameworks (j'ai un côté puriste Smiley smile ) ; si JS est désactivé l'information doit rester accessible.
- de plus, et c'est là que je m'aperçois que mon exemple est incomplet car je ne présente qu'un lien annexe (vers contenu supplémentaire) mais dans la réalité des faits ces liens sont multiples ; apportant chacun une information différente mais toujours en rapport avec le contenu principal. Or si j'ai bien compris, Boostrap semble ne pas supporter ce cas de figure
Boostrap a écrit :
Multiple open modals not supported

- et d'autres raisons mais le sujet n'est pas de faire le procès de Boostrap Smiley cligne

Jencal a écrit :
Passer par JS pour rendre le toggle body principal overflow-y: hidden;

C'est sur cette idée que je me concentre de prime abord. Je comprends bien qu'en Css cela semble impossible de part le fait qu'il est impossible de remonter le DOM.


Du coup j'ai un (peu) retravaillé mon Codepen. Dans un premier temps j'essaie de faire appliquer la propriété Css à #Contenu-principal lorsqu'est détecté un évènement sur le lien complémentaire (idée de Jencal).
Quand j'aurais réussi je pense généraliser en permettant d'apposer une classe à n'importe quel élément du DOM en fonction de l'évènement (idée de Yordi).

Voici les modifications que j'ai apporté :
Sur le lien "contenu complémentaire" j'ai ajouté la classe "js-hideVscroll".
Et voici le schéma JS :
function hideVscroll()
{
  document.getElementById('Contenu-principal').style.overflowY = 'hidden';
  
}

document.addEventListener('DOMContentReady', function()
{
  document.getElementsByClassName('js-hideVscroll').addEventListener('click', hideVscroll);
});


A votre avis, suis-je sur la bonne voie ?
Modifié par Greg_Lumiere (14 Sep 2016 - 19:48)
Je suis confus, en fait la barre de scroll n'est pas provoquée par #Contenu-principal mais par Body.

Donc je remplacerais
"document.getElementById('Contenu-principal')..."
par
"document.getElementsByTagName('body')..."
Re-bonjour,

Mon code a un petit peu évoluer depuis hier. Voici où j'en suis :

function controlVscroll()
{
 var element = document.getElementsByTagName('body')['0'];
 if(element != null){
  if(element.style.overflowY !== 'hidden')
   {
     element.style.overflowY = 'hidden';
   }
  else
    {
      element.style.overflowY = 'initial';
    }
 }
}

document.addEventListener('DOMContentReady', controlVscroll())
{
  var elements = document.getElementsByClassName('js-controlVscroll');
  for (var i = 0; i < elements.lenght; i++)
    {
      elements[i].addEventListener('click', controlVscroll);
      
    }
};


Résultat : la barre de défilement vertical a disparu de l'élément Body Smiley biggrin . C'est une bonne chose, enfin oui et non car du fait impossible pour moi de la réinitialiser Smiley decu .

Il y a un truc qui cloche mais je n'arrive pas à mettre le doigt dessus. Smiley sweatdrop

Auriez-vous une idée, s'il vous plaît, du pourquoi du comment ?


Codepen [/i]
Modifié par Greg_Lumiere (15 Sep 2016 - 10:16)
Je me suis aperçus que mon précédent bout de code comportait quelques erreurs :

- element et elements semblent être des noms réservés Edit 20160918: En fait pas du tout !
- plutôt que mettre une conditionnelle pour faire basculer le style, mieux vaut utiliser l'API classList (en combinaison avec .toggle)
- malgré ce que j'ai pus lire à divers endroits (pourtant des sources a priori fiables), DOMContentReady n'existe pas. En réalité c'est DOMContentLoaded qu'il faut utiliser.
- addEventListener nécessite 3 paramètres et non deux.

Et LE TRUC qui faisait tout foirer :
- Je ne sais toujours pas écrire le mot "longeur" en anglais. Je mettais lenght au lieu de length

Du coup voici le résultat de ma recherche :
function controlVscroll()
{
 var e = document.getElementsByTagName('body')['0'];
 if(e != ''){
   e.classList.toggle('js-noVscroll');
 }
}

document.addEventListener('DOMContentLoaded', function(){
  var c = document.getElementsByClassName('js-controlVscroll');
  for(var i = 0; i < c.length; i++)
    {
      c[i].addEventListener('click', controlVscroll, false);
    }
});


Et ça fonctionne !!! Smiley biggrin

Merci Yordi et Jencal de m'avoir mis sur la voie.[/i]
Modifié par Greg_Lumiere (18 Sep 2016 - 20:29)
Modérateur
En mettant un debugger dans le for, j'avais vu qu'il ne passait pas mais je ne n'avait pas vu la faute et puis j'ai eu pas mal de boulot donc j'ai du arrêter, sorry.

Quand je vois ces lignes, je me dis que Jquery nous a (un peu) trop faciliter la vie quand même...
Alors là je devient complètement fou !!!

J'ai inséré ce script au sein de mon site en dev. Rien de compliqué, je n'ai plus qu'à copier-coller ce que j'ai mis sur Codepen.

Mais contre toute attente, ça ne fonctionne pas du tout.

Quand dans la console je recopie le script, celle-ci me renvoi undefined. C'est bien joli mais qu'est-ce qui est undefined ?

C'est à n'y rien comprendre. Auriez-vous une idée de ce qui peu bloquer ?

J'ai essayé de placer un alert() (je ne connais que cette commande) mais même en la plaçant juste après document.addEventListener('DOMContentLoaded', function() {, le script reste en mode mutisme.
Bonsoir,

Finalement après m'être arraché jusqu'au dernier cheveux, j'ai fini par trouver pourquoi mon bout de code fonctionne sur Codepen et pas sur mon site.

J'avais tous simplement commenté ce code en Html au lieu d'utiliser /**/ Smiley confused

Non seulement je n'ai plus de cheveux mais en plus je n'ai pas de tête Smiley rolleyes

Je peux (enfin) considérer ce sujet comme résolu. Smiley biggrin


Le résultat est perfectible car je n'avais pas pensé à la situation où l'utilisateur arrive directement par le contenu secondaire car dans ce cas aucun clic ne peut être détecté. A voir si je ne pourrais mettre à l'écoute l'ancre dans la barre d'adresse. Ceci donnera (certainement) lieu à un nouveau topic.


A bientôt pour de nouvelles aventure "javascriptesques" Smiley smile
Modérateur
Greg_Lumiere a écrit :
Et ça se fait comment ça, "mettre un debugger" ?


En fait, pour mettre un debugger, c'est assez simple...
//Mon super code;
debugger;
//La suite de mon super code


Le debugger, c'est vraiment l'équivalent de mettre un point d'arret dans l'onglet source du developer tools.
=> Pour mettre un point d'arret :
Developer tools > Choisir ton fichier qui contient du js dans l'arbre de gauche > Cliquer sur un N° de ligne.

Si tu as l'outil de développement ouvert, tu vas avoir alors le script qui va se mettre en pause et c'est toi qui va décider de relancer la script ou d'aller à la ligne suivante.

Ca veut dire qui tu pourras inspecter le statut de tes variables directement (dans Chrome, le résultat est indiqué à coté de la ligne) ou alors tu peux interroger via la console pour connaitre le statut de ta variable à ce moment précis du code. Tu peux également sélectionner des variables ou des bouts de code (if, ...) pour les ajouter en watch et à ce moment, tu as tes items à inspecter dans la colonne de droite (Watch).


Autre petit truc très pratique pour remplacer l'alert, c'est le console.log().
Il ne stope pas le script mais indique quelque chose dans ta console. Soit un élément, soit un string.

Tu peux utiliser les 2 sans limite, c'est super pratique et ça sauve des vies Smiley smile (dans un if, une boucle...)

exemple :

var count = 6;
console.log("J'ai mangé " + count + "kiwis");
Yordi a écrit :
plein de petits trucs intéressants...

Merci Yordi pour ces précieuses informations qui m'aident beaucoup dans ce domaine pour lequel je n'ai pas encore accordé suffisamment d'attention.


J'ai pas mal modifié mon script car mon approche n'était pas satisfaisante et omettait certain contexte utilisateur auquel je n'avais pas pensé de prime abord.

Pour ceux qui seraient intéressés, j'ai mis à jour mon code sur Codepen en laissant ma première approche et la dernière qui se révèle plus complète et efficace.
=> Comment masquer les barres de défilement en JS lors de la mise en avant d'un contenu caché ?

Bien sûr, tout avis est bon à prendre alors n'hésitez pas à être critique et/ou suggestifs. Smiley smile
Modifié par Greg_Lumiere (22 Sep 2016 - 10:25)