【CSS练习】菜单图标

该文介绍了如何使用Less预编译语言进行CSS样式编写,特别是其循环功能和变量使用,配合JavaScript实现DOM操作,创建了一个响应式菜单图标。图标在点击后有动画效果,通过调整线条的位置和透明度实现视觉变换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

学习内容:

Day2
链接地址
【description】Menu Icon: Used on almost every website by now, simple but impressively animated it becomes a real eye-catcher
【知识点】animation、transition、JS中的DOM操作、less预编译转义|循环

知识补充

Less 函数

选择器名、url中使用变量使用@{value}的形式,样式书写使用@value的形式

  1. 循环
    each: 含有两个参数listreles,将rules的规则绑定到list中的每一个成员;
@selectors: blue, green, red;

each(@selectors, {
  .sel-@{value} {
    a: b;
  }
});

outputs:

.sel-blue {
  a: b;
}
.sel-green {
  a: b;
}
.sel-red {
  a: b;
}

配合range()函数,可以实现for循环的模式

each(range(4), {
  .col-@{value} {
    height: (@value * 50px);
  }
});
  1. 转义
    允许使用字符串作为属性或变量。任何~"anying"形式的内容按原样输出。某些时候,当需要引入无效的 CSS 语法或 Less 不能识别的字符,就需要使用转义字符

代码实现

html

<div class="frame">
    <div class="center">
      <div class="menu-icon">
        <div class="line-1 no-animation"></div>
        <div class="line-2 no-animation"></div>
        <div class="line-3 no-animation"></div>
      </div>
    </div>
  </div>

css

// delete the following line if no text is used
// edit the line if you wanna use other fonts
@import url(https://fonts.googleapis.com/css?family=Open+Sans:700,300);

@menu-icon-line-space: 14px;
@menu-icon-line-height: 8px;
@content-width: 70px;
@content-height: 3 * @menu-icon-line-height + 2 * @menu-icon-line-space;
@cubic-bezier-in: cubic-bezier(0.30,1,0.70,1);
@cubic-bezier-out: cubic-bezier(1,0.70,1,0.30);
// use only the available space inside the 400x400 frame

* {
  box-sizing: border-box;
}

.frame {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 400px;
  height: 400px;
  margin-top: -200px;
  margin-left: -200px;
  border-radius: 2px;
	box-shadow: 4px 8px 16px 0 rgba(0,0,0,0.1);
	overflow: hidden;
  background: #3faf82;
  color: #333;
	font-family: 'Open Sans', Helvetica, sans-serif;
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
}

.center {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%,-50%);
}

.menu-icon {
  position: relative;
  width: @content-width;
  height: @content-height;

  each(range(3), {  // each 遍历
    .line-@{value} {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      width: 100%;
      height: @menu-icon-line-height;
      background-color: #fff;
      border-radius: 10px;
      transition: background-color .5s ease-in-out;
    }
  })
  .line-1 {
    top: 0;
  }
  .line-3 {
    top: 100%;
  }
  &:hover {
    cursor: pointer;
  }
}
.active {
  each(range(3), {
    .line-@{value} {
      animation: ~'animate-line-@{value}' .7s @cubic-bezier-in forwards;
    }
  })
}
.no-animate {
  each(range(3), {
    .line-@{value} {
      animation: ~'animate-line-@{value}-rev' .7s @cubic-bezier-out forwards;
    }
  })
}

@keyframes animate-line-1-rev {
	0% {
		top: 50%;
    transform: translate3d(-50%, -50%, 0) rotate(135deg);
	}
	50% {
		top: 50%;
    transform: translate3d(-50%, -50%, 0);
	}

	100% {
		top: 0;
	}
}
@keyframes animate-line-2-rev {
	0% {
		transform: translate3d(-50%, -50%, 0) scale(0);
    opacity: 0;
	}
	100% {
		transform: translate3d(-50%, -50%, 0) scale(1);
		opacity: 1;
	}
}
@keyframes animate-line-3-rev {
	0% {
		top: 50%;
    transform: translate3d(-50%, -50%, 0) rotate(45deg);
	}
	50% {
		top: 50%;
    transform: translate3d(-50%, -50%, 0);
	}

	100% {
		top: 100%;
	}
}

@keyframes animate-line-1 {
  0% {
    top: 0;
  }
  50% {
    top: 50%;
    transform: translate3d(-50%, -50%, 0);
  }
  100% {
    top: 50%;
    transform: translate3d(-50%, -50%, 0) rotate(135deg);
  }
}
@keyframes animate-line-2 {
  0% {
    transform: translate3d(-50%, -50%, 0) scale(1);
    opacity: 1;
  }
  100% {
    transform: translate3d(-50%, -50%, 0) scale(0);
      opacity: 0;
  }
}
  @keyframes animate-line-3 {
  0% {
    top: 100%;
  }
  50% {
    top: 50%;
    transform: translate3d(-50%, -50%, 0);
  }
  100% {
    top: 50%;
    transform: translate3d(-50%, -50%, 0) rotate(45deg);
  }
}

js

window.addEventListener('load', function () {
  function judge(item) {
    return !item.contains('active') ? "active" : 'no-animate'
  }
  let menuIcon = this.document.querySelector('.menu-icon')
  menuIcon.addEventListener('click', function () {
    console.log(judge(this.classList));
    this.classList.toggle(judge(this.classList))
    console.log(this.classList);
  })
})

效果图
在这里插入图片描述
点击后,具有动画效果变化如下:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值