2

I wonder how can I use css/javascript to adjust the blinking cursor inside the search box with CSS?

enter image description here

Is it possible to replace default blinkig caret to horizontal blinking icon

Toastrackenigma
  • 7,604
  • 4
  • 45
  • 55
Tahir
  • 302
  • 3
  • 14
  • 1
    **No**. Many have tried and failed before you (including me). If you really want to pursue it (good luck), you'll need to a textbox with invisible text, a `div` underneath it which then updates to contain the text, and then another `div` styled the way you want the caret to look which moves as the user types and selects. Although, I think WebKit browsers can do it natively... – Toastrackenigma Jul 19 '17 at 08:02
  • 2
    Possible duplicate of [Styling text input caret](https://stackoverflow.com/questions/7339333/styling-text-input-caret) – Toastrackenigma Jul 19 '17 at 08:04
  • There is a CSS property to do that, but not supported yet: [`caret-shape`](https://www.w3.org/TR/css-ui-4/#caret-shape). – BarryCap Jul 16 '21 at 16:38

2 Answers2

5

I don't think it is so hard. I made a quick example, which works in most modern browsers except Safari. It draws the caret on a canvas, and sets it as a background of the input, on a position calculated from the browsers caret position.

It checks if the browser supports the caret-color css property, and if it doesn't it doesn't do anything, because both the system caret, and our caret will be visible in the same time. From the browsers I tested, only Safari doesn't support it.

$("input").on('change blur mouseup focus keydown keyup', function(evt) {
  var $el = $(evt.target);
  //check if the carret can be hidden
  //AFAIK from the modern mainstream browsers
  //only Safari doesn't support caret-color
  if (!$el.css("caret-color")) return;
  var caretIndex = $el[0].selectionStart;
  var textBeforeCarret = $el.val().substring(0, caretIndex);

  var bgr = getBackgroundStyle($el, textBeforeCarret);
  $el.css("background", bgr);
  clearInterval(window.blinkInterval);
  //just an examplethis should be in a module scope, not on window level
  window.blinkInterval = setInterval(blink, 600);
})

function blink() {
 
  $("input").each((index, el) => {
    var $el = $(el);
    if ($el.css("background-blend-mode") != "normal") {
      $el.css("background-blend-mode", "normal");
    } else {
      $el.css("background-blend-mode", "color-burn");
    }
  });
}


function getBackgroundStyle($el, text) {
  var fontSize = $el.css("font-size");
  var fontFamily = $el.css("font-family");

  var font = fontSize + " " + fontFamily;
  var canvas = $el.data("carretCanvas");
  //cache the canvas for performance reasons
  //it is a good idea to invalidate if the input size changes because of the browser text resize/zoom)
  if (canvas == null) {
    canvas = document.createElement("canvas");
    $el.data("carretCanvas", canvas);
    var ctx = canvas.getContext("2d");
    ctx.font = font;
    ctx.strokeStyle = $el.css("color");
    ctx.lineWidth = Math.ceil(parseInt(fontSize) / 5);
    ctx.beginPath();
    ctx.moveTo(0, 0);
    //aproximate width of the caret
    ctx.lineTo(parseInt(fontSize) / 2, 0);
    ctx.stroke();
  }
  var offsetLeft = canvas.getContext("2d").measureText(text).width + parseInt($el.css("padding-left"));
  return "#fff url(" + canvas.toDataURL() + ") no-repeat " +
    (offsetLeft - $el.scrollLeft()) + "px " +
    ($el.height() + parseInt($el.css("padding-top"))) + "px";
}
input {
  caret-color: transparent;
  padding: 3px;
  font-size: 15px;
  color: #2795EE;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" />

If there is interest, I can clean it a bit and wrap it in a jQuery plugin.

Edit: forgot about the blinking, so I added it. A better way will be to add it as css animation, in this case the caret should be in a separate html element positioned over the input.

Daniel Alexandrov
  • 1,299
  • 8
  • 13
0

Changing the color of the caret is supported by the latest standards. But not changing its width is not, which I think is a shame because it is a question of accessibility for vision-impaired people.

One approach for implementing such a change yourself is first trying to figure out what is the position the caret is blinking at, then overlaying it with an element that looks like the caret but is perhaps wider etc.

Here's an article on how to go about doing such a thing. It's a good article but the end-solution is kind of complicated as a whole. But see if it solves your problem:

https://medium.com/@jh3y/how-to-where-s-the-caret-getting-the-xy-position-of-the-caret-a24ba372990a

Here is perhaps a simpler explanation for how to find the care x-y position: How do I get the (x, y) pixel coordinates of the caret in text boxes?

Panu Logic
  • 2,193
  • 1
  • 17
  • 21