如何正确将图标居中在输入文本框中?

huangapple go评论54阅读模式
英文:

how to center properly an icon in an input text?

问题

我是stackoverflow新手,经常使用它来解决问题,但这是我第一次提问!所以,我试图做的事情似乎很简单,但我找不到一个令人满意和有效的方法来做到这一点。我的代码是用React编写的。我不能改变调用图标的方式,所以这不是问题所在。

我想要垂直居中这个图标,它被调用在标签内部,所以包裹在我的输入框中,就像这样:
居中图标

这是我的代码:

<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="[一个我不会在这里放的很长的代码]" fill="#4C4F5C"></path></g></svg>
    </span>
</label>

我给它加了flex,以便标签堆叠在输入框上,这正是我想要的。但是!如果我这样做,那么我的图标,我在父元素(标签)上使用绝对定位使其居中,会在整个块上居中,而不是仅在输入框上居中。

此外,W3C 不允许在一侧放置标签,然后用一个包装两个元素的 div 包裹它们。我尝试过,要么我做错了,要么就是 W3C 不接受这样做!所以我不会使用它,除非我被迫这样做。

我唯一能想到的解决办法是计算输入框的高度,然后将底部设置为高度除以2(然后使用 transform:translate(-50%) 来完美居中其余部分)。但我没有特定的输入框高度。所以我也可以简单地告诉:好的,输入框是20px,我设置底部为10px,完成(也就是说,问题解决了)。但这真的不准确,因为这个输入框是为设计系统而设计的。因此,它必须在多种情况下调用,并始终响应并适应。

最后,我发现输入框类型为搜索时可以解决这个问题,但是图标无法自定义,所以无论如何我都必须自己放置这个图标。此外,我不确定在需要输入文本时是否将其替换为搜索输入框是否是一个好主意。

你看到了更适合的方法吗?更可接受和有效的方法(如果可以用更少的代码做到,我不想添加额外的代码或做繁重的工作)。

感谢您的帮助!

英文:

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 !

答案1

得分: 0

你可以简单地使用label标签的for属性,将输入框和图标放入它们自己的容器中。我使用了flex和transform来定位图标,但有许多方法可以实现相同的结果:

.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>
英文:

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 :

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-css -->

.text-input-container {
  display: flex;
  align-items: center;
}

.text-input {
   padding-right: 24px;
}

.text-input-icon {
   transform: translateX(-20px);
}

<!-- language: lang-html -->

&lt;label for=&quot;text-input&quot;&gt;Nom&lt;/label&gt;
&lt;div class=&quot;text-input-container&quot;&gt;
  &lt;input id=&quot;text-input&quot; type=&quot;text&quot; class=&quot;text-input&quot;&gt;
  &lt;svg height=&quot;12&quot; width=&quot;12&quot; class=&quot;text-input-icon&quot;&gt;
    &lt;circle cx=&quot;6&quot; cy=&quot;6&quot; r=&quot;6&quot; stroke=&quot;black&quot; stroke-width=&quot;3&quot; fill=&quot;red&quot; /&gt;
  &lt;/svg&gt; 
 &lt;/div&gt;

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年2月13日 23:38:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/75438070.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定