138

I want to style the caret of a focused <input type='text'/>. Specifically, the color and thickness.

Velda
  • 587
  • 2
  • 5
  • 21
Randomblue
  • 112,777
  • 145
  • 353
  • 547

9 Answers9

109

'Caret' is the word you are looking for. I do believe though, that it is part of the browsers design, and not within the grasp of css.

However, here is an interesting write up on simulating a caret change using Javascript and CSS http://www.dynamicdrive.com/forums/showthread.php?t=17450 It seems a bit hacky to me, but probably the only way to accomplish the task. The main point of the article is:

We will have a plain textarea somewhere in the screen out of the view of the viewer and when the user clicks on our "fake terminal" we will focus into the textarea and when the user starts typing we will simply append the data typed into the textarea to our "terminal" and that's that.

HERE is a demo in action


2018 update

There is a new css property caret-color which applies to the caret of an input or contenteditable area. The support is growing but not 100%, and this only affects color, not width or other types of appearance.

input{
  caret-color: rgb(0, 200, 0);
}
<input type="text"/>
Michael Jasper
  • 7,962
  • 4
  • 40
  • 60
  • 1
    This should be the accepted answer, works like a charm - Thanks :) – Sarah Sep 08 '20 at 06:30
  • is there any way to set a custom cursor on `input` elements or is the only solution a hackish workaround? – oldboy Oct 14 '20 at 08:47
  • 2
    There is also [`caret-shape`](https://www.w3.org/TR/2021/WD-css-ui-4-20210316/#caret-shape) (where we can set `auto | bar | block | underscore`) and the shorthand [`caret`](https://www.w3.org/TR/2021/WD-css-ui-4-20210316/#caret). Too bad that they are currently [supported by no one](https://css-tricks.com/almanac/properties/c/caret-shape/#browser-support) (no even on [Can I use](https://caniuse.com/css-caret-shape) at the time this is written) – BarryCap Jul 16 '21 at 15:46
76

If you are using a webkit browser you can change the color of the caret by following the next CSS snippet. I'm not sure if It's possible to change the format with 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;
}

Here is an example: http://jsfiddle.net/8k1k0awb/

Nestor Britez
  • 1,218
  • 10
  • 14
  • 4
    A clever hack, but emoji don't work as they just become filled in by the shadow – simbolo Jun 30 '16 at 13:28
  • Hmm, shades isn't needed for effect in my case (desktop Chrome and FF) – just edit text-fill-color of then input. – Velda Sep 18 '17 at 13:50
41

In CSS3, there is now a native way to do this, without any of the hacks suggested in the existing answers: the caret-color property.

There are a lot of things you can do to with the caret, as seen below. It can even be animated.

/* 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);

The caret-color property is supported from Firefox 55, and Chrome 60. Support is also available in the Safari Technical Preview and in Opera (but not yet in Edge). You can view the current support tables here.

Toastrackenigma
  • 7,604
  • 4
  • 45
  • 55
Sacha Nacar
  • 2,308
  • 20
  • 14
  • 1
    Beat me to the punch. Of course, this property will only work in Firefox, at least for now, and doesn't release until April 2017. See [this](https://developer.mozilla.org/en-US/Firefox/Releases/53#Changes_for_Web_developers) page. – swinn Feb 25 '17 at 22:23
6

Here are some vendors you might me looking for

::-webkit-input-placeholder {color: tomato}
::-moz-placeholder          {color: tomato;} /* Firefox 19+ */
:-moz-placeholder           {color: tomato;} /* Firefox 18- */
:-ms-input-placeholder      {color: tomato;}

You can also style different states, such as focus

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

You can also do certain transitions on it, like

::-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;}
Armen Michaeli
  • 8,625
  • 8
  • 58
  • 95
Sergey Khmelevskoy
  • 2,429
  • 3
  • 19
  • 43
  • 6
    This is useful for styling the placholder text, however it doesn't style the blinking caret the OP referenced. – craig Apr 03 '17 at 13:30
4

It is enough to use color property alongside with -webkit-text-fill-color this way:

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

Works in WebKit browsers (but not in iOS Safari, where is still used system color for caret) and also in Firefox.

The -webkit-text-fill-color CSS property specifies the fill color of characters of text. If this property is not set, the value of the color property is used. MDN

So this means we set text color with text-fill-color and caret color with standard color property. In unsupported browser, caret and text will have same color – color of the caret.

Velda
  • 587
  • 2
  • 5
  • 21
1

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

it is simple. Just add the caret-color attribute like this:

* {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>
Tiago Rangel
  • 1,159
  • 15
  • 29
0

While I was trying to build a terminal like website i got to know that there is no way (yet) to change the style of the cursor using CSS.

But you can change the caret-color as shown in the other answer.

Then, after almost 3 days of research I got an Idea from inspecting a website (sorry, I can't provide the link)

It adds and removes a HTML span element in the command string and makes a block cursor but you can make any caret if you know the caret's position with a little bit of CSS.

I don't recommend this for a production application.

This helped me create a caret like you see in my site

You can see the source in this repo

Summary:

suppose your text is echo Hello with caret after H. Then the code might be something like

<div>
  <span>
    echo H
  </span>
  <span class="animate-blink" >  <!-- This span will act as your caret -->
    e
  </span>
  <span>
    llo
  </span>
</div>

Hope it helps ;-)

Lee Goddard
  • 10,680
  • 4
  • 46
  • 63
0

You can "style" the caret input with some hack tweaks... in this example the caret is "replaced" with a div animated with smooth movement, like in Office for MSWindows

<!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>
SDanielCH
  • 1
  • 1