相对于其前一个同级元素定位 div 元素(钢琴键盘样式)

问题描述 投票:0回答:1

我正在使用 HTML + CSS 开发钢琴键盘。
我的代码结构如下:

:root {
  --piano-width: 600px;
  --piano-height: 150px;
  --piano-keys-gap: 1px;
  --piano-black-keys-height-perc: 0.6;
}

.piano-keys {
  display: flex;
  flex-direction: row;
  justify-content: center;
  width: var(--piano-width);
  height: var(--piano-height);
}

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

.piano-key.key-white {
  background-color: #eeeeee;
  flex-basis: 100%;
}

.piano-key.key-black {
  background-color: #333;
  flex-basis: 90%;
  height: calc(var(--piano-height) * var(--piano-black-keys-height-perc));
  z-index: 1;
  margin-left: -HALF_CURRENT_SIZE;
  margin-right: -HALF_CURRENT_SIZE;
}
<div class="piano-container">
  <div class="piano-keys">
    <div class="piano-key key-white note-selector" data-note="C" selected>C</div>
    <div class="piano-key key-black note-selector" data-note="C#" has-acidental>C#</div>
    ...
    <div class="piano-key key-white note-selector" data-note="B">B</div>
  </div>
</div>

我想要一种将黑键定位在白键上方的方法,考虑到:

  • 按键的宽度是动态的,它们必须填充父div的大小
  • 黑键的宽度比白键的宽度稍小(白键约为 100% 弹性基础,黑键约为 90% 弹性基础)
  • 我希望能够控制按键之间的间隙,以 px 为单位

我在一个网站上发现,通过在每侧放置按键宽度一半的负水平边距,它会重叠,达到所需的效果。但由于宽度是动态的,我无法做到这一点。
有没有办法不用JavaScript也能达到这样的效果?

html css flexbox css-position
1个回答
0
投票

只是一个建议...

// just 4 testing...

const pianoKeys = document.querySelector('.pianoKeys')
  ;
let timConsole = 0
  ;
pianoKeys.onclick = e =>
  {
  clearTimeout(timConsole);
  console.clear();
  if (!e.target.matches('div[data-note]')) return;
  console.log( e.target.dataset.note );
  timConsole = setTimeout(console.clear,2000);
  }
:root {
  --gapWk :   2px; /* gap White keys         */
  --szwWk :  50px; /* size width White keys  */
  --szwBk :  40px; /* size width Black keys  */
  --szhWk : 100px; /* size height White keys */
  --szhBk :  50px; /* size height Black keys */
  }
*,html,body {
  margin     : 0;
  padding    : 0;
  box-sizing : border-box;
  }
body {
  font-family : Arial, Helvetica, sans-serif;
  font-size   : 16px;
  }
.pianoKeys {
  position  : relative;
  font-size : 0;

  & > div > div {
    font-size: 1rem;
    text-align: center;
    }
  & > div > div::before {
    content : attr(data-note);
    }
  & > .BlackKeys , 
  & > .whiteKeys {
    position    : absolute;
    top         : 0;
    left        : 0;
    white-space : nowrap;
    z-index     : -1;
    }
  & > .BlackKeys > div , 
  & > .whiteKeys > div {
    display    : inline-block;
    box-sizing : border-box;
    z-index    : 10;
    }
  }
.BlackKeys {
  padding-left: calc((var(--szwWk) - (var(--szwBk) / 2)) + (var(--gapWk) / 2));   
  }
.whiteKeys > div {
  width        : var(--szwWk);
  height       : var(--szhWk);
  background   : whitesmoke;
  border       : 1px solid black;
  margin-right : var(--gapWk);
  padding-top  : calc(var(--szhWk) - 1.6em) ;
  }
.BlackKeys > div {
  width        : var(--szwBk);
  height       : var(--szhBk);
  background   : darkslategrey;
  margin-right : calc(var(--szwWk) - var(--szwBk) + var(--gapWk));
  color        :  yellow;
  padding-top  : calc(var(--szhBk) - 2em) ;
  }
.BlackKeys > div[data-note="a#"] ,
.BlackKeys > div[data-note="d#"] {
  margin-right : calc((var(--szwWk) *2) - var(--szwBk) + (var(--gapWk) *2));
  }
  
  
.as-console-row       { background-color: yellow; }
.as-console-row::after{ display:none !important;  }
.as-console-row-code  { font-size: 30px !important; font-weight: bold !important; }
<div class="pianoKeys">
  <div class="whiteKeys">
    <div data-note="c"></div>
    <div data-note="d"></div>
    <div data-note="e"></div>
    <div data-note="f"></div>
    <div data-note="g"></div>
    <div data-note="a"></div>
    <div data-note="b"></div>
    <div data-note="c"></div>
    <div data-note="d"></div>
    <div data-note="e"></div>
    <div data-note="f"></div>
    <div data-note="g"></div>
    <div data-note="a"></div>
    <div data-note="b"></div>
  </div>
  <div class="BlackKeys">
    <div data-note="c#"></div>
    <div data-note="d#"></div>
    <div data-note="f#"></div>
    <div data-note="g#"></div>
    <div data-note="a#"></div>
    <div data-note="c#"></div>
    <div data-note="d#"></div>
    <div data-note="f#"></div>
    <div data-note="g#"></div>
    <div data-note="a#"></div>
  </div>
</div>

© www.soinside.com 2019 - 2024. All rights reserved.