JSFiddle - React, Tailwind, and code Playground

by Carlos Oropesa

HTML

<h3>Only in firefox</h3>

<h4>Trouble 1: placeholder in before with position relative</h4>
<p>If you click several times inside the div (not on the placeholder-text), the cursor change between the left and right part of the div (and still focused). When the cursor is on the right, typing doesn't work.</p>
<div class="content-editable placeholder-relative" contenteditable="true" placeholder="Type something here..."></div>

<h4>Trouble 2: placeholder in before with position absolute</h4>
<p>When the div is focus and empty, the cursor ignores the padding of the div. And if you click on the text the focus event is ignored.</p>
<div class="content-editable placeholder-absolute" contenteditable="true" placeholder="Type something here..."></div>

<h4>Solution:</h4>
<p>Don't use <i>:before</i> and simulate the placeholder (see the <i>html</i> and <i>css</i> code).</p>
<div class="content-wrapper">
    <div class="content-editable with-ghost" contenteditable="true" placeholder="Type something here..."></div>
    <div class="ghost-placeholder">Type something here...</div>
</div>

<h4>Another trouble (more? damn firefox...)</h4>
<p>In all cases, when you write and remove all the text, the content-editable div isn't empty, inside it has <i>&lt;br&gt;&lt;br&gt;</i>, so if you want to show the placeholder you have to remove this rubbish with javascript (on the <i>blur</i> event).</p>

<p>Good luck! =)</p>

CSS

/* halara style-reset */
* { margin: 0; padding: 0; } body { margin: 1rem; background: #dfeaff; } h4 { margin: 1rem 0 0} p { font-size: .8em; color: darkgray; margin: .5rem 0 1rem; }

/* default content style */
.content-editable {
    min-height: 1.5rem;
    max-height: 4rem;
    padding: 1.5rem;
    background: white;
    border: 1px solid #bdc3c7;
}
.content-editable:focus { border-color: #3498db; outline: 0 }

/* specific content style, troubles 1 & 2 */
.content-editable.placeholder-relative:empty:before { position: relative; }
.content-editable.placeholder-absolute:empty:before { position: absolute; }

.content-editable.placeholder-relative:empty:before,
.content-editable.placeholder-absolute:empty:before {
    content: attr(placeholder);
    color: #bdc3c7;
}

.content-editable.placeholder-relative:focus:empty:before,
.content-editable.placeholder-absolute:focus:empty:before {
   color: #3498db;
   opacity: .5
}

/* solution style */
.content-wrapper {
   position: relative;
   background: white;
 }
 
.content-editable.with-ghost {
   position: relative;
   background: transparent;
   z-index: 1;
}

.ghost-placeholder {
   position: absolute;
   display: none;
   z-index: 0;
   top: 1.5rem; /*as padding*/
   left: 1.5rem; /*as padding*/
   color: #bdc3c7;
}

.content-editable.with-ghost:empty + .ghost-placeholder {
   display: block;
}