You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何纯CSS实现动态宽度钢琴键盘的黑键定位与间隙控制

纯CSS实现动态宽度的钢琴键盘黑键覆盖效果

可以通过Flex布局结合绝对定位实现无需JavaScript的解决方案,完美满足你的所有需求:

完整代码实现

CSS部分

:root {
  --piano-width: 600px;
  --piano-height: 150px;
  --piano-keys-gap: 1px;
  --piano-black-keys-height-perc: 0.6;
  --white-key-count: 7; /* 一个八度的白键数量,多八度可按比例调整 */
}

.piano-container {
  display: flex;
  justify-content: center;
  margin: 20px;
}

.piano-keys {
  display: flex;
  width: var(--piano-width);
  height: var(--piano-height);
  gap: var(--piano-keys-gap); /* 用gap直接控制白键间的px级间隙 */
  position: relative; /* 作为黑键绝对定位的参考容器 */
}

.piano-key {
  position: relative;
  box-shadow: 2px 2px 3px rgba(0, 0, 0, 0.2);
  cursor: pointer;
  border-radius: 0 0 3px 3px;
}

.piano-key.key-white {
  background-color: #eeeeee;
  flex: 1; /* 自动平分父容器宽度,实现动态适配 */
}

.piano-key.key-black {
  position: absolute;
  background-color: #333;
  width: calc((100% / var(--white-key-count)) * 0.9); /* 黑键宽度为白键的90% */
  height: calc(var(--piano-height) * var(--piano-black-keys-height-perc));
  z-index: 1; /* 确保黑键在白键上方 */
  top: 0;
}

/* 定位每个黑键到正确位置(一个八度的布局) */
.piano-key.key-black:nth-child(2) {
  left: calc((100% / var(--white-key-count)) * 0.55);
}
.piano-key.key-black:nth-child(4) {
  left: calc((100% / var(--white-key-count)) * 1.55);
}
.piano-key.key-black:nth-child(7) {
  left: calc((100% / var(--white-key-count)) * 3.55);
}
.piano-key.key-black:nth-child(9) {
  left: calc((100% / var(--white-key-count)) * 4.55);
}
.piano-key.key-black:nth-child(11) {
  left: calc((100% / var(--white-key-count)) * 5.55);
}

HTML部分

<div class="piano-container">
  <div class="piano-keys">
    <div class="piano-key key-white note-selector" data-note="C">C</div>
    <div class="piano-key key-black note-selector" data-note="C#">C#</div>
    <div class="piano-key key-white note-selector" data-note="D">D</div>
    <div class="piano-key key-black note-selector" data-note="D#">D#</div>
    <div class="piano-key key-white note-selector" data-note="E">E</div>
    <div class="piano-key key-white note-selector" data-note="F">F</div>
    <div class="piano-key key-black note-selector" data-note="F#">F#</div>
    <div class="piano-key key-white note-selector" data-note="G">G</div>
    <div class="piano-key key-black note-selector" data-note="G#">G#</div>
    <div class="piano-key key-white note-selector" data-note="A">A</div>
    <div class="piano-key key-black note-selector" data-note="A#">A#</div>
    <div class="piano-key key-white note-selector" data-note="B">B</div>
  </div>
</div>

方案说明

  1. 动态宽度适配:

    • 白键使用flex:1,自动平分piano-keys容器的宽度,无论容器宽度如何变化,都能填满且均匀分配。
    • 通过--white-key-count变量统一控制白键数量,多八度场景只需调整该变量和黑键的nth-child选择器即可。
  2. 黑键宽度控制:

    • 黑键宽度通过calc((100% / var(--white-key-count)) * 0.9)计算,确保始终为白键宽度的90%,无需硬编码数值。
  3. px级间隙控制:

    • 直接利用Flex布局的gap属性设置--piano-keys-gap变量,精确控制白键间的间隙大小,单位支持px。
  4. 黑键覆盖定位:

    • 黑键采用position:absolute脱离文档流,通过calc计算left值,精准定位到两个白键的重叠区域,结合z-index:1确保覆盖在白键上方。

内容的提问来源于stack exchange,提问作者RrR2010

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 00:24:53