CSS 过渡不适用于高度 属性
CSS Transition doesn't work on height property
所以我在点击时进行菜单交互,这是我的代码片段,如果你想看一下。
let btn = document.querySelector('.trigger');
let icons = document.querySelector('.icons');
let labels = document.querySelector('.labels');
btn.onclick = function() {
icons.classList.toggle('active');
labels.classList.toggle('active');
}
body {
background: #222;
}
.trigger {
cursor: pointer;
}
nav {
position: absolute;
top: 30px;
right: 30px;
color: #222;
}
nav ul.icons {
background: #fff;
width: 60px;
height: 60px;
overflow: hidden;
border-radius: 60px;
transition: 1s ease;
}
nav ul.icons:hover {
height: 100%;
}
nav ul li {
list-style: none;
}
<html lang="en">
<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
</head>
<body>
<nav>
<ul class="icons">
<li class="trigger">
<i class="fas fa-bars"></i>
</li>
<li><i class="fas fa-home"></i></li>
<li><i class="fas fa-users"></i></li>
<li><i class="fas fa-concierge-bell"></i></li>
<li><i class="fas fa-pen"></i></li>
<li><i class="fas fa-phone-alt"></i></li>
</ul>
</nav>
</body>
</html>
我遇到的问题是过渡 属性 不能很好地处理 CSS 中的高度。是否有我没有注意到的问题,是否有快速解决方法?
“高度”属性的CSS过渡仅在指定两个值(开始和结束)时才有效。
您可以使用“最大高度”而不是“高度”来解决这个问题。这样您就可以安全地超过元素在过渡结束时应具有的确切高度。
let btn = document.querySelector('.trigger');
let icons = document.querySelector('.icons');
let labels = document.querySelector('.labels');
btn.onclick = function() {
icons.classList.toggle('active');
labels.classList.toggle('active');
}
body {
background: #222;
}
.trigger {
cursor: pointer;
}
nav {
position: absolute;
top: 30px;
right: 30px;
color: #222;
}
nav ul.icons {
background: #fff;
width: 60px;
max-height: 60px;
overflow: hidden;
border-radius: 60px;
transition: max-height 1s ease;
}
nav ul.icons:hover {
max-height: 120px;
}
nav ul li {
list-style: none;
}
<html lang="en">
<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
</head>
<body>
<nav>
<ul class="icons">
<li class="trigger">
<i class="fas fa-bars"></i>
</li>
<li><i class="fas fa-home"></i></li>
<li><i class="fas fa-users"></i></li>
<li><i class="fas fa-concierge-bell"></i></li>
<li><i class="fas fa-pen"></i></li>
<li><i class="fas fa-phone-alt"></i></li>
</ul>
</nav>
</body>
</html>
如果您设置的最终值与所需值相比过高,那么唯一的副作用可能是 return 过渡延迟过多。
只是您最初想要创建的内容的一个非常基本的片段。
[注意]:过渡 quite/bit 胡思乱想(不流畅)。但就是这样。
document.querySelector('.menu').addEventListener('click', (e) => {
document.querySelector('ul.icons').classList.toggle('active');
});
* {
margin: 0;
padding: 0;
outline: 0;
box-sizing: border-box;
}
.navbar {
position: relative;
width: 100%;
height: 100px;
display: flex;
padding: 0 4rem;
align-items: center;
justify-content: flex-end;
background-color: #f7f8f9;
border-bottom: 1px solid #c1c1c1;
}
.navbar .menu i {
cursor: pointer;
font-size: 2rem;
}
.navbar .icons {
opacity: 0;
list-style: none;
position: absolute;
top: calc(100% + 2px);
right: 3rem;
display: flex;
flex-direction: column;
transition: opacity 250ms ease;
}
.navbar .icons .icon {
display: grid;
padding: 1rem;
flex-shrink: 0;
min-width: 30px;
min-height: 30px;
border-radius: 50%;
place-items: center;
background-color: #f7f8f9;
border: 1px solid #c1c1c1;
transition: margin-top 250ms ease;
}
.navbar .icons .icon:not(:first-of-type) {
margin-top: 1rem;
}
.navbar .icons .icon:nth-child(2) {
margin-top: -62px;
}
.navbar .icons .icon:nth-child(3) {
margin-top: -62px;
}
.navbar .icons .icon:nth-child(4) {
margin-top: -62px;
}
.navbar .icons .icon:nth-child(5) {
margin-top: -62px;
}
.navbar .icons.active {
opacity: 1;
}
.navbar .icons.active .icon {
margin-top: 1rem;
}
.navbar .icons.active .icon:nth-child(1) {
margin-top: 0;
transition-delay: 250ms;
}
.navbar .icons.active .icon:nth-child(2) {
transition-delay: 250ms;
}
.navbar .icons.active .icon:nth-child(2) {
transition-delay: 500ms;
}
.navbar .icons.active .icon:nth-child(3) {
transition-delay: 750ms;
}
.navbar .icons.active .icon:nth-child(4) {
transition-delay: 1s;
}
.navbar .icons.active .icon:nth-child(5) {
transition-delay: 1.25s;
}
.bx {
font-size: 1.75rem;
}
<link href='https://unpkg.com/boxicons@2.0.9/css/boxicons.min.css' rel='stylesheet'>
<nav class="navbar">
<div class="menu" role="button">
<i class='bx bx-menu'></i>
</div>
<ul class="icons">
<li class="icon">
<i class='bx bx-home-alt'></i>
</li>
<li class="icon">
<i class='bx bx-user'></i>
</li>
<li class="icon">
<i class='bx bx-bell'></i>
</li>
<li class="icon">
<i class='bx bx-pen'></i>
</li>
<li class="icon">
<i class='bx bx-phone'></i>
</li>
</ul>
</nav>
如果有人能让这个过渡更顺利一些编辑这个答案。
所以问题是您尝试将高度转换为 100% - 但 CSS 无法立即处理。
快速但有问题的解决方案:
您可以将 :hover 中的高度设置为固定数量,例如100px.
但是如果你想在其中添加新项目或更改项目的大小,则必须手动调整高度。
我会做什么:
首先,我会稍微重组 HTML 并将触发器移出项目列表:
<nav>
<button class="trigger">
<i class="fas fa-bars"></i>
</button>
<ul class="icons fas-container">
<li><i class="fas fa-home"></i></li>
<li><i class="fas fa-users"></i></li>
<li><i class="fas fa-concierge-bell"></i></li>
<li><i class="fas fa-pen"></i></li>
<li><i class="fas fa-phone-alt"></i></li>
</ul>
</nav>
然后我会调整.icons的CSS:
(删除高度,添加最大高度并调整过渡)
nav ul.icons {
background: #fff;
width: 60px;
overflow: hidden;
border-radius: 60px;
max-height: 0;
transition: max-height 0.2s ease-out;
}
最后我会让 JavaScript 负责正确设置最大高度。
悬停时:
let btn = document.querySelector('.trigger');
let icons = document.querySelector('.icons');
btn.onmouseover = function () {
icons.style.maxHeight = icons.scrollHeight + "px";
}
btn.onmouseout = function () {
icons.style.maxHeight = null;
}
或点击(如果您愿意):
let btn = document.querySelector('.trigger');
let icons = document.querySelector('.icons');
btn.onclick = function() {
if (icons.style.maxHeight){
icons.style.maxHeight = null;
} else {
icons.style.maxHeight = icons.scrollHeight + "px";
}
}
这里有一些(可能)有用的链接:
- https://www.w3schools.com/howto/howto_js_collapsible.asp
- How can I transition height: 0; to height: auto; using CSS?
- https://codepen.io/felipefialho/pen/ICkwe
片段:
let btn = document.querySelector('.trigger');
let icons = document.querySelector('.icons');
btn.onmouseover = function () {
icons.style.maxHeight = icons.scrollHeight + "px";
}
btn.onmouseout = function () {
icons.style.maxHeight = null;
}
body {
background: #222;
}
.trigger {
cursor: pointer;
}
nav {
position: absolute;
top: 30px;
right: 30px;
color: #222;
}
nav ul.icons {
background: #fff;
width: 60px;
overflow: hidden;
border-radius: 60px;
max-height: 0;
transition: max-height 0.2s ease-out;
}
nav ul.icons:hover {
height: 100%;
}
nav ul li {
list-style: none;
}
<html lang="en">
<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
</head>
<body>
<nav>
<button class="trigger">
<i class="fas fa-bars"></i>
</button>
<ul class="icons fas-container">
<li><i class="fas fa-home"></i></li>
<li><i class="fas fa-users"></i></li>
<li><i class="fas fa-concierge-bell"></i></li>
<li><i class="fas fa-pen"></i></li>
<li><i class="fas fa-phone-alt"></i></li>
</ul>
</nav>
</body>
</html>
所以我在点击时进行菜单交互,这是我的代码片段,如果你想看一下。
let btn = document.querySelector('.trigger');
let icons = document.querySelector('.icons');
let labels = document.querySelector('.labels');
btn.onclick = function() {
icons.classList.toggle('active');
labels.classList.toggle('active');
}
body {
background: #222;
}
.trigger {
cursor: pointer;
}
nav {
position: absolute;
top: 30px;
right: 30px;
color: #222;
}
nav ul.icons {
background: #fff;
width: 60px;
height: 60px;
overflow: hidden;
border-radius: 60px;
transition: 1s ease;
}
nav ul.icons:hover {
height: 100%;
}
nav ul li {
list-style: none;
}
<html lang="en">
<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
</head>
<body>
<nav>
<ul class="icons">
<li class="trigger">
<i class="fas fa-bars"></i>
</li>
<li><i class="fas fa-home"></i></li>
<li><i class="fas fa-users"></i></li>
<li><i class="fas fa-concierge-bell"></i></li>
<li><i class="fas fa-pen"></i></li>
<li><i class="fas fa-phone-alt"></i></li>
</ul>
</nav>
</body>
</html>
我遇到的问题是过渡 属性 不能很好地处理 CSS 中的高度。是否有我没有注意到的问题,是否有快速解决方法?
“高度”属性的CSS过渡仅在指定两个值(开始和结束)时才有效。
您可以使用“最大高度”而不是“高度”来解决这个问题。这样您就可以安全地超过元素在过渡结束时应具有的确切高度。
let btn = document.querySelector('.trigger');
let icons = document.querySelector('.icons');
let labels = document.querySelector('.labels');
btn.onclick = function() {
icons.classList.toggle('active');
labels.classList.toggle('active');
}
body {
background: #222;
}
.trigger {
cursor: pointer;
}
nav {
position: absolute;
top: 30px;
right: 30px;
color: #222;
}
nav ul.icons {
background: #fff;
width: 60px;
max-height: 60px;
overflow: hidden;
border-radius: 60px;
transition: max-height 1s ease;
}
nav ul.icons:hover {
max-height: 120px;
}
nav ul li {
list-style: none;
}
<html lang="en">
<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
</head>
<body>
<nav>
<ul class="icons">
<li class="trigger">
<i class="fas fa-bars"></i>
</li>
<li><i class="fas fa-home"></i></li>
<li><i class="fas fa-users"></i></li>
<li><i class="fas fa-concierge-bell"></i></li>
<li><i class="fas fa-pen"></i></li>
<li><i class="fas fa-phone-alt"></i></li>
</ul>
</nav>
</body>
</html>
如果您设置的最终值与所需值相比过高,那么唯一的副作用可能是 return 过渡延迟过多。
只是您最初想要创建的内容的一个非常基本的片段。
[注意]:过渡 quite/bit 胡思乱想(不流畅)。但就是这样。
document.querySelector('.menu').addEventListener('click', (e) => {
document.querySelector('ul.icons').classList.toggle('active');
});
* {
margin: 0;
padding: 0;
outline: 0;
box-sizing: border-box;
}
.navbar {
position: relative;
width: 100%;
height: 100px;
display: flex;
padding: 0 4rem;
align-items: center;
justify-content: flex-end;
background-color: #f7f8f9;
border-bottom: 1px solid #c1c1c1;
}
.navbar .menu i {
cursor: pointer;
font-size: 2rem;
}
.navbar .icons {
opacity: 0;
list-style: none;
position: absolute;
top: calc(100% + 2px);
right: 3rem;
display: flex;
flex-direction: column;
transition: opacity 250ms ease;
}
.navbar .icons .icon {
display: grid;
padding: 1rem;
flex-shrink: 0;
min-width: 30px;
min-height: 30px;
border-radius: 50%;
place-items: center;
background-color: #f7f8f9;
border: 1px solid #c1c1c1;
transition: margin-top 250ms ease;
}
.navbar .icons .icon:not(:first-of-type) {
margin-top: 1rem;
}
.navbar .icons .icon:nth-child(2) {
margin-top: -62px;
}
.navbar .icons .icon:nth-child(3) {
margin-top: -62px;
}
.navbar .icons .icon:nth-child(4) {
margin-top: -62px;
}
.navbar .icons .icon:nth-child(5) {
margin-top: -62px;
}
.navbar .icons.active {
opacity: 1;
}
.navbar .icons.active .icon {
margin-top: 1rem;
}
.navbar .icons.active .icon:nth-child(1) {
margin-top: 0;
transition-delay: 250ms;
}
.navbar .icons.active .icon:nth-child(2) {
transition-delay: 250ms;
}
.navbar .icons.active .icon:nth-child(2) {
transition-delay: 500ms;
}
.navbar .icons.active .icon:nth-child(3) {
transition-delay: 750ms;
}
.navbar .icons.active .icon:nth-child(4) {
transition-delay: 1s;
}
.navbar .icons.active .icon:nth-child(5) {
transition-delay: 1.25s;
}
.bx {
font-size: 1.75rem;
}
<link href='https://unpkg.com/boxicons@2.0.9/css/boxicons.min.css' rel='stylesheet'>
<nav class="navbar">
<div class="menu" role="button">
<i class='bx bx-menu'></i>
</div>
<ul class="icons">
<li class="icon">
<i class='bx bx-home-alt'></i>
</li>
<li class="icon">
<i class='bx bx-user'></i>
</li>
<li class="icon">
<i class='bx bx-bell'></i>
</li>
<li class="icon">
<i class='bx bx-pen'></i>
</li>
<li class="icon">
<i class='bx bx-phone'></i>
</li>
</ul>
</nav>
如果有人能让这个过渡更顺利一些编辑这个答案。
所以问题是您尝试将高度转换为 100% - 但 CSS 无法立即处理。
快速但有问题的解决方案:
您可以将 :hover 中的高度设置为固定数量,例如100px.
但是如果你想在其中添加新项目或更改项目的大小,则必须手动调整高度。
我会做什么:
首先,我会稍微重组 HTML 并将触发器移出项目列表:
<nav>
<button class="trigger">
<i class="fas fa-bars"></i>
</button>
<ul class="icons fas-container">
<li><i class="fas fa-home"></i></li>
<li><i class="fas fa-users"></i></li>
<li><i class="fas fa-concierge-bell"></i></li>
<li><i class="fas fa-pen"></i></li>
<li><i class="fas fa-phone-alt"></i></li>
</ul>
</nav>
然后我会调整.icons的CSS:
(删除高度,添加最大高度并调整过渡)
nav ul.icons {
background: #fff;
width: 60px;
overflow: hidden;
border-radius: 60px;
max-height: 0;
transition: max-height 0.2s ease-out;
}
最后我会让 JavaScript 负责正确设置最大高度。
悬停时:
let btn = document.querySelector('.trigger');
let icons = document.querySelector('.icons');
btn.onmouseover = function () {
icons.style.maxHeight = icons.scrollHeight + "px";
}
btn.onmouseout = function () {
icons.style.maxHeight = null;
}
或点击(如果您愿意):
let btn = document.querySelector('.trigger');
let icons = document.querySelector('.icons');
btn.onclick = function() {
if (icons.style.maxHeight){
icons.style.maxHeight = null;
} else {
icons.style.maxHeight = icons.scrollHeight + "px";
}
}
这里有一些(可能)有用的链接:
- https://www.w3schools.com/howto/howto_js_collapsible.asp
- How can I transition height: 0; to height: auto; using CSS?
- https://codepen.io/felipefialho/pen/ICkwe
片段:
let btn = document.querySelector('.trigger');
let icons = document.querySelector('.icons');
btn.onmouseover = function () {
icons.style.maxHeight = icons.scrollHeight + "px";
}
btn.onmouseout = function () {
icons.style.maxHeight = null;
}
body {
background: #222;
}
.trigger {
cursor: pointer;
}
nav {
position: absolute;
top: 30px;
right: 30px;
color: #222;
}
nav ul.icons {
background: #fff;
width: 60px;
overflow: hidden;
border-radius: 60px;
max-height: 0;
transition: max-height 0.2s ease-out;
}
nav ul.icons:hover {
height: 100%;
}
nav ul li {
list-style: none;
}
<html lang="en">
<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
</head>
<body>
<nav>
<button class="trigger">
<i class="fas fa-bars"></i>
</button>
<ul class="icons fas-container">
<li><i class="fas fa-home"></i></li>
<li><i class="fas fa-users"></i></li>
<li><i class="fas fa-concierge-bell"></i></li>
<li><i class="fas fa-pen"></i></li>
<li><i class="fas fa-phone-alt"></i></li>
</ul>
</nav>
</body>
</html>