文本输入光标的样式设计

138
我希望能够样式化一个聚焦的<input type='text'/>元素的插入符号,特别是颜色和粗细。

1
好的,我猜这是针对 <input type="text"/> 的。 - Benjamin Crouzier
他正在寻找样式化插入符号,编辑问题和标签。 - Ben
3
请考虑更改已接受的答案。鉴于最新的CSS更改,Michael Jasper的更新答案明显更优秀:https://dev59.com/Z2s05IYBdhLWcg3wR_22#7339406 - Boaz
9个回答

109
“Caret”是你要找的词。我相信它是浏览器设计的一部分,而不是在CSS范围内。
然而,这里有一篇有趣的文章,介绍了如何使用Javascript和CSS模拟插入符号更改:http://www.dynamicdrive.com/forums/showthread.php?t=17450。对我来说,这似乎有点hacky,但可能是完成任务的唯一方法。该文章的主要观点是:
我们在屏幕上的某个地方有一个普通的文本区域,超出了查看者的视线,当用户单击我们的“假终端”时,我们将聚焦于文本区域,当用户开始输入时,我们将简单地将输入的数据附加到我们的“终端”,就这样。 这里是演示

2018更新

有一个新的CSS属性caret-color,适用于inputcontenteditable区域的插入符。支持正在增长,但不是100%,而且这只影响颜色,而不是宽度或其他类型的外观。

input{
  caret-color: rgb(0, 200, 0);
}
<input type="text"/>


1
这应该是被接受的答案,运行得很好 - 谢谢 :) - Sarah
有没有办法在“input”元素上设置自定义光标,或者唯一的解决方案是一个具有hackish特征的变通方法? - oldboy
2
还有caret-shape(我们可以设置auto | bar | block | underscore)和简写形式的caret。很遗憾,它们目前没有被任何人支持(甚至在Can I use上也不支持,这篇文章编写时)。 - BarryCap

76

如果您使用的是 Webkit 浏览器,可以按照下面的 CSS 代码片段更改插入符的颜色。我不确定是否可以使用 CSS 更改格式。


如果您使用的是 Webkit 浏览器,可以按照下面的 CSS 代码片段更改插入符的颜色。我不确定是否可以使用 CSS 更改格式。
input,
textarea {
    font-size: 24px;
    padding: 10px;
    
    color: red;
    text-shadow: 0px 0px 0px #000;
    -webkit-text-fill-color: transparent;
}

input::-webkit-input-placeholder,
textarea::-webkit-input-placeholder {
    color:
    text-shadow: none;
    -webkit-text-fill-color: initial;
}

这是一个例子:http://jsfiddle.net/8k1k0awb/


4
聪明的技巧,但是表情符号不起作用,因为它们只会被阴影填充。 - simbolo
嗯,在我的情况下(桌面版Chrome和FF),不需要使用阴影来产生效果 - 只需编辑输入框的text-fill-color即可。 - Velda

41

在CSS3中,现在有一种本地方法可以做到这一点,而不需要任何现有答案中建议的hack:caret-color属性

您可以对插入符号进行许多操作,如下所示。 它甚至可以进行动画处理

/* Keyword value */
caret-color: auto;
color: transparent;
color: currentColor;

/* <color> values */
caret-color: red;
caret-color: #5729e9;
caret-color: rgb(0, 200, 0);
caret-color: hsla(228, 4%, 24%, 0.8);

caret-color 属性支持 Firefox 55 和 Chrome 60。Safari Technical Preview 和 Opera 也提供支持(但 Edge 尚未支持)。您可以在此处查看当前的支持表格。


1
抢了我的风头。当然,这个属性目前只在Firefox中有效,并且要到2017年4月才会发布。请参见此页面 - SpyderScript

6
这里有一些您可能正在寻找的供应商。
::-webkit-input-placeholder {color: tomato}
::-moz-placeholder          {color: tomato;} /* Firefox 19+ */
:-moz-placeholder           {color: tomato;} /* Firefox 18- */
:-ms-input-placeholder      {color: tomato;}

您可以为不同状态设置样式,例如聚焦

:focus::-webkit-input-placeholder {color: transparent}
:focus::-moz-placeholder          {color: transparent}
:focus:-moz-placeholder           {color: transparent}
:focus:-ms-input-placeholder      {color: transparent}

您可以对其执行某些转换,例如:
::-VENDOR-input-placeholder       {text-indent: 0px;   transition: text-indent 0.3s ease;}
:focus::-VENDOR-input-placeholder  {text-indent: 500px; transition: text-indent 0.3s ease;}

6
这对于设置占位符文本的样式很有用,但它并不会为 OP 提到的闪烁插入符号设置样式。 - craig

4

只需将color属性与-webkit-text-fill-color一起使用即可:

    input {
        color: red; /* color of caret */
        -webkit-text-fill-color: black; /* color of text */
    }
