Je développe un composant bouton avec une icône et du texte.
L'icône est placée sur le côté gauche du bouton et le texte est aligné au milieu du bouton.
Si le texte ne peut pas tenir dans le bouton, il ne doit pas être renvoyé à la ligne mais peut être tronqué.
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.
Vous ne pouvez donc pas ajouter un remplissage en ligne égal dans les boutons.
Si le texte n'est pas tronqué, il sera aligné au milieu du bouton.
Cependant, dès qu'il commence à chevaucher l'icône ou ne parvient pas à s'adapter au bouton, le texte sera coupé.
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.
Exemple visuel de bouton
J'ai essayé d'utiliser CSS pour obtenir cet effet, mais j'ai échoué.
Enfin, j'ai ajouté un ResizeObserver à chaque bouton qui calcule s'il y a suffisamment d'espace pour le texte.
S'il n'y a pas assez d'espace, un style différent sera appliqué à l'icône.
Ma solution ResizeObserver, essayez de redimensionner la fenêtre
CodePen
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); });Ma question est :
Est-il possible d'obtenir le même effet en utilisant du CSS pur ?
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
.