Скрыть элемент анимация css

How to animate an element in display none in two steps

Animate a hidden element is very simple now. We just need 2 CSS declaration and a bit of JavaScript to toggle the state open / close.

The solution

In this article:

  • CSS :not pseudo-selector
  • Single Source of truth
  • animationend event
  • Accessibility

Problem we try to solve

You have a hidden element with a hidden attribute. To provide a better UX, you want to animate this opening and closing state. But in CSS, display:none is like an interrupter; it can be «on» or «off» but animate between both state with a CSS transition is impossible.

Step 1: animate during opening

As you notice, I’m opting for a link instead of a button. Why ? Because my modal will still be accessible without JavaScript, thanks to the target CSS pseudo-class. I will focus on this point after.

JS to show the modal

modalButton.addEventListener("click", function (e) < e.preventDefault(); modal.hidden = false; >); 

CSS

That’s it. ¯_(ツ)_/¯.
If you prefer relying on .hidden class (like in Tailwind), you can switch :not([hidden]) with :not(.hidden) . If you want both, the not pseudo-class accept multiple arguments separated by a comma : not([hidden], .hidden) . Anyway, our Modal appears with a shiny animation now :

Читайте также:  Upgrade python version ubuntu

Step 2 : animate during closing

The closing state is a little more tricky. If you set the hidden attribute to «true», you won’t be able to hide it smoothly. You need to add a temporary class like is-closing to play the closing animation and then, hide the element.

JS

