Centering the placeholder caret in contentEditable

2019-06-15 17:01发布

问题:

I have the following: http://jsfiddle.net/mb76koj3/.

[contentEditable=true]:empty::before{
  content:attr(data-ph);
  color: #CCC;
  text-align: center;
}

h1 {
  text-align: center;
}
<h1 contenteditable="true" data-ph="Name"></h1>

The problem is the <h1> is centered, but the placeholder caret isn't centered (until you start typing). The caret is on the left side, how can I change this?

回答1:

Not an ideal solution but we can fake the effect by applying a padding-left of 50% to the :empty element to make the cursor appear at the middle.

And then align the placeholder (the pseudo-element) at the middle by using absolute positioning and a negative value of translateX transform function.

* {
  margin: 0;
  padding: 0;
}

@-moz-document url-prefix() { /* CSS Hack to fix the position of cursor on FF */
  [contentEditable=true]:empty {
    padding-top: 1em;
    padding-bottom: .25em;
    -moz-box-sizing: content-box;
  }
}

[contentEditable=true]:empty {
  padding-left: 50%;
  text-align: left; /* Fix the issue on IE */
}

[contentEditable=true]:empty::before{
  content:attr(data-ph);
  color: #CCC;
  position: absolute;
  top: 0;
  left: 50%;
  -webkit-transform: translateX(-50%);
  -moz-transform:  translateX(-50%);
  -ms-transform:  translateX(-50%);
  -o-transform:  translateX(-50%);
  transform:  translateX(-50%);
}

h1 {
  text-align: center;
  position: relative;
}
<h1 contenteditable="true" data-ph="Name"></h1>

The only problem that remains — as can be seen in the OP's provided code — is that on Firefox, an empty <br> element is appended to contentEditable elements which causes :empty pseudo-class not matching the element anymore. Hence the placeholder won't be restored.

However since the question is about the position of the cursor, I assume this behavior is just fine for the OP.



回答2:

After looking at Hashem Qolami's answer, I came up with this:

[contentEditable=true]:empty {
    padding-left: 50%;
}

[contentEditable=true]:empty::before{
    content:attr(data-ph);
    color: #CCC;
    text-align: center;
    margin-left: -100%;
}

h1 {
    text-align: center;
}
<h1 contenteditable="true" data-ph="Name"></h1>

However, adamdc78 discovered 2 problems:

  • In IE11, the cursor appears after the placeholder.
  • In Firefox, the placeholder is not restored after typing and emptying.

At this time, I can't figure out how to solve that.