selectionStart でキャレットの位置を取得する

selectionStartを使う。

selectionStart - Mozilla | MDN

イベントと組み合わせて使う。

イベント DOM API 結果
keydown selectionStart 直前の位置を取得
keyup selectionStart 直前の位置を取得

jQuery だとこう。

$('input.selector').on('keyup', function(e) {
  // カーソル位置取得
  var cursorPosition = this.selectionStart;

  //ひとつ右にずらす
  cursorPosition++;

  // カーソル位置セットする
  $(this).focus().get(0).setSelectionRange(cursorPosition, cursorPosition);

}).change();

改行によるスペースを非表示にする方法

親要素にfont-size: 0; を指定する方法がいちばんスマート。
Android2.3 のようなゴミでありながら化石と化した端末はスルー。
でもいちいちCSSでfont-size 指定するのもあれだからコンセンサスが取れていれば他のやり方でもいい。

詳細

改行しない

ソースが見づらくなるという欠点を除けばどのデバイスでも動作する。

  <div class="wrapper">
    <span>aaa</span><span>bbb</span><span>ccc</span>
  </div>

タグの中で改行する

見づらい以上の不快感ある。

  <div class="wrapper">
    <span>aaa</span
    ><span>bbb</span
    ><span>ccc</span>
  </div>

改行をコメントアウトする

意図を知らない人には伝わりづらい

  <div class="wrapper">
    <span>aaa</span><!--
    --><span>bbb</span><!--  
    --><span>ccc</span>
  </div>

親要素にfont-size: 0; を指定する

CSSに明示的に指定するので意図をソースから判断できる。
子要素にもfont-sizeを指定しなければいけない。
Android2.3でfont-size: 0;が効かない | cly7796.net

#css
.wrapper {
  font-size: 0;
}
.child {
  font-size: 1.0rem;
}
  <div class="wrapper">
    <span class="child">aaa</span>
    <span class="child">bbb</span>
    <span class="child">ccc</span>
  </div>

参考