Search code examples
htmlcssformsinputcenter

how to center properly an icon in an input text?


I'm new to stackoverflow, been using it to solve problems very often but it's the first time I ask something ! So. What I'm trying to do seems simple, but I can't figure out a satisfying and valid way to do it. My code is made with React. I can't change the way the icon is called, so here is not the question.

I want to vertically center this icon, which is called inside the label, so wrapped with my input, like this : centered icon vertically

Here's my code :

<label class="input-label">
nom
    <input type="text" class="input input-text input-with-icon" name="nom" placeholder="exemple" value=""/>
    <span class="input-icon input-icon--right" tabindex="0">
    <svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg"><g id="ad76e940dfa45c8f1e8d7675f49d95e7"><path id="c2de19005ef6cc9c6fd13489277b23b8" fill-rule="evenodd" clip-rule="evenodd" d="[a very long code I won't put here]" fill="#4C4F5C"></path></g></svg>
    </span>
</label>

I put flex on it so that the Label stack on the input, as I want. BUT ! If I do so, then my icon, which I center with absolute position on the parent (the label), get centered on the entire block which is two lines, instead of being centered only on input.

Also, W3C doesn't validate to have the label on one hand, then a div that wrap the two elements inside him. I tried it and, either I did it wrong or it's simply something that W3C is not ok with ! So I won't use it unless I'm forced to.

The only solution I see would be to calculate the input height, then do a bottom of the height divided by 2 (and then let the transform:translate(-50%) for the rest to be perfectly centered. But I don't have the specific height of the input. So I can also just tell : ok the input is 20px, I set a bottom of 10px, and 'finito pepito' (aka : it's over). But it's really not accurate, as this input is made for a design system. So it must be called in several cases, and always be responsive and adapted.

And to finish, I found that the input type search was answering to this but the icon can't be customized, so in any way I have to put this icon myself. Plus, I'm not sur it's a good idea to put a input search when you need an input text.

Do you see something more adapted ? Something acceptable and valid (I don't want to put some extra code or do something heavy if I can do it with less code.)

Thanks for your help !


Solution

  • You can simply use the for attribute of label tag in order to move input and icon into their own container. I've used flex and transform to position icon but there's many ways to achieve the same result :

    .text-input-container {
      display: flex;
      align-items: center;
    }
    
    .text-input {
       padding-right: 24px;
    }
    
    .text-input-icon {
       transform: translateX(-20px);
    }
    <label for="text-input">Nom</label>
    <div class="text-input-container">
      <input id="text-input" type="text" class="text-input">
      <svg height="12" width="12" class="text-input-icon">
        <circle cx="6" cy="6" r="6" stroke="black" stroke-width="3" fill="red" />
      </svg> 
     </div>