28112 sujets

CSS et mise en forme, CSS3

Bonjour,

J'ai un problème qui je le suis sûr va vous paraître bête et simple mais pourtant... je bloque dessus depuis un moment maintenant.

J'ai une div, qui au chargement de la page, est masqué. Je cherche à faire apparaître progressivement cette div, avec l'aide d'une animation, en cliquant sur un lien. Pour cela j'ajoute une classe à la div avec l'aide de Javascript. Dans ce sens tout va bien ça fonctionne.

En revanche, lorsque la classe est retirée de la div à l'aide de Javascript, j'aimerais que l'animation se déroule en sens inverse afin que celle-ci disparaisse progressivement. Et c'est là que je bloque. Impossible de faire disparaître progressivement la div en jouant sur le retrait de la classe.


body#index div#DIVguestBookingWarning {
	display: none;
	opacity: 0;
	position: absolute;
	top: 19vw;
	left: 28vw;
	max-width: 40vw;
	border-radius: 1vw;
	padding: 1vw;
	background-color: rgba(0, 102, 102, 1);
	color: rgba(255, 255, 255, 1);
	animation: DIVguestBookingWarning_recto 1s linear;
	
}

body#index div#DIVguestBookingWarning.visible {
	display: block;
	opacity: 1;
	animation: DIVguestBookingWarning_verso 1s linear;
}

@keyframes DIVguestBookingWarning_recto {
	from {
		display: none;
		opacity: 0;
	}
	1% {
		display: block;
		opacity: 0;
	}
	to {
		display: block;
		opacity: 1;
	}
}

@keyframes DIVguestBookingWarning_verso {
	from {
		display: block;
		opacity: 1;
	}
	99% {
		display: block;
		opacity: 0;
	}
	to {
		display: none;
		opacity: 0;
	}
}
Modérateur
Salut Javaslip,

Compliqué de passer par des animations juste pour un opacity. J'imagine que tu as buté sur les transitions couplées au display none ! Normal.


Smiley attention Avant de commencer ton animation à l'air d'etre montée a l'envers... j'imagine qu'au début on a pas la classe "visible" et qu'on est dons en opacity:0 et display: none.
A l'apparition on fire DIVguestBookingWarning_recto qui le fait apparaitre doucement puis disparaitre d'un coup à la fin de l'animatio (état par défaut).
En ajoutant la classe "visible" on fire l'animation DIVguestBookingWarning_verso qui fait passer de block/opacity 1 à none/opacity 0 alors qu'on y était déjà ! Et ensuite le bouton prend le style par défaut de visible soit block/opacity 1 du coup ca clignote, on dirait Noel, c'est joli, mais je pense que c'est pas ce que tu veux Smiley lol


Bon sinon pour rester dans ton exemple avec les animations il faudrait que ton anim de retour se fasse sur une seconde classe plutôt que sur l'état principal sinon quand tu enlève la classe "visible" rien ne va lancer l'animation qui était déjà la. En plus de ca pour éviter de faire tout buguer on vire les état de display par défaut pour mettre du animation-fill-mode: forwards; qui va garder l'état de la dernière frame de l'animation. Je sais pas si c'est safe de faire ça mais bon... a voir :

div#DIVguestBookingWarning {
	position: absolute;
	top: 19vw;
	left: 28vw;
	max-width: 40vw;
	border-radius: 1vw;
	padding: 1vw;
	background-color: rgba(0, 102, 102, 1);
	color: rgba(255, 255, 255, 1);
	
}



div#DIVguestBookingWarning.visible {
	animation: DIVguestBookingWarning_recto 1s linear forwards;
}
@keyframes DIVguestBookingWarning_recto {
	from {
		display: none;
		opacity: 0;
	}
	1% {
		display: block;
		opacity: 0;
	}
	to {
		display: block;
		opacity: 1;
	}
}

div#DIVguestBookingWarning.hidden {
	animation: DIVguestBookingWarning_verso 1s linear forwards;
}
@keyframes DIVguestBookingWarning_verso {
	from {
		display: block;
		opacity: 1;
	}
	99% {
		display: block;
		opacity: 0;
	}
	to {
		display: none;
		opacity: 0;
	}
}

