|CSS|Fix Hover Font Weight & Spacing Changes

當設計 hover 效果時想變更文字粗細或是字距,文字通常會導致佈局發生一些變化。這是因為粗體字和字距變得比原空間更大所導致。以下將示範如何解決文字粗細、字距導致空間改變的問題:
在文字標籤 .tt-block 上設置自定義屬性 data-*,屬性名稱可自訂,並將其值設為與標籤內顯示的文字內容相同。
html
在文字標籤的偽元素 .tt-block::before 上,使用 content 屬性來取得 .tt-block 的 data-tt 值,並設定與 .tt-block:hover 相同的 font-weight 和 letter-spacing,用來撐開標籤的空間。接著,為 .tt-block::before 設定 pointer-events: none、display: block 和 height: 0,達到隱藏效果。
以上做法是用偽元素來預留空間,將 hover 狀態的 font-weight 和 letter-spacing 設定到偽元素中。即使在 hover 時文字外觀發生變化,整體布局空間仍保持不變,避免因字體調整導致跳動。
css
.tt-block{ font-weight: 300;
color: rgba(0, 0, 0, 1);
letter-spacing: 0;
transition: color 0.5s, letter-spacing 0.5s;
}
.btn:hover .tt-block{ font-weight: 700;
color: rgba(255, 255, 255, 1);
letter-spacing: var(--tt-spacing);
}
/* 偽元素撐開 */
.fix .tt-block::before{ content: attr(data-tt); /* 用 content 屬性獲取 data-tt 的值 */
font-weight: 700; /* 設定同 hover 時的字體粗細 */
letter-spacing: var(--tt-spacing); /* 設定同 hover 時的字距 */
pointer-events: none; /* 鼠標觸發不到它 */
display: block; /* 讓 ::before 往下空間擠 */
height: 0; /* 隱藏用 */
}
:root{ --tt-spacing: min(0.12vw, 0.2rem);}
如果只有單純做文字粗細變化,可改用 text-shadow 的疊加做出文字粗細變化效果,也可達到不會改變文字空間。
css
.font-weight .tt-block{ transition: color 0.5s, text-shadow 0.5s;
text-shadow: 0 0 0 rgba(255, 255, 255, 0),
0 0 0 rgba(255, 255, 255, 0),
0 0 0 rgba(255, 255, 255, 0),
0 0 0 rgba(255, 255, 255, 0),
0 0 1px rgba(255, 255, 255, 0);
}
.font-weight .btn:hover .tt-block{ text-shadow: 0 0 0.8px rgba(255, 255, 255, 1),
0 0 0.8px rgba(255, 255, 255, 1),
0 0 0.8px rgba(255, 255, 255, 1),
0 0 0.8px rgba(255, 255, 255, 1),
0 0 0.8px rgba(255, 255, 255, 0.5);
}