CSS 过渡不适用于宽度

CSS Transition doesn't work with width

我在创建下拉菜单时发现了一个问题,我已经谷歌了一个小时,现在我想问一下。所以我想在过渡的同时增加宽度和背景,但它只是改变了不透明度只要看看代码片段并将鼠标悬停在子菜单上,你就会看到它只是改变了不透明度。问题是我希望它随着过渡增加宽度。

.nav {
  background-color: #333;
}
.nav ul {
  padding: 0;
  margin: 0;
  list-style: none;
  position: relative;
}
.nav ul li {
  display: inline-block;
  background-color: #333;
}
.nav a {
  display: block;
  padding: 0 10px;
  color: #FFF;
  font-size: 20px;
  line-height: 60px;
  text-decoration: none;
  font-family: Sansa_Light;
  width: 170px;
}
.nav ul li a:hover {
  background-color: #111;
  /*width:170px;*/
}
.nav ul ul li a:hover {
  background-color: #111;
  width: 170px;
  -webkit-transition: all 1s ease-in;
  -o-transition: all 1s ease-in;
  -moz-transition: all 1s ease-in;
  transition: all 1s ease-in;
}
.nav ul ul {
  display: none;
  position: absolute;
  top: 60px;
}
.nav ul li:hover > ul {
  display: inherit;
}
.nav ul ul li {
  width: 170px;
  float: none;
  display: list-item;
  position: relative;
}
.nav ul ul ul li {
  position: relative;
  top: -60px;
  left: 170px;
}
<div class="nav">
  <ul>
    <li><a>Test drop</a>
      <ul>
        <li><a>Dropped</a>
        </li>
      </ul>
    </li>
    <li><a>Non drop</a>
    </li>
  </ul>
</div>

  1. 如果您不仅希望在悬停时平滑过渡(而且在悬停时也如此),您应该为主要选择添加 transition 属性,而不仅仅是 :hover选择器。
  2. 您忘记为 <ul> 添加 transition 属性,现在只在 <a>.
  3. display property is not animatable, you should use opacity + visibility.
  4. transition 的旧供应商前缀(如 -o-moz)现在不再适用,参见 Can I Use

.nav {
    background-color: #333;
}

.nav ul {
    padding: 0;
    margin: 0;
    list-style: none;
    position: relative;
}

.nav ul li {
    display: inline-block;
    background-color: #333;
    width: 170px;
    position: relative;
}

.nav a {
    display: block;
    padding: 0 10px;
    color: #FFF;
    font-size: 20px;
    line-height: 60px;
    text-decoration: none;
    -webkit-transition: all 0.2s ease-in;
    transition: all 0.2s ease-in;
}

.nav ul li a:hover {
    background-color: #111;
}

.nav ul ul {
    opacity: 0;
    visibility: hidden;
    position: absolute;
    width: 0;
    top: 60px;
    -webkit-transition: all 0.2s ease-in;
    transition: all 0.2s ease-in;
}

.nav ul li:hover > ul {
    width: 100%;
    opacity: 1;
    visibility: visible;
}

.nav ul ul li {
    width: 100%;
    display: list-item;
}

.nav ul ul ul li {
    top: -60px;
    left: 170px;
}
<div class="nav">
    <ul>
        <li><a>Test drop</a>
            <ul>
                <li><a>Dropped</a></li>
            </ul>
        </li>
        <li><a>Non drop</a></li>
    </ul>
</div>

display 不是 Animatable CSS 属性,所以你不能使用 transition属性就可以了!

https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties

https://www.w3schools.com/cssref/css_animatable.asp

as @sergey-denisov said, display property is not animatable, you should use opacity + visibility!

现场演示:https://codepen.io/gildata/pen/bopoQZ

<!DOCTYPE html>
<html lang="zh-Hans">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .showPanel {
            /* display: block; */
            visibility: visible;
            /* opacity === 不透明度 1 & 不透明 === opaque */
            opacity: 1;
            height: 100%;
            width: 100%;
            /* transform: translateX(100px); */
            -webkit-transition: all 1.0s ease-in 0.5s;
            transition: all 1.0s ease-in 0.5s;
        }
        
        .hidePanel {
            /* display: none; */
            visibility: hidden;
            /* opacity === 不透明度 0 & 透明 === transparent */
            opacity: 0;
            height: 0;
            width: 0;
            /* transform: translateX(-100px); */
            -webkit-transition: all 1s ease 0.5s;
            -moz-transition: all 1s ease 0.5s;
            transition: all 1s ease 0.5s;
            /* 
            -webkit-transition: property duration timing-function delay;
            -moz-transition: property duration timing-function delay;
            transition: property duration timing-function delay; */
        }
    </style>
</head>

<body>
    <div>
        <!-- js in HTML ??? onclick="test(e);" -->
        <button id="btn">button</button>
        <div class="showPanel" id="panel">
            <div>
                content <br> content <br> content <br> content <br> content <br> content <br> content <br> content <br> content <br> content <br> content <br>
            </div>
            <div>
                content <br> content <br> content <br> content <br> content <br> content <br> content <br> content <br> content <br> content <br> content <br>
            </div>
            <div>
                content <br> content <br> content <br> content <br> content <br> content <br> content <br> content <br> content <br> content <br> content <br>
            </div>
            <div>
                content <br> content <br> content <br> content <br> content <br> content <br> content <br> content <br> content <br> content <br> content <br>
            </div>
        </div>
    </div>
    <div>
        <pre>
                .showPanel {
                    display: block;
                    /* height: 100%; */
                    /* transform: translateX(100px); */
                    -webkit-transition: all 1.0s ease-in 0.5s;
                    transition: all 1.0s ease-in 0.5s;
                }
                
                .hidePanel {
                    display: none;
                    /* height: 0; */
                    /* transform: translateX(-100px); */
                    -webkit-transition: all 1.0s ease-out 0.5s;
                    transition: all 1.0s ease-out 0.5s;
                    /* 
                    -webkit-transition: property duration timing-function delay;
                    -moz-transition: property duration timing-function delay;
                    transition: property duration timing-function delay;
                    */
                }
        </pre>
    </div>
    <script>
        const btn = document.querySelector("#btn");
        const panel = document.querySelector("#panel");
        btn.addEventListener(`click`, (e) => {
            console.log(`e = \n`, e);
            let className = panel.className;
            if (className === "showPanel") {
                panel.className = "hidePanel";
            } else {
                panel.className = "showPanel";
            }
        });
        const test = (e) => {
            console.log(`e = \n`, e);
        };
    </script>
</body>

</html>