Rectangle 27 27

It uses a combination of CSS3 and JavaScript to show the placeholder without adding to the content of the div:

<div contenteditable='true' data-placeholder='Enter some text'></div>
div[data-placeholder]:not(:focus):not([data-div-placeholder-content]):before {
    content: attr(data-placeholder);
    float: left;
    margin-left: 5px;
    color: gray;
}
(function ($) {
    $('div[data-placeholder]').on('keydown keypress input', function() {
        if (this.textContent) {
            this.dataset.divPlaceholderContent = 'true';
        }
        else {
            delete(this.dataset.divPlaceholderContent);
        }
    });
})(jQuery);

NB: Since I wrote this answer, I've updated the plugin for IE compatibility and non-div elements. See the linked GitHub repo for the latest version.

Does it work if I am setting div text from backend? In my case placeholder and my text are concated

javascript - Placeholder in contenteditable - focus event issue - Stac...

javascript jquery focus contenteditable caret
Rectangle 27 20

span.spanclass:empty:before {content:"placeholder";}

This works like a charm.

Works just like the native placeholder behavior, perfect!

javascript - Placeholder in contenteditable - focus event issue - Stac...

javascript jquery focus contenteditable caret
Rectangle 27 8

I found that the best way to do this is to use the placeholder attribute like usual and add a few lines of CSS.

<div contenteditable placeholder="I am a placeholder"></div>
[contenteditable][placeholder]:empty:before {
    content: attr(placeholder);
    color: #bababa;
}

Note: the CSS :empty selector only works if there is literally nothing in-between the opening and closing tag. This includes new lines, tabs, empty space, etc.

This solution has an issue in FF. on near right side border if you click twice, cursor hangs there.

javascript - Placeholder in contenteditable - focus event issue - Stac...

javascript jquery focus contenteditable caret
Rectangle 27 149

Here is a CSS only solution augmenting some of the other answers:-

<div contentEditable=true data-ph="My Placeholder String"></div>
<style>
    [contentEditable=true]:empty:not(:focus)::before{
        content:attr(data-ph)
    }
</style>

EDIT2: Be advised, this method doesn't work 100% for multi-line applications due to residual <br> elements being present in the div after performing a select-all-cut or select-all-delete on all lines. Credits:- @vsync Backspace seems to work fine (at least on webkit/blink)

This would be exceptionally cool, except... can't get it to work. Can you post a working jsfiddle?

This should be the accepted answer. It's a little more complicated than the one from @amwinter but it keeps the placeholder in the html instead of the css.

True! Another advantage of the complexity tradeoff is that if you have multiple contentEditable elements, all you have to do is specify a data-ph placeholder for each and the same CSS code takes care of all of them.

This is NOT the answer, this fails and is unreliable. Try writing 2 lines text, then select all and delete. there will still be some junk HTML inside the contentEditable, which will prevent the :empty from being triggered. fail.

You're right @vsync! That's a very good find. Thank you for sharing.

javascript - Placeholder in contenteditable - focus event issue - Stac...

javascript jquery focus contenteditable caret
Rectangle 27 23

You may need to manually update the selection. In IE, the focus event is too late, so I would suggest using the activate event instead. Here's some code that does the job in all major browsers, including IE <= 8 (which a CSS-only alternative will not):

$('div').on('activate', function() {
    $(this).empty();
    var range, sel;
    if ( (sel = document.selection) && document.body.createTextRange) {
        range = document.body.createTextRange();
        range.moveToElementText(this);
        range.select();
    }
});

$('div').focus(function() {
    if (this.hasChildNodes() && document.createRange && window.getSelection) {
        $(this).empty();
        var range = document.createRange();
        range.selectNodeContents(this);
        var sel = window.getSelection();
        sel.removeAllRanges();
        sel.addRange(range);
    }
});

Another +1 for the RangeMaster. I thought by keeping it simple I'd be avoiding the cross browser issues, but that was rather naive of me.

