Solution 1 :

visibility without transition will be changed immediately. add visibility in transition property with same as transition time.

body {
    margin: 0;
    padding: 0;
}

nav {
    padding: 10px;
    right: 0;
    position: absolute;
    width: auto;
}

nav div {
    width: 0px;
    visibility:hidden;
    overflow:hidden;
    transition: width 0.5s cubic-bezier(0.77, 0.2, 0.05, 1.0), visibility 0.5s;
    background-color: cadetblue;
}

nav input {
    display: block;
    margin-left: auto;
    margin-right: 0;        
}

nav input:checked~div {
    width:200px;
    visibility: visible;
    transition: width 0.5s cubic-bezier(0.77, 0.2, 0.05, 1.0);
}

nav a {
    display: block;
    background-color:cadetblue;
    color:cornsilk;
    margin: 5pt;
    padding: 5pt;
    font-family: Arial, Helvetica, sans-serif;
    text-decoration: none;
}
<!DOCTYPE html>
<html>
<head>
    <title>Menu Test</title>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8">
    <meta name="viewport" content="width=device-width, minimum-scale=1, initial-scale=1, user-scalable=no">
</head>
<body>
  <nav role="navigation">
    <input type="checkbox" aria-label="Toggle menu" />
    <div>
      <a href="https://stackoverflow.com">Stackoverflow</a>
      <a href="https://google.com">Google</a>
      <a href="https://bing.com">Bing</a>
    </div>
  </nav>
</body>
</html>

Problem :

I am making a right-hand-side menu in pure CSS inspired by this menu by Erik Terwan. However, Erik’s menu has some issues – because it renders off-screen when hidden, it confuses tools such as Google’s Search Console, and even though it uses overflow-x: hidden on the body element, it can still be swiped to on mobile (at least iOS).

I decided to try a different approach and, instead, place the menu on-page but hide it by default and animate the width while toggling visibility. It seems to work fairly well (note – I haven’t finished styling the hamburger menu so it’s just a checkbox for now) but I do have an issue.

  • When showing the menu, the animation works as expected (it slides out nicely)
  • When hiding the menu, the transition doesn’t seem to kick in and the menu collapses immediately

How can I make my animation work when collapsing the menu? Is this approach reasonable? In terms of using this with screen readers, is the behavior acceptable?

body {
  margin: 0;
  padding: 0;
}

nav {
  padding: 10px;
  right: 0;
  position: absolute;
  width: auto;
}

nav div {
  width: 60px;
  visibility:collapse;
  transition: width 0.5s cubic-bezier(0.77, 0.2, 0.05, 1.0);
}

nav input {
  display: block;
  margin-left: auto;
  margin-right: 0;        
}

nav input:checked~div {
  width:200px;
  visibility: visible;
  transition: width 0.5s cubic-bezier(0.77, 0.2, 0.05, 1.0);
  background-color: cadetblue;
}

nav a {
  display: block;
  background-color:cadetblue;
  color:cornsilk;
  margin: 5pt;
  padding: 5pt;
  font-family: Arial, Helvetica, sans-serif;
  text-decoration: none;
}
<!DOCTYPE html>
<html>
<head>
    <title>Menu Test</title>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8">
    <meta name="viewport" content="width=device-width, minimum-scale=1, initial-scale=1, user-scalable=no">
</head>
<body>
  <nav role="navigation">
    <input type="checkbox" aria-label="Toggle menu" />
    <div>
      <a href="https://stackoverflow.com">Stackoverflow</a>
      <a href="https://google.com">Google</a>
      <a href="https://bing.com">Bing</a>
    </div>
  </nav>
</body>
</html>

Comments

Comment posted by David Airapetyan

I’ve noticed you made a few other tweaks as well, good call on adding width: 0px; alongside overflow:hidden; – this is better than the arbitrary “width: 60px” I had. Curious about visibility:hidden – in this scenario, does it have an advantage over visibility:collapsed?

Comment posted by developer.mozilla.org/en-US/docs/Web/CSS/visibility

@DavidAirapetyan I think there is no advatage over visibility:collapsed because target is not table or flex. check out

By