Placeholder in contenteditable - focus event issue
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>
EDIT: Here is my snippet on codepen -> http://codepen.io/mrmoje/pen/lkLez
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)
I've just published a plugin for this.
It uses a combination of CSS3 and JavaScript to show the placeholder without adding to the content of the div
:
HTML:
<div contenteditable='true' data-placeholder='Enter some text'></div>
CSS:
div[data-placeholder]:not(:focus):not([data-div-placeholder-content]):before { content: attr(data-placeholder); float: left; margin-left: 5px; color: gray;}
JS:
(function ($) { $('div[data-placeholder]').on('keydown keypress input', function() { if (this.textContent) { this.dataset.divPlaceholderContent = 'true'; } else { delete(this.dataset.divPlaceholderContent); } });})(jQuery);
And that's it.
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):
Live demo: http://jsfiddle.net/hHLXr/12/
Code:
$('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); }});