https://jsfiddle.net/yqLmt6jn/

Et enfin en bonus la variante avec une transition :

div#DIVguestBookingWarning {
	opacity: 0;
	position: absolute;
	top: 19vw;
	left: 28vw;
	max-width: 40vw;
	border-radius: 1vw;
	padding: 1vw;
	background-color: rgba(0, 102, 102, 1);
	color: rgba(255, 255, 255, 1);
	transition: opacity 1s linear;
}

div#DIVguestBookingWarning.visible {
	opacity: 1;
}


Et si jamais ca te pose soucis qu'il soit juste en opacity en plein milieu tu as plusieurs solutions :
- mettre un z-index négatif pour qu'il passe derrière tout le reste
- mettre son padding, max-width a 0 par exemple
- l'envoyer hors de vue (top -100vw par exemple)

Pour les deux derniers points il faut tricker un peu pour éviter qu'au retour ca disparaisse d'un coup (overidder l'animation avec un délai de 1s au retour pour laisser l'opacity faire son taff)... je le mets ici parce que c'était fun Smiley banane mais bon c'est ptetre pas le top, à toi de voir
div#DIVguestBookingWarning {
	opacity: 0;
	position: absolute;
	top: -19vw;
	left: 28vw;
	max-width: 40vw;
	border-radius: 1vw;
	padding: 1vw;
	background-color: rgba(0, 102, 102, 1);
	color: rgba(255, 255, 255, 1);
	transition: opacity 1s linear, top 0s linear 1s;
}

div#DIVguestBookingWarning.visible {
	opacity: 1;
	top: 19vw;
	transition: opacity 1s linear, top 0s linear 0s;
}

https://jsfiddle.net/90f15uch/1/

Bonne nuit ! Smiley biggrin
Modifié par _laurent (29 Jul 2021 - 03:12)
_laurent a écrit :
Salut Javaslip,

Compliqué de passer par des animations juste pour un opacity. J'imagine que tu as buté sur les transitions couplées au display none ! Normal.


Exactement ! C'est une vraie merde de vouloir associer les propriétés display et opacity avec des transitions... mais pourquoi, encore aujourd'hui, la propriété display n'est toujours pas pris en charge par les transitions ? C'est à n'y rien comprendre. Surtout que cela fait des années que je vois ce type de problème revenir régulièrement sur le devant de la scène.

_laurent a écrit :
Smiley attention Avant de commencer ton animation à l'air d'etre montée a l'envers... j'imagine qu'au début on a pas la classe "visible" et qu'on est dons en opacity:0 et display: none.


C'est ça.

_laurent a écrit :
A l'apparition on fire DIVguestBookingWarning_recto qui le fait apparaitre doucement puis disparaitre d'un coup à la fin de l'animatio (état par défaut).


Tout à fait.

_laurent a écrit :
En ajoutant la classe "visible" on fire l'animation DIVguestBookingWarning_verso qui fait passer de block/opacity 1 à none/opacity 0 alors qu'on y était déjà ! Et ensuite le bouton prend le style par défaut de visible soit block/opacity 1 du coup ca clignote, on dirait Noel, c'est joli, mais je pense que c'est pas ce que tu veux Smiley lol


Non effectivement.

_laurent a écrit :
Bon sinon pour rester dans ton exemple avec les animations il faudrait que ton anim de retour se fasse sur une seconde classe plutôt que sur l'état principal sinon quand tu enlève la classe "visible" rien ne va lancer l'animation qui était déjà la. En plus de ca pour éviter de faire tout buguer on vire les état de display par défaut pour mettre du animation-fill-mode: forwards; qui va garder l'état de la dernière frame de l'animation. Je sais pas si c'est safe de faire ça mais bon... a voir :

div#DIVguestBookingWarning {
	position: absolute;
	top: 19vw;
	left: 28vw;
	max-width: 40vw;
	border-radius: 1vw;
	padding: 1vw;
	background-color: rgba(0, 102, 102, 1);
	color: rgba(255, 255, 255, 1);
	
}



