Bouton avec texte et icône centrés
P粉033429162
2023-08-15 11:01:09
<p>Je développe un composant bouton avec une icône et du texte. </p>
<p>L'icône est placée sur le côté gauche du bouton et le texte est aligné au milieu du bouton. </p>
<p>Si le texte ne peut pas tenir dans le bouton, il ne doit pas être renvoyé à la ligne mais peut être tronqué. </p>
<p>La condition clé pour tronquer le texte est que le texte doit être à la même distance du bord du bouton que l'icône l'est du bord du bouton. </p>
<p>Vous ne pouvez donc pas ajouter un remplissage en ligne égal dans les boutons. </p>
<p>Si le texte n'est pas tronqué, il sera aligné au milieu du bouton. </p>
<p>Cependant, dès qu'il commence à chevaucher l'icône ou ne parvient pas à s'adapter au bouton, le texte sera coupé. </p>
<p>En d'autres termes, dans l'état normal, la position de l'icône reste inchangée, mais lorsqu'il n'y a pas assez d'espace pour le texte, l'icône poussera le texte vers la position tronquée. </p>
<p>Exemple visuel de bouton</p>
<p>J'ai essayé d'utiliser CSS pour obtenir cet effet, mais j'ai échoué. </p>
<p>Enfin, j'ai ajouté un ResizeObserver à chaque bouton qui calcule s'il y a suffisamment d'espace pour le texte. </p>
<p>S'il n'y a pas assez d'espace, un style différent sera appliqué à l'icône. </p>
<p>Ma solution ResizeObserver, essayez de redimensionner la fenêtre</p>
<p>CodePen</p>
<pre class="brush:php;toolbar:false;">const CLASS_TEXT = `button__text`;
const CLASS_NO_FREE_SPACE = `bouton_no-free-space` ;
const FREE_SPACE_SIZE = 70 ;
const boutons = document.querySelectorAll(`.${CLASS_ROOT}`);
const handleButtonResize = (entrées) =>
entrées.forEach((entrée) => {
const { cible } = entrée ;
const text = target.querySelector(`.${CLASS_TEXT}`);
const { width: widthButton } = entrée.contentRect;
if (!(instance de texte de HTMLElement)) {
retour;
}
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);
[...boutons].forEach((bouton) => {
resizeObserver.observer(bouton);
});</pré>
<p><strong>Ma question est :</strong></p>
<p>Est-il possible d'obtenir le même effet en utilisant du CSS pur ? </p>
Puisque la largeur de l'icône est toujours la même (
2em
),我们可以使用::after
le pseudo-élément fait office de "tampon" pour l'équilibrage de l'espace à droite.Placez
.button__icon
设置为弹性布局流。这在“推动”其他元素时至关重要。给它margin-right
pour équilibrer le rembourrage gauche du bouton.Créez un espace
flex-basis: calc(2em + 20px)
的::after
伪元素。其中2em
是.button__icon
的宽度,20px
是.button__icon
的margin-right
。这样可以在.button__text
équilibré à gauche et à droite lorsqu'il est plus court.sera
justify-content: space-between
应用于父元素,以帮助平衡.button__icon
、.button__text
和::after
当.button__text
sera plus court.Ajoutez un élément
flex-shrink: 999
,一个巨大的收缩因子,以便布局引擎在.button__text
较长时优先收缩::after
.