modal.addEventListener("click", function (e) < // Omitted… if (hasClickedOutside || hasClickedCloseButton) < modal.classList.add("is-closing"); // Omitted… 

CSS


Now our modal is closing smoothly, but it is not back to hidden state. You have to wait to the end of the animation to remove the .is-closing class and back to hidden="true" . With setTimeout ? You could, but you have a better option.

Animationend event

With a timeout , we have to declare a value at least equal to the animation duration, which can change.
If you can, you have to have a single source of truth : here, the animation duration declared in the CSS.
The animationend will wait to the end of the animation, then execute the function inside the listener.

modal.addEventListener("click", function (e) < const hasClickedOutside = !e.target.closest(".modal-main"); const hasClickedCloseButton = e.target.closest(".modal-close"); if (hasClickedOutside || hasClickedCloseButton) < modal.classList.add("is-closing"); modal.addEventListener( "animationend", function () < modal.hidden = true; modal.classList.remove("is-closing"); >, < once: true >); > >); 

Once the event is completely done, you have to destroy it with the once: true option, as you don't need it anymore.
And voilà, you have the knowledge to animate any element hidden in the DOM.

Bonus : A little accessibility enhancement

Without JS, the modal can still be open via its hash, and you can style the opened state with the :target pseudo class.
To close it, the user needs to back in your history. This is why I hide the .modal-close . It's not pertinent to show it if it can't do anything.

Don't play animation if user don't want animation.

For personal taste, medical reason or to solve a performance issue on their device, your users may not want any animation, and you have to respect their preferences. It would be a good idea to embed the following the rule as part of your CSS reset, if it's not already done.

@media (prefers-reduced-motion: reduce) < *, *::before, *::after < animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; scroll-behavior: auto !important; >> 

Источник

Как сделать css-анимацию по скрытию элемента?

Суть вот в чем, если задать элементу анимацию через keyframes, то она всегда будет исполняться когда элемент становиться видимым. Пример — jsfiddle.net/Zvyxd
Как-то можно добиться обратного эффекта когда элемент становиться display: none;?

BelkinVadim

Вы хотите сделать плавное появление и скрытие? Если да, то зачем keyframes? Можно же для элемента сделать доп.класс который отвечает за его скрытие или показ. И удалять его или добавлять.
jsfiddle.net/YxsTV

@BelkinVadim вы допускаете примерно такую же ошибку. Элемент прозрачный, но не скрытый - uimages.ru/img/6kmsacqcck.png Хотя по нему и не получается кликнуть и событие вряд ли сработает, сролл появляется и место он занимает. В общем единственным правильным решением это будет обработка событий по завершению анимации, как-то так — jsfiddle.net/Zvyxd/8

BelkinVadim

jsfiddle.net/Zvyxd/8 в этом примере скролл появляется при показе элемента. он будет появляться в любом случае если элемент у вас будет выходить за рамки размеров окна. Ну а вообще согласен с тем что лучше после завершения анимации элемент скрывать.

@BelkinVadim При показе это естественно, а вот в вашем примере он остается и после того как стал прозрачным, что как бы плохо. Только display: none; полностью скрывает отображение элемента на странице.

Я очень костыльно написал на скорую руку, но логику вы по идее должны понять, почему анимация будет работать.

@DeLaVega то что вы предлагаете не скрывает элемент, а делает его прозрачным. Он остается на своем месте, по нему можно будет кликать, будут срабатывать события и так далее. Все эти танцы с дополнительными классами я знаю, а так же можно ловить событие onAnimationEnd и в конечном счете скрывать его, но это решение не такое простое, как с показом элемента.

Дело в том, что у ксс анимаций нет колбэка. И раз вы всё равно используете js, то почему бы и анимацию целиком не написать? И да, я открывал в фоксе, у меня тоже изначально не было никакой анимации.

А то что я вам предлагаю то вместо хайд у вас будет нечто .animate()

@DeLaVega Дело в том, что у css анимации есть колбэк — www.sitepoint.com/css3-animation-javascript-event-. , но как-то не хочется. Суть вопроса в том, чтобы это было так же просто как и с показом. А в FireFox и правда не работает без префиксов -moz, я написал только для -webkit. И кстати нативная анимация на css на много быстрее и плавнее нежели js, просто не хочется вешать обработчики на события по анимации, но видимо придется. Кстати события есть как и для анимации (onAnimationEnd) так и для transition (onTransitionEnd).

@Piterski да, вы правы на счёт плавности и скорости, но всё зависит от того где применять. И как вы заметили, колбэк идёт всё равно на js, а не внутри ксс-а.

Источник

Скрыть элемент анимация css

To hide an HTML element after certain seconds using CSS, you can use the @keyframes CSS rule and set the CSS property called visibility to value hidden for that particular element in CSS.

TL;DR

div id="hideMeAfter5Seconds">Hello World! div> 
#hideMeAfter5Seconds < animation: hideAnimation 0s ease-in 5s; animation-fill-mode: forwards; > @keyframes hideAnimation < to < visibility: hidden; width: 0; height: 0; > > 

For example, let's say we have a div with some content Hello world! inside it which we need to hide after 5 seconds.

So for that let's first create the div and also set an id attribute to it so we can reference it later in the CSS. It can be done like this,

div id="hideMeAfter5Seconds">Hello World! div> 

Now in the CSS, we can refernce the hideMeAfter5Seconds div id like this,

After that, let's use the animation css property and define 4 properties like this,

#hideMeAfter5Seconds < animation: hideAnimation 0s ease-in 5s; > 

As you can see from the above css declaration, we have set some properties like hideAnimation , 0s , ease-in , and 5s .

  • The first one, hideAnimation is the name of the animation which we need to declare using the @keyframes rule. This is where we will define the auto-hiding logic for the div HTML element.
  • Advertisement area The second one is the animation duration which we have set to 0s because we don't need the animation to run for any amount of seconds. We just need to execute some properties immediately in the hideAnimation animation.
  • The third one is the animation timing function, which defines the speed curve of the animation. In our case, we have set it to be ease-in .
  • Advertisement area The fourth one is the delay of the animation which we have set to 5s so that animation waits for 5s then executes it.

After that we can use the CSS animation-fill-mode property and set its value to forwards like this,

#hideMeAfter5Seconds < animation: hideAnimation 0s ease-in 5s; animation-fill-mode: forwards; > 

Now we have declared the animation property, now we need to set the behavior of the hideAnimation animation itself using the @keyframes css rule.

#hideMeAfter5Seconds < animation: hideAnimation 0s ease-in 5s; animation-fill-mode: forwards; > @keyframes hideAnimation < // animation behavior > 

Inside the hideAnimation , we can use the the to value or block and set the css visibiltiy property to hidden like this,

#hideMeAfter5Seconds < animation: hideAnimation 0s ease-in 5s; animation-fill-mode: forwards; > @keyframes hideAnimation < to < visibility: hidden; > > 

So at the end when the browser loads the above process works like this,

  • CSS gets loaded to the browser
  • The Browser sees the animation property and waits for 5s to execute the hideAnimation animation.
  • Since we have set the running time or the duration of the animation to 0s , the to block is immediately executed after waiting for 5 seconds, and the visibility:hidden CSS property gets applied to the div element which hides the div .

The visibility:hidden only sets the visible state of the div element and doesn't remove the entire div from the visual flow. To remove it we can also set its CSS width and the height property to 0 like this,

#hideMeAfter5Seconds < animation: hideAnimation 0s ease-in 5s; animation-fill-mode: forwards; > @keyframes hideAnimation < to < visibility: hidden; width: 0; height: 0; > > 

That's it we have successfully hidden the element after 5 seconds. 🎉 Yay 😃!

See the above code live in JSBin

One question may arise on why couldn't we use the display CSS property and set its value to none . This is because we cannot animate the display property and thus it will not work inside the to block.

Feel free to share if you found this useful 😃.

Software engineer and web development blogger

Источник

Оцените статью