skip to Main Content

I have a button component (in React) that I want to make so that it would position its content centrally while allowing the specification of left or right icons. The content must be positioned in the center relating to the parent and respect each icon (optionally) if provided.

The problem I’m facing is that I’m not sure what’s the best way to make sure that the content can overlap on the next line when it reaches the icon.

Below are a couple of images of what I’m trying to achieve

enter image description here

enter image description here

I was trying to use absolute positioning for both elements with transform: translateX to adjust the position of the content, but it doesn’t work in case if the content take the full space or longer than expected. Also, was trying to use flexbox, but it doesn’t allow to align single element in relation to parent without taking into account the icons. Setting a padding on left or right side (depending on the icon’s width) doesn’t seem to work either as it shifts the content and breaks the central alignment

Would much appreciate any advice or direction which I can try to make it work. Trying to avoid going with any "hacky" Javascript based solution where I would have to calculate each container 🙏

2

Answers


  1. You can create a css class incorporating grid design system & also depending on style requirement you can add ellipis to show dots for long button text

    .custom-btn {
      display: grid;
      padding: 5px;
      align-items: center;
      grid-template-columns: 1fr 40px;
      width: 200px
    }
    
    .btn-txt {
      text-overflow: ellipsis;
      white-space: nowrap;
      overflow: hidden;
    }
    <button class="custom-btn">
         <span class="btn-txt">Text Content</span>
         <span>Icon</span>
        </button>
    
    <button class="custom-btn">
         <span class="btn-txt">iedowedoiwfohwiuwriufwriufhwrufnhwriofnwroirfnwrfiwrf </span>
         <span>Icon</span>
        </button>
    Login or Signup to reply.
  2. I’m not wholly clear what behaviour you want from the text when it wraps, but maybe you want something like this. Basically, add a ::before and/or ::after pseudo element to stand in for any missing icon. Set their height to match the height of the icon. Set the flex-basis to the width of the icon and the flex-grow to 0, so that when the button text is short the pseudo-element will take up the same space as the icon would, and the text will be centered. Also set their flex-shrink to a large number so that they rapidly shrink when the text becomes too long to fit on one line between the icons.

    button {
      width: 80%;
      display: flex;
      justify-content: space-between;
      padding: 0.2em;
    }
    button:has(span:first-child)::before,
    button:has(span:last-child)::after {
      content: '';
      height: 32px;
      flex: 0 10 32px;
    }
    section {
      margin-block: 0.3em;
    }
    <section class="case one">
      <button>
        <img src="https://placehold.co/32/cadetblue/white">
        <span contenteditable>short text</span>
        <img src="https://placehold.co/32/moccasin/black">
      </button>
    </section>
    <section class="case two">
      <button>
        <span contenteditable>short text</span>
        <img src="https://placehold.co/32/moccasin/black">
      </button>
    </section>
    <section class="case three">
      <button>
        <img src="https://placehold.co/32/cadetblue/white">
        <span contenteditable>short text</span>
      </button>
    </section>
    <section class="case four">
      <button>
        <span contenteditable>short text</span>
      </button>
    </section>
    <section class="case five">
      <button>
        <img src="https://placehold.co/32/cadetblue/white">
        <span contenteditable>Lorem ipsum dolor sit amet, consectetur 
          adipiscing elit, sed do eiusmod tempor 
          incididunt ut labore et dolore magna aliqua.</span>
        <img src="https://placehold.co/32/moccasin/black">
      </button>
    </section>
    <section class="case six">
      <button>
        <span contenteditable>Lorem ipsum dolor sit amet, consectetur 
          adipiscing elit, sed do eiusmod tempor 
          incididunt ut labore et dolore magna aliqua.</span>
        <img src="https://placehold.co/32/moccasin/black">
      </button>
    </section>
    <section class="case seven">
      <button>
        <img src="https://placehold.co/32/cadetblue/white">
        <span contenteditable>Lorem ipsum dolor sit amet, consectetur 
          adipiscing elit, sed do eiusmod tempor 
          incididunt ut labore et dolore magna aliqua.</span>
      </button>
    </section>
    <section class="case eight">
      <button>
        <span contenteditable>Lorem ipsum dolor sit amet, consectetur 
          adipiscing elit, sed do eiusmod tempor 
          incididunt ut labore et dolore magna aliqua.</span>
      </button>
    </section>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search