{
  "$type": "site.standard.document",
  "content": {
    "$type": "at.markpub.markdown",
    "text": {
      "$type": "at.markpub.text",
      "markdown": "One of the most annoying things on the web is when a dropdown opens on hover and you move the most diagonally into the dropdown, but in doing so the dropdown disappears because I stopped hovering over the zone that triggers the dropdown to appear. There's a couple ways to go about this including this [awesome SVG-based solution from Hakim El Hattab](https://team.slides.com/hakimel/cssday-2019#/).\n\nMy go to method, however, is to use a little bit of animation.\n\n- [View Demo App](https://arkmuntasser.github.io/better-dropdown/)\n- [Download Source Code on GitHub](https://github.com/arkmuntasser/better-dropdown)\n\nWhat I particularly like about this method is that it doesn't require any JavaScript to implement. All you need is the right markup and a bit of CSS.\n\n## Prerequisites\n\n- Working knowledge of [HTML and CSS](https://internetingishard.com/html-and-css/)\n- Basic knowledge of [CSS transitions](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Transitions/Using_CSS_transitions)\n\n## The Big Idea\n\nConceptually, we're not doing anything too dissimilar than what Hakim is doing with his solution. What we're after is an extended hoverable area going from our trigger point to our menu. To do this, we create have an invisible dropdown helper element that is the width of the dropdown and the height of the trigger area and we place it over trigger area.\n\nIn the demo app, if you hover over the the word \"dropdown\" you'll see a red rectangle appear: this is our dropdown helper. As you move off the word \"dropdown\" you'll notice the red area starts shrinking downward toward the menu.\n\nWhat this results in is a time limit in which you can move diagonally from the trigger point to the dropdown. As you move horizontally, the valid hoverable area shrinks vertically, this gives us our triangular area to move in. And because the easing isn't linear, we actually get a nice curve like in Hakim's solution that is a lot more natural to work in.\n\nSo that's the idea, but what does the code actually look like?\n\n## The Code\n\nHere is what the markup looks like for this dropdown.\n\n```html\n<div class=\"nav-section\">\n  <div class=\"nav-section-title\">Dropdown</div>\n  <div class=\"dropdown-helper\"></div>\n  <div class=\"nav-section-dropdown\">\n    <a href=\"#\" title=\"link\">Link</a>\n    <a href=\"#\" title=\"link\">Link</a>\n    <a href=\"#\" title=\"link\">Link</a>\n    <a href=\"#\" title=\"link\">Link</a>\n    <a href=\"#\" title=\"link\">Link</a>\n    <a href=\"#\" title=\"link\">Link</a>\n    <a href=\"#\" title=\"link\">Link</a>\n    <a href=\"#\" title=\"link\">Link</a>\n    <a href=\"#\" title=\"link\">Link</a>\n  </div>\n</div>\n```\n\nAnd here's the CSS that handles the making the dropdown visible on hover.\n\n```css\n.header .nav-section-dropdown {\n  display: none;\n}\n.header .nav-section:hover .nav-section-dropdown {\n  display: grid;\n}\n```\n\nBy default, the dropdown is not shown and when we hover over anything in the `.nav-section` we show the dropdown. That's the setup, let's take a look at the animation.\n\nFirst, we define the initial state of the dropdown helper and how it's animation is going to work.\n\n```css\n.header .dropdown-helper {\n  transform: scaleY(0);\n  transform-origin: bottom center;\n  transition: transform 300ms ease 200ms;\n}\n```\n\nBy default, we want to this to essentially not exist but we want it readily animatable. To do this, we set the Y scale to 0.\n\nWe also want this to animate downward so we need to set the transform origin accordingly.\n\nAnd last, we set the transition we want. I find having a slight delay of about 200ms gives a much better feel to the whole effect, but you might find you need or want to adjust these numbers for your needs and taste.\n\nNext, we need to make the helper full scale on hover.\n\n```css\n.header .nav-section-title:hover + .dropdown-helper {\n  transform: scaleY(1);\n  transition: none;\n}\n```\n\nThere are 2 things to note here:\n\n1. The hover is **not** on the `.nav-section` itself, but instead on the `.nav-section-title`. We're also using the immediate sibling selector to target the helper. This is because the dropdown is closed, the title is essentially the entire valid trigger area and it's also what the user will be hovering off of to get into the dropdown.\n\n2. The transition is set to `none` when the title is hovered. We don't want the helper to animate in, because if the user is moving quickly, they may trigger the animate out animation before the helper has fully animated in which would likely break the effect. So we remove the transition and have the helper instantly blink to full size.\n\nNow when we move away from the title, the animation will begin and the user can move diagonally into the dropdown.\n\nFinally, there's one last thing to take care of.\n\n```css\n.header .nav-section-title {\n  position: relative;\n  z-index: 2;\n}\n```\n\nWe want to make sure that the title sits above the helper so we don't accidentally cause the helper to animate out early.\n\nAltogether, we get this:\n\n```css\n.header .dropdown-helper {\n  transform: scaleY(0);\n  transform-origin: bottom center;\n  transition: transform 300ms ease 200ms;\n}\n.header .nav-section-title:hover + .dropdown-helper {\n  transform: scaleY(1);\n  transition: none;\n}\n.header .nav-section-title {\n  position: relative;\n  z-index: 2;\n}\n```\n\n## Conclusion\nIt's a little extra CSS, but the effect goes a long way toward providing a better user experience. And I'm personally happy when I can get a win like this without needing to add more JavaScript to a site.\n\nThat said, do also check out Hakim's method. There are many ways to tackle a problem and just as many contexts in which a particular solution is best. The only truly wrong way to go about it, is to not try to provide an optimal experience for your users."
    }
  },
  "description": "Trying to move diagonally to a hover-triggered menu and having it disappear on you. Flames. On the sides of my face.",
  "path": "/posts/how-to-improve-dropdown-navigation-with-animation",
  "publishedAt": "2017-12-27T00:00:00.000Z",
  "site": "at://did:plc:2lm4lab5fhnj6kaazrxopv37/site.standard.publication/self",
  "tags": [
    "animation",
    "css",
    "html"
  ],
  "title": "How to Improve Dropdown Navigation with Animation"
}