How to create a "placeholder" for DIV that act like textfield?
Asked Answered
S

4

32

Div don't have a placeholder attribute

<div id="editable" contentEditable="true"></div>

I want <Please your enter your Name> to show in DIV when the User backspace the whole text in the DIV, or no text on inside, How can I do it?

Sweat answered 5/6, 2013 at 13:33 Comment(5)
can you explain more on how can user 'backspace a div'?Crawler
sorry my fault, forget to code itSweat
javascript will be your friend in this situation!Maomaoism
can show me some example??Sweat
pure css and MUI placeholder example https://mcmap.net/q/158766/-placeholder-for-contenteditable-divImpassive
G
12

What I find in other answers is that when using :not(:focus) pseudo class, I have to click again in order to get the blinking cursor and be able to type. Such issue doesn't happen if I click on an area other than the placeholder.

My workaround is simply removing :not(:focus). Even though in this way the placeholder will still be there after I click on the editable div, I'm able to type no matter where in the div I click, and the placeholder disappears immediately after I type something.

BTW, I inspected YouTube's comment div implementation, seems they are doing the same thing, e.g. #contenteditable-root.yt-formatted-string[aria-label].yt-formatted-string:empty:before

.editableDiv1,
.editableDiv2 {
  border-bottom: 1px solid gray;
  outline: none;
  margin-top: 20px;
}

.editableDiv1[contentEditable="true"]:empty:not(:focus):before {
  content: attr(placeholder)
}

.editableDiv2[contentEditable="true"]:empty:before {
  content: attr(placeholder)
}
<div class="editableDiv1" contentEditable=true placeholder="If you click on this placeholder, you have to click again in order to get the blinking cursor and type..."></div>

<div class="editableDiv2" contentEditable=true placeholder="Click on placeholder is fine, it'll disappear after you type something..."></div>
Gimcrackery answered 11/7, 2020 at 19:10 Comment(0)
B
67

Here is a pure CSS only solution:-

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

Here, we basically select all contentEditable <divs> that are empty & blurred. We then create a pseudo element before the CSS selection (the editable div) and fix our placeholder text (specified the data-ph attribute) as its content.

If you are targeting old school CSS2 browsers, change all occurrences of data-ph to title
Correction.......the :empty selector is not supported in IE version 8 and earlier.

Bieber answered 21/8, 2013 at 22:20 Comment(6)
Thans man, I never thought u could do smth like this with pure css. Awesome !Abmho
Unconstructive comment: This is beautiful! Great job!Slander
how to keep placeholder even when the element is focused? without not(:focus) selector, the caret disappears or appears at wrong place.Barnaul
@boh, to keep placeholder even when the element is focused, do this: [contentEditable=true]:empty:before { content: attr(data-ph) }Knickers
This won't work if there is any character or white-space between the opening and the closing div tags.Serpentiform
I found if I click on the placeholder content, then I have to click the div again in order to get the cursor, otherwise I won't be able to enter anything; no this issue when I click on the div other than the placeholder area. (tested on Chrome 83.0.4103.116)Gimcrackery
G
12

What I find in other answers is that when using :not(:focus) pseudo class, I have to click again in order to get the blinking cursor and be able to type. Such issue doesn't happen if I click on an area other than the placeholder.

My workaround is simply removing :not(:focus). Even though in this way the placeholder will still be there after I click on the editable div, I'm able to type no matter where in the div I click, and the placeholder disappears immediately after I type something.

BTW, I inspected YouTube's comment div implementation, seems they are doing the same thing, e.g. #contenteditable-root.yt-formatted-string[aria-label].yt-formatted-string:empty:before

.editableDiv1,
.editableDiv2 {
  border-bottom: 1px solid gray;
  outline: none;
  margin-top: 20px;
}

.editableDiv1[contentEditable="true"]:empty:not(:focus):before {
  content: attr(placeholder)
}

.editableDiv2[contentEditable="true"]:empty:before {
  content: attr(placeholder)
}
<div class="editableDiv1" contentEditable=true placeholder="If you click on this placeholder, you have to click again in order to get the blinking cursor and type..."></div>

<div class="editableDiv2" contentEditable=true placeholder="Click on placeholder is fine, it'll disappear after you type something..."></div>
Gimcrackery answered 11/7, 2020 at 19:10 Comment(0)
D
8

You can try this one !

html:

<div contentEditable=true data-text="Enter name here"></div>

css:

[contentEditable=true]:empty:not(:focus):before{
content:attr(data-text) }

check it out (demo)

Dynamo answered 18/9, 2015 at 17:10 Comment(1)
how is that different from the first answer?Kamakura
F
-2

in HTML

<div id="editable" contenteditable="true">
    <p>Please your enter your Name</p>
</div>

in JavaScript

jQuery.fn.selectText = function(){
    var doc = document;
    var element = this[0];
    console.log(this, element);
    if (doc.body.createTextRange) {
        var range = document.body.createTextRange();
        range.moveToElementText(element);
        range.select();
    } else if (window.getSelection) {
        var selection = window.getSelection();        
        var range = document.createRange();
        range.selectNodeContents(element);
        selection.removeAllRanges();
        selection.addRange(range);
    }
};

$("#editable").click(function() {
    $("#editable").selectText();
});

jsFiddle

Farthing answered 7/8, 2013 at 13:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.