div#DIVguestBookingWarning.visible {
	animation: DIVguestBookingWarning_recto 1s linear forwards;
}
@keyframes DIVguestBookingWarning_recto {
	from {
		display: none;
		opacity: 0;
	}
	1% {
		display: block;
		opacity: 0;
	}
	to {
		display: block;
		opacity: 1;
	}
}

div#DIVguestBookingWarning.hidden {
	animation: DIVguestBookingWarning_verso 1s linear forwards;
}
@keyframes DIVguestBookingWarning_verso {
	from {
		display: block;
		opacity: 1;
	}
	99% {
		display: block;
		opacity: 0;
	}
	to {
		display: none;
		opacity: 0;
	}
}

https://jsfiddle.net/yqLmt6jn/


Oui du coup je me suis lancé sur 2 classes.

_laurent a écrit :
Et enfin en bonus la variante avec une transition :

div#DIVguestBookingWarning {
	opacity: 0;
	position: absolute;
	top: 19vw;
	left: 28vw;
	max-width: 40vw;
	border-radius: 1vw;
	padding: 1vw;
	background-color: rgba(0, 102, 102, 1);
	color: rgba(255, 255, 255, 1);
	transition: opacity 1s linear;
}

div#DIVguestBookingWarning.visible {
	opacity: 1;
}


Pas la peine que je me prenne la tête avec les transitions à partir du moment où il me faut absolument la propriété display.

_laurent a écrit :
Et si jamais ca te pose soucis qu'il soit juste en opacity en plein milieu tu as plusieurs solutions :
- mettre un z-index négatif pour qu'il passe derrière tout le reste
- mettre son padding, max-width a 0 par exemple
- l'envoyer hors de vue (top -100vw par exemple)


Oui mais du coup pour le hors de vue c'est pas l'effet que je recherche. Pour le padding j'ai déjà essayé et je trouve que ça fait pas propre au niveau de l'apparition. Et pour le z-index, j'ai peur par la suite de m'y perdre si je me retrouve avec plusieurs couches.

_laurent a écrit :
Pour les deux derniers points il faut tricker un peu pour éviter qu'au retour ca disparaisse d'un coup (overidder l'animation avec un délai de 1s au retour pour laisser l'opacity faire son taff)... je le mets ici parce que c'était fun Smiley banane mais bon c'est ptetre pas le top, à toi de voir
div#DIVguestBookingWarning {
	opacity: 0;
	position: absolute;
	top: -19vw;
	left: 28vw;
	max-width: 40vw;
	border-radius: 1vw;
	padding: 1vw;
	background-color: rgba(0, 102, 102, 1);
	color: rgba(255, 255, 255, 1);
	transition: opacity 1s linear, top 0s linear 1s;
}

div#DIVguestBookingWarning.visible {
	opacity: 1;
	top: 19vw;
	transition: opacity 1s linear, top 0s linear 0s;
}

https://jsfiddle.net/90f15uch/1/

Bonne nuit ! Smiley biggrin


Bon déjà je te remercie pour ce roman. Smiley lol Du coup en reprenant l'idée des 2 classes voici ce que cela donne :


body#index div#DIVguestBookingWarning {
	display: none;
	opacity: 0;
	position: absolute;
	top: 19vw;
	left: 28vw;
	max-width: 40vw;
	border-radius: 1vw;
	padding: 1vw;
	background-color: rgba(0, 102, 102, 1);
	color: rgba(255, 255, 255, 1);
	animation: DIVguestBookingWarning_verso 1s linear forwards;
	
}

body#index div#DIVguestBookingWarning.hidden {
	animation: DIVguestBookingWarning_recto 1s linear forwards paused;
	animation: DIVguestBookingWarning_verso 1s linear forwards running;
}

body#index div#DIVguestBookingWarning.visible {
	animation: DIVguestBookingWarning_verso 1s linear forwards paused;
	animation: DIVguestBookingWarning_recto 1s linear forwards running;
}

@keyframes DIVguestBookingWarning_recto {
	from {
		display: none;
		opacity: 0;
	}
	1% {
		display: block;
		opacity: 0;
	}
	to {
		display: block;
		opacity: 1;
	}
}

@keyframes DIVguestBookingWarning_verso {
	from {
		display: block;
		opacity: 1;
	}
	99% {
		display: block;
		opacity: 0;
	}
	to {
		display: none;
		opacity: 0;
	}
}


