作为程序员天天敲打着键盘,我就想能否通过css实现呢,今天我们就用css来实现一下虚拟键盘,为了不让他看起来那么单调,我们在给它添加一个变化主题色的功能
效果图
未变色前
变色后
实现思路
我们来分析下布局,这一个键盘是大盒子,然后大盒子里面有三个盒子,这三个盒子分别代表三行,每一行Y轴不对齐
页面结构
三行盒子我们通过无序列表进行实现,键盘上有一个Fn键,他是用于控制键盘主题色变化的,我们把他单独拿出来
<!-- 大盒子 --> <div id="app"> <div id="btn">Fn</div> <ul> <!-- 键盘列 --> <li> <div>q</div> <div>w</div> <div>e</div> <div>r</div> <div>t</div> <div>y</div> <div>u</div> <div>i</div> <div>o</div> <div>p</div> </li> <li> <div>a</div> <div>s</div> <div>d</div> <div>f</div> <div>g</div> <div>h</div> <div>j</div> <div>k</div> <div>l</div> </li> <li> <div>z</div> <div>x</div> <div>c</div> <div>v</div> <div>b</div> <div>n</div> <div>m</div> </li> </ul> </div>
样式实现
我们先清除所有元素的基本样式,给在外面的大盒子设置好样式,高度我们让里面的内容把他撑起来
* { box-sizing: border-box; list-style: none; } /* 大盒子 */ #app { position: relative; width: 680px; margin: 13vh auto; display: flex; justify-content: center; border: 1px solid #ccc; border-radius: 10px; }
在设置键盘的每一行的位置,我们这里使用外边距属性让无序列表的子元素距离左边都有距离,这样第一列初始就不对齐,后面每一列自然不对齐
ul { padding: 0; } /* 键盘每一列 */ ul li { display: flex; overflow: hidden; } ul li:nth-child(2) { margin-left: 24px; } ul li:nth-child(3) { margin-left: 52px; }
实现键帽的样式,我们这里给键帽里面的文字设置一个发光样式,由于初始是白光,所以看不到,只有当变换主题色的时候才可以看到
/* 键帽 */ ul li div { display: flex; justify-content: center; align-items: center; width: 50px; height: 50px; text-transform: capitalize; margin: 8px; box-shadow: 0px 0px 3px 0px #ccc; border-radius: 10px; cursor: pointer; user-select: none; transition: background 0.05s; text-shadow: 0 0 10px #fff, 0 0 20px #fff, 0 0 30px #fff, 0 0 40px #00a67c, 0 0 70px #00a67c, 0 0 80px #00a67c, 0 0 100px #00a67c, 0 0 150px #00a67c; } /* 键帽滑过 */ ul li div:hover { background: #eee; }
最后将Fn键样式写一下,在通过定位的方式定位到合适的位置即可
/* 按钮 */ #btn { position: absolute; bottom: 4px; right: 20px; margin: 20px auto; display: flex; justify-content: center; align-items: center; width: 130px; height: 50px; user-select: none; cursor: pointer; border-radius: 10px; background: #eee; }
主题色变换逻辑实现
// 获取Fn键 const btn = document.getElementById('btn'); // 获取所有的键帽 const keyupAll = document.querySelectorAll('ul li div'); // 给Fn键绑定点击事件 btn.onclick = function () { // 随机获取3个0~255之间的数用于更换背景色 const R = Math.round(Math.random() * 255); const G = Math.round(Math.random() * 255); const B = Math.round(Math.random() * 255); // 把随机数添加到css的rgba属性中 let rgba = `rgb(${R},${G},${B},${0.5})` // 按键也需要用到背景色,更换主题按钮的背景色和普通的键帽需要有区别所以给出区别 this.style.backgroundColor = `rgb(${R},${G},${R},${0.5})` // 循环每个键帽并赋值背景色 for (let i = 0; i < keyupAll.length; i++) { keyupAll[i].style.backgroundColor = rgba } } // 给键帽添加点击事件,当键帽点击弹出我们点击的按键内容 keyupAll.forEach(function (R) { R.onclick = function () { alert(`您按下了${this.innerText}键`) } })
代码我放到码上掘金上了,感兴趣的可以看一看!
坚持努力,无惧未来!