Ive been banging my head the last two days on this one, trying all kinds of quirks. I was even adding an absolute positioned placeholder at the back of my head, so this solution is simple enough for me! I agree though, there should be a simpler solution...

Awesome! You saved me a lot of headaches :)

javascript - Placeholder in contenteditable - focus event issue - Stac...

javascript jquery focus contenteditable caret
Rectangle 27 6

All you need is this little solution

[contenteditable=true]:empty:before{
  content: attr(placeholder);
  display: block; /* For Firefox */
}

Works. Tested in firefox, chrome, and Safari.

javascript - Placeholder in contenteditable - focus event issue - Stac...

javascript jquery focus contenteditable caret
Rectangle 27 4

Works exactly like the html5 placeholder attribute!

  • Hides itself right away when you input the first letter
  • Shows itself again when you delete what you input into it
<div class="placeholder" contenteditable="true"></div>
.placeholder:after {
    content: "Your placeholder"; /* this is where you assign the place holder */
    position: absolute;
    top: 10px;
    color: #a9a9a9;
}
$('.placeholder').on('input', function(){
    if ($(this).text().length > 0) {
        $(this).removeClass('placeholder');
    } else {
        $(this).addClass('placeholder');
    }
});
input

javascript - Placeholder in contenteditable - focus event issue - Stac...

javascript jquery focus contenteditable caret
Rectangle 27 1

Here's the fix that I used.

<div contenteditable><em>Edit me</em></div>
<script>
$('div').focus(function() {
    var target = $(this);
    window.setTimeout(function() { target.empty(); }, 10);
});
</script>

javascript - Placeholder in contenteditable - focus event issue - Stac...

javascript jquery focus contenteditable caret
Rectangle 27 0

span.spanclass:empty:before {content:"placeholder";}

This works like a charm.

javascript - Placeholder in contenteditable - focus event issue - Stac...

javascript jquery focus contenteditable caret
Rectangle 27 0

It uses a combination of CSS3 and JavaScript to show the placeholder without adding to the content of the div:

<div contenteditable='true' data-placeholder='Enter some text'></div>
div[data-placeholder]:not(:focus):not([data-div-placeholder-content]):before {
    content: attr(data-placeholder);
    float: left;
    margin-left: 5px;
    color: gray;
}
(function ($) {
    $('div[data-placeholder]').on('keydown keypress input', function() {
        if (this.textContent) {
            this.dataset.divPlaceholderContent = 'true';
        }
        else {
            delete(this.dataset.divPlaceholderContent);
        }
    });
})(jQuery);

NB: Since I wrote this answer, I've updated the plugin for IE compatibility and non-div elements. See the linked GitHub repo for the latest version.

javascript - Placeholder in contenteditable - focus event issue - Stac...

javascript jquery focus contenteditable caret
Rectangle 27 0

change your html a bit then use the below css:use placeholder instead of data-placeholder i.e. without data attribute.

input,div {
    border: 1px black solid;
    margin-top: 20px;
}

[contenteditable=true]:empty:before {
  content: attr(placeholder);
}
<input placeholder="test"/>
<div contenteditable='true' placeholder="test"></div>

javascript - ContentEditable Placeholder Issue - Stack Overflow

javascript jquery html css
Rectangle 27 0

if this expression returns true, the element seems to be empty.

Thanks for the answer. That is indeed a nice way to do it. Unfortunately my interpretation of the code was wrong. The placeholder is not getting saved into the database. But when you switch from author view to student view, the page is not being rendered again, thus keeping the placeholder in the div. I need to make some changing in the switch view statement. But thanks anyway :)

javascript - Contenteditable placeholder needs to be empty when saved ...

javascript angularjs
Rectangle 27 0

It feels like I am repeating myself, but why not to check contenteditable element mutations? Trying to bind everything to event that are changing content are pain in the butt. What if You need to add button (For example paste), or change content dynamically (javascript). My approach would be using MutationObservers. Demo fiddle

<div class="test" id="test" placeholder="Type something..." contenteditable="true"></div>
.test {
    width: 500px;
    height: 70px;
    background: #f5f5f5;
    border: 1px solid #ddd;
    padding: 5px;
}

