我正在使用 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>
我想要一种将黑键定位在白键上方的方法,考虑到:
我在一个网站上发现,通过在每侧放置按键宽度一半的负水平边距,它会重叠,达到所需的效果。但由于宽度是动态的,我无法做到这一点。
有没有办法不用JavaScript也能达到这样的效果?
只是一个建议...
// 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>