Schaltfläche mit zentriertem Text und Symbol
P粉033429162
2023-08-15 11:01:09
<p>Ich entwickle eine Schaltflächenkomponente mit einem Symbol und Text. </p>
<p>Das Symbol wird auf der linken Seite der Schaltfläche platziert und der Text wird in der Mitte der Schaltfläche ausgerichtet. </p>
<p>Wenn der Text nicht in die Schaltfläche passt, sollte er nicht umgebrochen werden, sondern kann abgeschnitten werden. </p>
<p>Die wichtigste Bedingung für das Abschneiden von Text ist, dass der Text den gleichen Abstand vom Rand der Schaltfläche haben sollte wie das Symbol vom Rand der Schaltfläche. </p>
<p>Sie können also keine gleichmäßige Inline-Auffüllung in Schaltflächen hinzufügen. </p>
<p>Wenn der Text nicht abgeschnitten ist, wird er in der Mitte der Schaltfläche ausgerichtet. </p>
<p>Sobald der Text jedoch das Symbol überlappt oder nicht mehr in die Schaltfläche passt, wird er abgeschnitten. </p>
<p>Mit anderen Worten: Im Normalzustand bleibt die Position des Symbols unverändert, aber wenn nicht genügend Platz für den Text vorhanden ist, verschiebt das Symbol den Text an die abgeschnittene Position. </p>
<p>Visuelles Beispiel einer Schaltfläche</p>
<p>Ich habe versucht, CSS zu verwenden, um diesen Effekt zu erzielen, aber es ist mir nicht gelungen. </p>
<p>Zuletzt habe ich zu jeder Schaltfläche einen ResizeObserver hinzugefügt, der berechnet, ob genügend Platz für den Text vorhanden ist. </p>
<p>Wenn nicht genügend Platz vorhanden ist, wird ein anderer Stil auf das Symbol angewendet. </p>
<p>Meine ResizeObserver-Lösung, versuchen Sie, die Größe des Fensters zu ändern</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 = (Einträge) =>
Einträge.forEach((entry) => {
const { Ziel } = Eintrag;
const text = target.querySelector(`.${CLASS_TEXT}`);
const { width: widthButton } = enter.contentRect;
if (!(Textinstanz von HTMLElement)) {
zurückkehren;
}
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>Meine Frage ist:</strong></p>
<p>Ist es möglich, den gleichen Effekt mit reinem CSS zu erzielen? </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
元素。