如何让占位符文本缩小以适合其文本输入元素并显示其全部值?
How can I get placeholder text to shrink to fit within its text input element and show its entire value?
我有以下 HTML:
<form>
<table border="1">
<tr>
<td>Traveler's name:</td>
<td>
<input type="text" id="travelername" placeholder="Last Name, First Name, Middle Initial"/>
</td>
</tr>
<tr>
<td>Traveler's E-mail:</td>
<td>
<input type="email" id="traveleremail"/>
</td>
</tr>
</table>
</form>
我希望占位符 val 始终完全可见,但事实并非如此:
我试着添加这个 CSS:
input[placeholder] {
font-size: 0.6em;
}
...但是,虽然这很好地减小了字体的大小,但文本被截断了:
我尝试像这样添加到 CSS:
input[placeholder] {
font-size: 0.6em;
width: 500;
}
...但它对 expand/widen 输入文本中的占位符文本区域没有任何作用(输入文本足够宽以容纳缩小的文本,但它仍然被压成一个太小的区域在它自己内)。
如何实现?
原始回复 - 2015 年 7 月
做这样的事情怎么样?我用 jQuery 来演示它。如果您希望它在文本宽度方面更多 'exact',您可以查看一种获取文本宽度的方法,然后将 jquery 的 CSS 中的宽度设置为从获取文本宽度的函数返回的值(在这种情况下,您可能必须创建一个元素,将其 html 设置为占位符的内容,获取文本的宽度,然后删除该元素)。无论如何,下面的代码是我要完成你所要求的。
我决定使用 setInterval
,因为获取输入字段的更改不是非黑即白的。 each
循环遍历输入元素。然后代码检查输入是否为空,如果是,则缩小字体大小(我硬编码为 10px),否则将其设置为默认值(假设你想要 14px,它得到 14px)。
setInterval(function() {
$('input').each(function(){
if($(this).val() === ''){
$(this).css({
"width":$(this).width()+"px",
"height":$(this).height()+"px"
});
if(parseFloat($(this).css('font-size'))<=14){
$(this).animate({
"font-size":10+"px"
});
}
}
else {
$(this).finish().clearQueue().css({
"font-size":14+"px"
});
}
});
}, 100);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form>
<table border="1">
<tr>
<td>Traveler's name:</td>
<td>
<input type="text" id="travelername" placeholder="Last Name, First Name, Middle Initial"/>
</td>
</tr>
<tr>
<td>Traveler's E-mail:</td>
<td>
<input type="email" id="traveleremail"/>
</td>
</tr>
</table>
</form>
如果需要,您可以降低或增加 setInterval
函数的间隔,以使其执行得更快或更慢(请记住性能和不同的计算速度)
编辑 - 2017 年 5 月
看到这个问题已经被浏览了一千多次,我觉得我应该更新我的答案,让它更有用一点,减少对手动输入的依赖。
下面的代码工作如下:
- 为输入字段及其关联的克隆创建 CSS 样式(可以根据您的需要自定义此逻辑,但为了简单起见,我为所有输入元素克隆提供了相同的 class)
- 遍历所有
input
个元素并创建一个克隆
- 获取克隆的宽度并将其宽度与输入元素的宽度进行比较,同时在每次迭代中将
font-size
减少 step
- 一旦克隆的宽度小于或等于输入元素的宽度,我们删除克隆元素并设置输入的
font-size
.
- 根据 用户在
input
元素内输入 ,我们撤消对 font-size
的更改
注意:当“撤消”我们对输入元素的更改时,我们实际上是在删除 内联属性 和 值。这些元素的任何样式都应在 CSS 中完成(否则您将不得不尝试找到解决此问题的方法,例如创建一个带有 id 的隐藏元素,访问它,提取样式并将其应用回输入元素)。
在测试下面的代码时,我个人发现 0.1
的步长就足够了,较小的值(比如 0.01)会影响性能。但是,您可以随意使用此值。
// Step is used to reduce font-size by value X
var step = 0.1;
setInterval(function() {
// Loop over input elements
$('input').each(function() {
// Only change font-size if input value is empty (font-size should only affect placeholder)
if ($(this).val() === '') {
// Create clone
$clone = $('<span></span>')
.appendTo('body')
.addClass('inputClone')
.text($(this).attr('placeholder'));
// Adjust font-size of clone
var fontSize = $(this).css('font-size');
do {
fontSize = parseFloat($clone.css('font-size')) - step;
$clone.css({
'font-size': fontSize
});
} while ($clone.width() > $(this).width());
// Maintain input field size
$(this).css({
"width": $(this).width() + "px",
"height": $(this).height() + "px"
});
// Change input font-size
$(this).animate({
'font-size': fontSize
});
// Delete clone
$clone.remove();
} else {
// Default input field back to normal
$(this)
.finish()
.clearQueue()
.attr('style', function(i, style) {
// Remove inline style for font-size
return style.replace(/font-size[^;]+;?/g, '');
});
}
});
}, 100);
input,
.inputClone {
font-family: "Arial", Helvetica, sans-serif;
font-size: 14px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
<table border="1">
<tr>
<td>Traveler's name:</td>
<td>
<input type="text" id="travelername" placeholder="Last Name, First Name, Middle Initial" />
</td>
</tr>
<tr>
<td>Traveler's E-mail:</td>
<td>
<input type="email" id="traveleremail" />
</td>
</tr>
</table>
</form>
我有以下 HTML:
<form>
<table border="1">
<tr>
<td>Traveler's name:</td>
<td>
<input type="text" id="travelername" placeholder="Last Name, First Name, Middle Initial"/>
</td>
</tr>
<tr>
<td>Traveler's E-mail:</td>
<td>
<input type="email" id="traveleremail"/>
</td>
</tr>
</table>
</form>
我希望占位符 val 始终完全可见,但事实并非如此:
我试着添加这个 CSS:
input[placeholder] {
font-size: 0.6em;
}
...但是,虽然这很好地减小了字体的大小,但文本被截断了:
我尝试像这样添加到 CSS:
input[placeholder] {
font-size: 0.6em;
width: 500;
}
...但它对 expand/widen 输入文本中的占位符文本区域没有任何作用(输入文本足够宽以容纳缩小的文本,但它仍然被压成一个太小的区域在它自己内)。
如何实现?
原始回复 - 2015 年 7 月
做这样的事情怎么样?我用 jQuery 来演示它。如果您希望它在文本宽度方面更多 'exact',您可以查看一种获取文本宽度的方法,然后将 jquery 的 CSS 中的宽度设置为从获取文本宽度的函数返回的值(在这种情况下,您可能必须创建一个元素,将其 html 设置为占位符的内容,获取文本的宽度,然后删除该元素)。无论如何,下面的代码是我要完成你所要求的。
我决定使用 setInterval
,因为获取输入字段的更改不是非黑即白的。 each
循环遍历输入元素。然后代码检查输入是否为空,如果是,则缩小字体大小(我硬编码为 10px),否则将其设置为默认值(假设你想要 14px,它得到 14px)。
setInterval(function() {
$('input').each(function(){
if($(this).val() === ''){
$(this).css({
"width":$(this).width()+"px",
"height":$(this).height()+"px"
});
if(parseFloat($(this).css('font-size'))<=14){
$(this).animate({
"font-size":10+"px"
});
}
}
else {
$(this).finish().clearQueue().css({
"font-size":14+"px"
});
}
});
}, 100);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form>
<table border="1">
<tr>
<td>Traveler's name:</td>
<td>
<input type="text" id="travelername" placeholder="Last Name, First Name, Middle Initial"/>
</td>
</tr>
<tr>
<td>Traveler's E-mail:</td>
<td>
<input type="email" id="traveleremail"/>
</td>
</tr>
</table>
</form>
如果需要,您可以降低或增加 setInterval
函数的间隔,以使其执行得更快或更慢(请记住性能和不同的计算速度)
编辑 - 2017 年 5 月
看到这个问题已经被浏览了一千多次,我觉得我应该更新我的答案,让它更有用一点,减少对手动输入的依赖。
下面的代码工作如下:
- 为输入字段及其关联的克隆创建 CSS 样式(可以根据您的需要自定义此逻辑,但为了简单起见,我为所有输入元素克隆提供了相同的 class)
- 遍历所有
input
个元素并创建一个克隆 - 获取克隆的宽度并将其宽度与输入元素的宽度进行比较,同时在每次迭代中将
font-size
减少step
- 一旦克隆的宽度小于或等于输入元素的宽度,我们删除克隆元素并设置输入的
font-size
. - 根据 用户在
input
元素内输入 ,我们撤消对font-size
的更改
注意:当“撤消”我们对输入元素的更改时,我们实际上是在删除 内联属性 和 值。这些元素的任何样式都应在 CSS 中完成(否则您将不得不尝试找到解决此问题的方法,例如创建一个带有 id 的隐藏元素,访问它,提取样式并将其应用回输入元素)。
在测试下面的代码时,我个人发现 0.1
的步长就足够了,较小的值(比如 0.01)会影响性能。但是,您可以随意使用此值。
// Step is used to reduce font-size by value X
var step = 0.1;
setInterval(function() {
// Loop over input elements
$('input').each(function() {
// Only change font-size if input value is empty (font-size should only affect placeholder)
if ($(this).val() === '') {
// Create clone
$clone = $('<span></span>')
.appendTo('body')
.addClass('inputClone')
.text($(this).attr('placeholder'));
// Adjust font-size of clone
var fontSize = $(this).css('font-size');
do {
fontSize = parseFloat($clone.css('font-size')) - step;
$clone.css({
'font-size': fontSize
});
} while ($clone.width() > $(this).width());
// Maintain input field size
$(this).css({
"width": $(this).width() + "px",
"height": $(this).height() + "px"
});
// Change input font-size
$(this).animate({
'font-size': fontSize
});
// Delete clone
$clone.remove();
} else {
// Default input field back to normal
$(this)
.finish()
.clearQueue()
.attr('style', function(i, style) {
// Remove inline style for font-size
return style.replace(/font-size[^;]+;?/g, '');
});
}
});
}, 100);
input,
.inputClone {
font-family: "Arial", Helvetica, sans-serif;
font-size: 14px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
<table border="1">
<tr>
<td>Traveler's name:</td>
<td>
<input type="text" id="travelername" placeholder="Last Name, First Name, Middle Initial" />
</td>
</tr>
<tr>
<td>Traveler's E-mail:</td>
<td>
<input type="email" id="traveleremail" />
</td>
</tr>
</table>
</form>