居中文字和圖示的按鈕
P粉033429162
2023-08-15 11:01:09
<p>我正在開發一個帶有圖標和文字的按鈕元件。 </p>
<p>圖示位於按鈕的左側,文字在按鈕中間對齊。 </p>
<p>如果文字無法適應按鈕,它不應該換行,而是可以被截斷。 </p>
<p>截斷文字的關鍵條件是,文字距離按鈕邊緣的距離應與圖示距離按鈕邊緣的距離相同。 </p>
<p>所以你不能在按鈕中加入相等的內嵌填滿。 </p>
<p>如果文字沒有被截斷,它將在按鈕中間對齊。 </p>
<p>然而,一旦它開始重疊圖標或無法適應按鈕,文字將被截斷。 </p>
<p>換句話說,在正常狀態下,圖示的位置不變,但當文字沒有足夠的空間時,圖示會將文字推到被截斷的位置。 </p>
<p>按鈕的視覺化範例</p>
<p>我嘗試使用CSS來實現這個效果,但失敗了。 </p>
<p>最後,我為每個按鈕添加了一個ResizeObserver,用於計算文字是否有足夠的空間。 </p>
<p>如果沒有足夠的空間,將套用不同的樣式到圖示上。 </p>
<p>我的ResizeObserver解決方案,請嘗試調整視窗大小</p>
<p>CodePen</p>
<pre class="brush:php;toolbar:false;">const CLASS_TEXT = `button__text`;
const CLASS_NO_FREE_SPACE = `button_no-free-space`;
const FREE_SPACE_SIZE = 70;
const buttons = document.querySelectorAll(`.${CLASS_ROOT}`);
const handleButtonResize = (entries) => {
entries.forEach((entry) => {
const { target } = entry;
const text = target.querySelector(`.${CLASS_TEXT}`);
const { width: widthButton } = entry.contentRect;
if (!(text instanceof HTMLElement)) {
return;
}
const widthText = text.offsetWidth;
const freeSpaceLeft = (widthButton - widthText) / 2;
const noFreeSpace = freeSpaceLeft <= FREE_SPACE_SIZE;
target.classList.toggle(CLASS_NO_FREE_SPACE, noFreeSpace);
});
};
const resizeObserver = new ResizeObserver(handleButtonResize);
[...buttons].forEach((button) => {
resizeObserver.observe(button);
});</pre>
<p><strong>我的問題是:</strong></p>
<p>是否可以使用純CSS實現相同的效果? </p>
由於圖示的寬度始終相同(
2em
),我們可以使用::after
偽元素作為右側空間平衡的「緩衝區」。將
.button__icon
設定為彈性佈局流。這在「推動」其他元素時至關重要。給它margin-right
來平衡按鈕的左填充。建立一個具有
flex-basis: calc(2em 20px)
的::after
偽元素。其中2em
是.button__icon
的寬度,20px
是.button__icon
的margin-right
。這樣可以在.button__text
較短時平衡左右空間。將
justify-content: space-between
套用到父元素,以幫助平衡.button__icon
、.button__text
和::after
當.button__text
較短時。加上
flex-shrink: 999
,一個巨大的收縮因子,以便佈局引擎在.button__text
較長時優先收縮::after
元素。