在我之前的文章中,我研究了 CSS 中新的、改進的attr()
方法。我欣喜若狂(雙關語)。這次,我將繼續研究attr()
方法,展示如何製作易於閱讀的元件(至少對於吉他手來說),如下所示:
<fret-board frets="4" strings="6" chord="C Major">
<string-note string="6" mute></string-note>
<string-note string="5" fret="3" finger="3"></string-note>
<string-note string="4" fret="2" finger="2"></string-note>
<string-note string="3" open></string-note>
<string-note string="2" fret="1" finger="1"></string-note>
<string-note string="1" open></string-note>
</fret-board>
.... 變成這樣 —完全沒有 JavaScript :
讓我們開始吧!
首先,我們需要一個基本的網格。單元格和行的數量取決於我們在 HTML 中定義的frets
和strings
屬性 —— 因此讓我們將它們作為<number>
並設定兩個自訂屬性:
--_frets: attr(frets type(<number>), 4);
--_strings: attr(strings type(<number>), 6);
在 CSS 中,我們將字串的數量增加一倍,這樣我們就可以在字串上放置註解 - 字串本身左側的一個網格單元。我們還希望頂部和底部行用於和弦名稱和打開/靜音指示器,因此我們的網格如下所示:
fret-board {
grid-template-columns: repeat(calc(var(--_strings) * 2), 1fr);
grid-template-rows:
var(--fret-board-top-row-h, 12%)
repeat(calc(var(--_frets)), 1fr)
var(--fret-board-bottom-row-h, 15%);
}
我們現在有:
音品和琴弦作為兩個線性漸變加入到偽元素中:
fret-board {
--fret-board-fret-c: light-dark(#000, #FFF);
--fret-board-fret-w: clamp(0.0625rem, 0.03125rem + 0.5cqi, 0.5rem);
--fret-board-string-c: light-dark(#0008, #FFF8);
--fret-board-string-w: clamp(0.0625rem, 0.03125rem + 0.5cqi, 0.125rem);
background-image:
/* Vertical strings */
linear-gradient(
90deg,
var(--fret-board-string-c) var(--fret-board-string-w),
transparent 0 var(--fret-board-string-w)
),
/* Horizontal frets */
linear-gradient(
180deg,
var(--fret-board-fret-c) var(--fret-board-fret-w),
transparent 0 var(--fret-board-fret-w)
);
background-position:
0 var(--fret-board-fret-w),
0 0;
background-repeat:
repeat-x,
repeat-y;
background-size:
/* Width and height for strings */
calc(100% / (var(--_strings) - 1) - (var(--fret-board-string-w) / var(--_strings)))
calc(100% - (2 * var(--fret-board-fret-w))),
/* Width and height for frets */
100%
calc(100% / var(--_frets) - (var(--fret-board-fret-w) / var(--_frets)));
}
好的,這確實有點麻煩,但我們基本上從上到下為音品建立了水平線,並為貫穿整個琴弦建立了垂直線。
讓我們加入一些註釋 - 但首先,讓我們抓住這些屬性:
--barre: attr(barre type(<number>), 1);
--fret: attr(fret type(<number>), 0);
--string: attr(string type(<number>), 0);
我們很快就會講到--barre
,但現在,我們使用這個公式來放置音符:
string-note {
grid-column: calc((var(--_strings) * 2) - (var(--string) * 2 - 1)) / span calc(var(--barre) * 2);
grid-row: calc(var(--fret) + 1);
}
讓我們來分析一下:
(var(--_strings) * 2)
- 從網格的最右側開始
(var(--string) * 2 - 1)
- 計算從右側移動多遠
例如,有 6 個字串:
- String 1 (highest) goes at position `12 - (1*2-1) = 11`
- String 6 (lowest) goes at position `12 - (6*2-1) = 1`
span calc(var(--barre) * 2)
- 對於常規筆記,跨越 2 列
對於封閉和弦,跨越更多列,取決於覆蓋的弦數
calc(var(--fret) + 1)
- +1
代表標題行
開放弦(品味 = 0)放在第 1 行,第一品位放在第 2 行,等等。
這讓我們:
為了獲得好的指法譜,我們需要指出彈奏每個音符時應該使用哪根手指。我們從 HTML 中的finger
屬性取得它並使用偽元素顯示它:
string-note::after {
color: var(--string-note-c, light-dark(#FFF, #222));
content: attr(finger);
font-size: var(--string-note-fs, 7cqi);
font-weight: var(--string-note-fw, 500);
text-box: cap alphabetic;
}
注意:
text-box: cap alphabetic
是一種現代 CSS 功能,可以修剪由line-height
建立的間距。light-dark()
函數會自動調整文字顏色以適應亮模式或暗模式。
吉他和弦通常涉及未按下的琴弦,而是空弦演奏或靜音(未演奏):
<string-note string="6" mute></string-note> <!-- Muted string -->
<string-note string="3" open></string-note> <!-- Open string -->
對於字串狀態的視覺表示:
對於靜音弦,我們使用 Temani Atif 的十字形與border-image
和 45° 旋轉來建立一個 X 符號
對於開放的字串,我們使用帶有徑向漸變的 CSS 遮罩來建立空心圓效果
string-note[mute] {
border-image: conic-gradient(var(--fret-board-bg) 0 0) 50%/calc(50% - 0.25cqi);
rotate: 45deg;
}
string-note[open] {
border-radius: 50%;
mask: radial-gradient(circle farthest-side at center,
transparent calc(100% - 1cqi),
#000 calc(100% - 1cqi + 1px));
}
「封閉和弦」是指用一根手指按住多根弦的和弦。讓我們在 HTML 中加入barre
屬性:
<string-note string="6" fret="1" barre="6" finger="1"></string-note>
我們已經介紹了上面的計算,但它的視覺效果如下:
有時,和弦不是從第一品開始的,我們需要標明品味編號。為此,我們使用有序列表<ol>
,其中我們在第一項上設定value
屬性:
<ol><li value="7"></li></ol>
您可以在最終演示中檢查樣式,但它看起來像這樣:
現在,透過幾個屬性控制 CSS 的妙處在於,我們可以輕鬆地使其適用於其他儀器。以下是一些範例:
這是一個演示。請注意,它目前僅適用於 Chrome :
https://codepen.io/stoumann/pen/qEEKJYq
我希望您像我寫這篇文章一樣喜歡它——現在,我要拿起吉他彈奏一些和弦。