En fait j'ai repris ton idée du fill-mode et j'y ai ajouté l'option play-state. Arrivée à ce stade tout fonctionnait sauf sur un petit détail. Lorsque l'utilisateur arrivait pour la première fois sur la page ou rechargeait celle-ci, l'animation verso se jouait et du coup on voyait la div disparaître mais bien visible tout d'abord. Du coup pour régler ce problème, j'ai bidouillé un truc, j'ai ajouté un display none et un opacity 0 sur l'état d'origine de la div, que j'enlève avec Javascript lorsque l'utilisateur clique pour la première fois sur le lien. Après je ne sais pas si ma méthode est réglo mais maintenant ça fonctionne. Merci pour ton aide.
Javaslip a écrit :

mais pourquoi, encore aujourd'hui, la propriété display n'est toujours pas pris en charge par les transitions ?


C'est un problème de logique. Il faut pouvoir calcul des états intermédiaires. Les transitions ne peuvent se calculer qu'entre des valeurs numériques. C'est quoi l'intermédiaire entre oui et non (none) ?
Modérateur
Javaslip a écrit :
Oui mais du coup pour le hors de vue c'est pas l'effet que je recherche. Pour le padding j'ai déjà essayé et je trouve que ça fait pas propre au niveau de l'apparition. Et pour le z-index, j'ai peur par la suite de m'y perdre si je me retrouve avec plusieurs couches.

Pour le coup le "hors de vue" ou le "padding" ou le "zindex" ne sont pas dans l'animation, ils sont juste la pour faire disparaitre l'élément comme un display une fois l'animation opacity finie. Tu n'as pas du regarder l'exemple ou alors tu as mal compris Smiley smile

Javaslip a écrit :
Pas la peine que je me prenne la tête avec les transitions à partir du moment où il me faut absolument la propriété display.

Pourquoi ça par curiosité ? Parceque faut avoir une raison béton pour s'embêter garder les display dans les animations...

Javaslip a écrit :
Lorsque l'utilisateur arrivait pour la première fois sur la page ou rechargeait celle-ci, l'animation verso se jouait et du coup on voyait la div disparaître mais bien visible tout d'abord. Du coup pour régler ce problème, j'ai bidouillé un truc, j'ai ajouté un display none et un opacity 0 sur l'état d'origine de la div, que j'enlève avec Javascript lorsque l'utilisateur clique pour la première fois sur le lien. Après je ne sais pas si ma méthode est réglo mais maintenant ça fonctionne.

Non ca fait un peu bricolage effectivement...


body#index div#DIVguestBookingWarning {
	animation: DIVguestBookingWarning_verso 1s linear forwards;
}

body#index div#DIVguestBookingWarning.hidden {
	animation: DIVguestBookingWarning_recto 1s linear forwards paused;
	animation: DIVguestBookingWarning_verso 1s linear forwards running;
}

body#index div#DIVguestBookingWarning.visible {
	animation: DIVguestBookingWarning_verso 1s linear forwards paused;
	animation: DIVguestBookingWarning_recto 1s linear forwards running;
}

T'as pas l'impression d'avoir eu la main lourde sur les animations ? Smiley sweatdrop

Déjà quand tu en mets deux l'une après l'autre il n'y a que la dernière qui est prise en compte comme si tu faisais :
div {
    color: blue;
    color: red;
}


Du coup je ne vois pas ce que tu veux faire avec le play-state vu que la premiere ligne en paused n'est jamais active...

Ensuite ca ne sert a rien de mettre une animation dans l'état par défaut pour exactement les meme raison (écrasé pas l'animation de la classe)... Pour ton état de départ que tu fais sauter en Js tu peux passer par une troisième classe, donc il faudrait que ca ressemble à ca :

#DIVguestBookingWarning {
	/* CSS de l'état de base hors opacity et display */
}
#DIVguestBookingWarning.hide{
	/* juste l'état de début, pas d'animation donc il n'y en aura pas au chargement */
}
body#index div#DIVguestBookingWarning.visible {
	/* animation qui fait apparaitre */
	animation: DIVguestBookingWarning_recto 1s linear forwards running;
}
body#index div#DIVguestBookingWarning.hidden {
	/* Animation qui cache */
	animation: DIVguestBookingWarning_verso 1s linear forwards running;
}