<input type="text"/>

在WebKit浏览器中可用(但在iOS Safari中仍使用系统颜色作为插入符号的颜色),并且在Firefox中也可用。
-webkit-text-fill-color CSS属性指定文本字符的填充颜色。如果未设置此属性,则使用color属性的值。这里是MDN
因此,这意味着我们可以使用text-fill-color设置文本颜色,使用标准color属性设置插入符号的颜色。在不支持该属性的浏览器中,插入符号和文本具有相同的颜色 - 插入符号的颜色。

1

input{
  caret-color: rgb(0, 200, 0);
}
<input type="text"/>


0

我在尝试构建一个类似终端的网站时,发现目前还无法使用CSS改变光标的样式。

但是你可以像其他答案中所示,改变插入符的颜色。

然后,在经过将近3天的研究后,我从检查一个网站中得到了一个想法(抱歉,我不能提供链接)。

它在命令字符串中添加和删除了一个HTML span元素,并生成了一个块状光标,但如果你稍微懂一点CSS,就可以制作任何插入符。

我不建议在生产应用中使用这个方法。

这帮助我创建了一个类似于你在我的网站中看到的插入符。

你可以在这个repo中查看源代码。

总结:

假设您的文本是在 H 后面带有插入符号的 echo Hello。 那么代码可能是这样的。
<div>
  <span>
    echo H
  </span>
  <span class="animate-blink" >  <!-- This span will act as your caret -->
    e
  </span>
  <span>
    llo
  </span>
</div>

希望它有所帮助 ;-)

0

很简单。 只需像这样添加caret-color属性:

* {cursor: url(http://labs.semplice.com/wp-content/uploads/2020/02/custom-cursor-arrow.png) 20 20, auto;}
input, div {padding: 20px;}
<input style="caret-color: rgb(0, 200, 0);">

<br>
<textarea style="caret-color: blue;"></textarea>

<br>
<div contenteditable style="padding: 5px; border: 1px solid black;border-color: black;caret-color: red"></div>


0

您可以使用一些技巧来“样式化”插入符号输入... 在这个例子中,插入符号被“替换”为一个带有平滑动画效果的 div,就像 MSWindows 的 Office 中一样。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
</head>
<body>
    <script>
        function getCaretCoordinates() {
            let x = 0,
            y = 0;
            const isSupported = typeof window.getSelection !== "undefined";
            if (isSupported) {
                const selection = window.getSelection();
                if (selection.rangeCount !== 0) {
                    const range = selection.getRangeAt(0).cloneRange();
                    range.collapse(true);
                    const rect = range.getClientRects()[0];
                    if (rect) {
        x = rect.left; 
        y = rect.top;
    }
}
}
return { x, y };
}

function getCaretIndex(element) {
    let position = 0;
    const isSupported = typeof window.getSelection !== "undefined";
    if (isSupported) {
        const selection = window.getSelection();
        if (selection.rangeCount !== 0) {
            const range = window.getSelection().getRangeAt(0);
            const preCaretRange = range.cloneRange();
            preCaretRange.selectNodeContents(element);
            preCaretRange.setEnd(range.endContainer, range.endOffset);
            position = preCaretRange.toString().length;
        }

    }
    return position;
}




$(document).ready(function(){
    $("#cc").hide();

    $(".texto").on("click keydown keypress keyup", function(e) {
        $("#cc").hide();
        var posX = getCaretCoordinates().x;
        var posY = getCaretCoordinates().y;
        var arregloX = posX + 1;
        if (posX > 1 || posY > 1) {
            $("#cc").show().css({
                top: posY + "px",
                left: arregloX + "px",
            });
        } else {
            $("#cc").hide();
        }
        
    }).on("blur", function(e) {
        $("#cc").hide();
    });

});
</script>



<div class="texto" contenteditable="true" style="font-size: 16px; caret-color: transparent; border: 1px #323232 solid; border-radius: 8px; padding: 20px; line-height: 1.2;">
    
    Hello World! Press here and test to Write!

</div>

<div class="texto" contenteditable="true" style="margin-top: 20px;font-size: 16px; caret-color: transparent; border: 1px #323232 solid; border-radius: 8px; padding: 20px; line-height: 1.2;">
    
    Hello World! Press here and test to Write!

</div>
<div id="cc"></div>
<style>
    #cc {
        width: 2px; height: 16px; background: #282828; position: absolute; top: 0; left: 0; transition: 100ms;
         transition-timing-function: ease-out;
          display: inline; border-radius: 8px;
         animation-duration: 500ms;
  animation-name: parpadear;
  animation-iteration-count: infinite;
  animation-direction: alternate;

    }
@keyframes parpadear {
  from {
    opacity: 1;
  }

  to {
    opacity: 0;
  }
}
</style>

</body>
</html>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接