title: Blazor Animation - set div to display: none after animation ends
body: <p>Recently I have implemented some animations but I am having some problems when the animation ends. I have a div structure for responsiveness, that shows a menu button when the screen size is smaller than X. </p>
  
  <p>When someone clicks on the menu button a left side bar, which is default set to <code>display:none</code>, is being shown by removing the <code>display: none</code> property immediately and then adding an animation class, this all works fine. 
  However, when the sidebar is collapsed again (by clicking on a close button), a new animation (for removing the menu) is being added, when this animation ends I need to set the display back to <code>display:none</code> (I don't want the sidebar take up any space). </p>
  
  <p>In the current situation I accomplished this by setting some boolean variables that add <code>display:none</code> on false and removes it on true. My animation takes up to 300MS so I added a <code>Task.Delay</code> of 300MS to set the boolean. Sadly this doesn't create a perfect 'flow', you can see the screen hiccup because the setting of the <code>display:none</code> happens just a few MS to late. Of course I can decrease the <code>Task.Delay</code> to 290MS~ but this isn't a great solution. </p>
  
  <p>Any ideas how I can accomplish this using Blazor? </p>
  
  <p>Below the code:</p>
  
  <p><strong>HTML:</strong></p>
  
  <pre><code>&lt;!-- The mobile side bar, display: none default on screen sizes &gt; X  --&gt; 
  &lt;div class="md:hidden" style=@mobileSideBarDisplay&gt;
      &lt;div class="fixed inset-0 flex z-40"&gt;
  
          &lt;! this sets the opacity of tyhe space to the right (grayed out) --&gt; 
          &lt;div class="fixed inset-0 @sidebarOverlayAnimation"&gt;
              &lt;div class="absolute inset-0 bg-gray-600 opacity-75"&gt;&lt;/div&gt;
          &lt;/div&gt;
  
          &lt;!-- the actual side bar with it's buttons --&gt;
          &lt;div class="relative flex-1 flex flex-col max-w-xs w-full pt-5 pb-4 bg-gray-800  @sidebarMenuAnimation"&gt;
              &lt;!-- Close button with which the sidebar menu can be closed --&gt;
              &lt;button class=".." aria-label="Close sidebar" @onclick="ToggleSidebar"&gt;&lt;/button&gt;
  
              ... Left out for readability
          &lt;/div&gt;
      &lt;/div&gt;
  &lt;/div&gt;
  
  
  &lt;!-- Static sidebar for desktop --&gt;
  &lt;div class="hidden md:flex md:flex-shrink-0"&gt;
      .. Left out for readability
  &lt;/div&gt;
  
  &lt;!-- menu button div which becomes visible at screensize &lt; X
  &lt;div class="flex flex-col w-0 flex-1 overflow-hidden"&gt;
  
      &lt;!-- Menu button with which the sidebar menu can be opened --&gt;
      &lt;button class=".. md:hidden" aria-label="Open sidebar" @onclick="ToggleSidebar"&gt;
      .. Left out for readability
  &lt;/div&gt;
  </code></pre>
  
  <p><strong>C# backend code:</strong></p>
  
  <pre><code>@code {
  
      // used to set display: none; (or empty)
      private bool showMobileSideBar = false;
  
      // Used to show / toggle animations
      private bool showMobileSideBarAnimation = false; 
  
  
      // toggle animation and display classes
      private string mobileSideBarDisplay =&gt; showMobileSideBar ? "" : "display: none;"; 
      private string sidebarOverlayAnimation =&gt; showMobileSideBarAnimation ? "sidebar-overlay-animation-entering" : "sidebar-overlay-animation-leaving";
      private string sidebarMenuAnimation =&gt; showMobileSideBarAnimation ? "sidebar-menu-animation-entering" : "sidebar-menu-animation-leaving";
  
      // Function to display entering or leaving animation depending on the boolean value)
      private async Task ToggleSidebar()
      {
          showMobileSideBarAnimation = !showMobileSideBarAnimation;
          if (showMobileSideBar == true) // only delay when we need to set div to display: none;
          {
              await Task.Delay(300); // this works kinda clunky now
          }
          showMobileSideBar = !showMobileSideBar;
  
      }
  
  }
  </code></pre>
  
  <p><strong>The CSS / animations:</strong></p>
  
  <pre><code>/*
      Animations for setting the right-space opacity (when the sidebar is shown / hidden)
  */
  
  .sidebar-overlay-animation-entering {
      animation-name: sidebar-overlay-entering;
      animation-duration: 300ms;
      animation-timing-function: linear;
  }
  
  @keyframes sidebar-overlay-entering {
      from { opacity: 0; }
      to { opacity: 1; } 
  }
  
  .sidebar-overlay-animation-leaving {
      animation-name: sidebar-overlay-leaving;
      animation-duration: 300ms;
      animation-timing-function: linear;
  }
  
  @keyframes sidebar-overlay-leaving {
      from { opacity: 1; }
      to { opacity: 0; }
  }
  
  
  
  
  /*
      Animations for displaying the sidebar (in- and out)
  */
  
  
  .sidebar-menu-animation-entering {
      animation-name: sidebar-menu-entering;
      animation-duration: 300ms;
      animation-timing-function: ease-in-out;
  }
  
  @keyframes sidebar-menu-entering {
      from { transform: translateX(-100%); }
      to { transform: translateX(0); }
  }
  
  .sidebar-menu-animation-leaving {
      animation-name: sidebar-menu-leaving;
      animation-duration: 300ms;
      animation-timing-function: ease-in-out;
  }
  
  @keyframes sidebar-menu-leaving {
      from { transform: translateX(0); }
      to { transform: translateX(-100%); }
  }
  </code></pre>
  
  <p>P.S. I tried using <a href="https://github.com/dazinator/BlazorDeferredRemove" rel="nofollow noreferrer">https://github.com/dazinator/BlazorDeferredRemove</a> but I cant get it this to work. There is also not an example using animations (only transition with visibility) or using <code>display: none;</code> (But perhaps the library can work if someone could give a few pointers)</p>