https://jsfiddle.net/ax9Ls8kf/1/

Bonne soirée
_laurent a écrit :

Pour le coup le "hors de vue" ou le "padding" ou le "zindex" ne sont pas dans l'animation, ils sont juste la pour faire disparaitre l'élément comme un display une fois l'animation opacity finie. Tu n'as pas du regarder l'exemple ou alors tu as mal compris Smiley smile


J'avais bien compris.

_laurent a écrit :
Non ca fait un peu bricolage effectivement...


body#index div#DIVguestBookingWarning {
	animation: DIVguestBookingWarning_verso 1s linear forwards;
}

body#index div#DIVguestBookingWarning.hidden {
	animation: DIVguestBookingWarning_recto 1s linear forwards paused;
	animation: DIVguestBookingWarning_verso 1s linear forwards running;
}

body#index div#DIVguestBookingWarning.visible {
	animation: DIVguestBookingWarning_verso 1s linear forwards paused;
	animation: DIVguestBookingWarning_recto 1s linear forwards running;
}

T'as pas l'impression d'avoir eu la main lourde sur les animations ? Smiley sweatdrop


Oui après coup. Pour l'animation de l'état d'origine c'était juste un oubli de ma part. Je l'ai supprimé entre temps.

_laurent a écrit :
Déjà quand tu en mets deux l'une après l'autre il n'y a que la dernière qui est prise en compte comme si tu faisais :
div {
    color: blue;
    color: red;
}


Du coup je ne vois pas ce que tu veux faire avec le play-state vu que la premiere ligne en paused n'est jamais active...


Du coup oui j'ai corrigé.

_laurent a écrit :
Ensuite ca ne sert a rien de mettre une animation dans l'état par défaut pour exactement les meme raison (écrasé pas l'animation de la classe)...


Oui comme dit plus haut c'était un oubli bête.

_laurent a écrit :
Pour ton état de départ que tu fais sauter en Js tu peux passer par une troisième classe, donc il faudrait que ca ressemble à ca :

#DIVguestBookingWarning {
	/* CSS de l'état de base hors opacity et display */
}
#DIVguestBookingWarning.hide{
	/* juste l'état de début, pas d'animation donc il n'y en aura pas au chargement */
}
body#index div#DIVguestBookingWarning.visible {
	/* animation qui fait apparaitre */
	animation: DIVguestBookingWarning_recto 1s linear forwards running;
}
body#index div#DIVguestBookingWarning.hidden {
	/* Animation qui cache */
	animation: DIVguestBookingWarning_verso 1s linear forwards running;
}


https://jsfiddle.net/ax9Ls8kf/1/

Bonne soirée


Bon pas besoin de 3ème classe. J'ai corrigé et ça fonctionne. Je vais quand même gardé l'action de Javascript sur le CSS car au final ça va me servir pour autre chose. Voici ce que ça donne :


body#index div#DIVguestBookingWarning {
	display: none;
	opacity: 0;
	position: absolute;
	top: 19vw;
	left: 28vw;
	max-width: 40vw;
	border: solid 1vw rgba(0, 102, 102, 1);
	border-radius: 1vw;
	padding: 1vw;
	background-color: rgba(255, 255, 255, 1);
	color: rgba(0, 102, 102, 1);
}

body#index div#DIVguestBookingWarning.hidden { animation: DIVguestBookingWarning_verso 1s linear forwards; }

body#index div#DIVguestBookingWarning.visible { animation: DIVguestBookingWarning_recto 1s linear forwards; }

@keyframes DIVguestBookingWarning_recto {
	from {
		display: none;
		opacity: 0;
	}
	1% {
		display: block;
		opacity: 0;
	}
	to {
		display: block;
		opacity: 1;
	}
}

@keyframes DIVguestBookingWarning_verso {
	from {
		display: block;
		opacity: 1;
	}
	99% {
		display: block;
		opacity: 0;
	}
	to {
		display: none;
		opacity: 0;
	}
}


Bonne soirée.