.test[placeholder]:empty:before {
    content: attr(placeholder);
    color: #555; 
}
var target = document.querySelector('#test');
var observer = new MutationObserver(function(mutations) {
  mutations.forEach(function(mutation) {
      if (target.textContent == '') {
          target.innerHTML = '';
      }
  });    
});
var config = { attributes: true, childList: true, characterData: true };
observer.observe(target, config);

javascript - Placeholder for contenteditable div - Stack Overflow

javascript jquery html css
Rectangle 27 0

I have a workaround for this Issue.

.title {
   width: 500px;
   margin: 0 25%;
}

javascript - How to place cursor position at the start of center align...

javascript jquery html css placeholder
Rectangle 27 0

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.

javascript - Centering the placeholder caret in contentEditable elemen...

javascript html css contenteditable
Rectangle 27 0

All you need is to add the following CSS:

[contenteditable=true]:empty:before {
  content: attr(placeholder);
  display: block; /* For Firefox */
}
/* General Styling for Demo only */
div[contenteditable=true] {
  border: 1px dashed #AAA;
  width: 290px;
  padding: 5px;
}
pre {
  background: #EEE;
  padding: 5px;
  width: 290px;
}
<h3>Placeholder support for contentEditable elements,<br>without JavaScript!</h3> 

<h5>Demo:</h5>
<div contenteditable="true" placeholder="Enter text here..."></div>

<p>All you need is to add the following CSS:</p>
<pre>
[contenteditable=true]:empty:before {
  content: attr(placeholder);
  display: block; /* For Firefox */
}
</pre>

<h5>Notes</h5>
<ul>
  <li>Can add a different style than actual text like opacity, italic, etc</li>
  <li>If your html needs to be 100% compliant, you can replace "placeholder" for "data-placeholder" on both files</li>
  <li>Chrome will add &lt;br />'s inside contentEditable elements in some cases, breaking the :empty check. Can be fixed with a bit of JavaScript.</li>
</ul>

<i>By Ariel Flesler</i>

@infinity Sorry, I linked you to the wrong Fiddle. Please see the new one. jsfiddle.net/d5ep3eLw/1

javascript - ContentEditable Placeholder Issue - Stack Overflow

javascript jquery html css
Rectangle 27 0

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.

javascript - Centering the placeholder caret in contentEditable elemen...

javascript html css contenteditable
Rectangle 27 0

I found that the best way to do this is to use the placeholder attribute like usual and add a few lines of CSS.

<div contenteditable placeholder="I am a placeholder"></div>
[contenteditable][placeholder]:empty:before {
    content: attr(placeholder);
    color: #bababa;
}

Note: the CSS :empty selector only works if there is literally nothing in-between the opening and closing tag. This includes new lines, tabs, empty space, etc.

javascript - Placeholder in contenteditable - focus event issue - Stac...

javascript jquery focus contenteditable caret
Rectangle 27 0

Here's the fix that I used.

<div contenteditable><em>Edit me</em></div>
<script>
$('div').focus(function() {
    var target = $(this);
    window.setTimeout(function() { target.empty(); }, 10);
});
</script>

javascript - Placeholder in contenteditable - focus event issue - Stac...

javascript jquery focus contenteditable caret
Rectangle 27 0

While searching for the same problem i worked out a simple mixed css-javascript solution i'd like to share:

.test[placeholder]:empty:focus:before {
    content: "";
}
jQuery(function($){
    $(".test").focusout(function(){
        var element = $(this);        
        if (!element.text().trim().length) {
            element.empty();
        }
    });
});

How to get the placeholder when my page onload? It's working perfectly, but it's comming after I typed something and erased everything in the input field.

Perhaps your element is not empty? The code above only filters whitespaces, not, say, line breaks.

Sign up for our newsletter and get our top new questions delivered to your inbox (see an example).

javascript - Placeholder for contenteditable div - Stack Overflow

javascript jquery html css