Quill: Placeholder text overflows editor

Created on 26 Nov 2018  路  6Comments  路  Source: quilljs/quill

When the height of the placeholdertext i larger than the editor it just overflows out the bottom.

Steps for Reproduction

  1. Visit https://codepen.io/hoffmeyer/pen/JeZQLZ

Expected behavior:
The editor should expand to contain the placeholder text

Actual behavior:
The placholder text flows out of the editor area.

Platforms:
Tested on Windows 10 and Linux in Chrome 70

Version:
1.3.6

Most helpful comment

I like the solution by @ajmueller - although I might suggest a slight change. If you use this method, you'll find that the actual content of the editor will be pushed down by the now statically positioned placeholder ::before pseudo element - and so this gives the awkward behavior of the cursor being _underneath_ the placeholder.

Hopefully this might help someone else if they run into this issue:

The simplest fix that you could employ without this being a PR to Quill would be to do the following in your own codebase:

.ql-editor.ql-blank::before {
  content: none;
}

.ql-editor.ql-blank::after {
  color: rgba(0,0,0,0.6);
  content: attr(data-placeholder);
  font-style: italic;
  pointer-events: none;
  display: block;
  margin-top: -1.42rem;
}

The ::after pseudo element is just using the base styles already defined on the ::before pseudo element, without the position: relative left and right rules.

All 6 comments

The placeholder should normally be few words long.
You can give the editor min-height:

.ql-editor {
  min-height: 200px;
}

@hoffmeyer I just ran into this issue myself and wanted a fix that wasn't min-height related; that's not a truly dynamic solution because you need to know the length of your placeholder and the resolution of the device. The main issue lies with the absolute position of the before pseudo element. My fix was as follows:

.ql-editor.ql-blank::before {
  display: block;  /* needed to allow for the below margin */
  margin-bottom: -1.42em; /* pulls content below the placeholder up to match the position: absolute behavior where content is on the same line as the placeholder; 1.42 matches the line-height of the editor */
  position: static;
}

It looks like the offending code is here. I'd be happy to open up a PR to fix this, @benbro, if it's a fix that the core team is okay with. The behavior isn't perfect since multi-line placeholder text only pulls the cursor up one line, but the placeholder does wrap and the editor adjusts to its content.

I like the solution by @ajmueller - although I might suggest a slight change. If you use this method, you'll find that the actual content of the editor will be pushed down by the now statically positioned placeholder ::before pseudo element - and so this gives the awkward behavior of the cursor being _underneath_ the placeholder.

Hopefully this might help someone else if they run into this issue:

The simplest fix that you could employ without this being a PR to Quill would be to do the following in your own codebase:

.ql-editor.ql-blank::before {
  content: none;
}

.ql-editor.ql-blank::after {
  color: rgba(0,0,0,0.6);
  content: attr(data-placeholder);
  font-style: italic;
  pointer-events: none;
  display: block;
  margin-top: -1.42rem;
}

The ::after pseudo element is just using the base styles already defined on the ::before pseudo element, without the position: relative left and right rules.

@jesselloyd awesome solution! This worked wonderfully, except I changed the -1.42rem to -1.42em to get the cursor placement perfect (and keep it relative to the font-size of the Quill editor).

Good point! Thanks for catching that. I forgot to switch the units, that'll do it!

@jesselloyd one more minor tweak that I've found is necessary is to add a fallback for the content property. So the entire snippet is:

.ql-editor.ql-blank::before {
    content: none;
}

.ql-editor.ql-blank::after {
    color: rgba(0, 0, 0, 0.6);
    content: attr(data-placeholder, '');
    display: block;
    font-style: italic;
    margin-top: -1.42em;
    pointer-events: none;
}

Without this, Chrome renders the initial state of the editor like so:

image

Adding this fallback fixes the initial render:

image

Evidently Chrome doesn't like pseudo elements with content pointing to non-existent attributes. Firefox renders it fine either way.

EDIT I should have read the MDN docs more carefully. Fallbacks are experimental and not yet supported by browsers. Someday this will fix the problem! In the meantime, a slightly more hacky min-height addition will fix it:

.ql-editor.ql-blank::before {
    content: none;
}

.ql-editor.ql-blank::after {
    color: rgba(0, 0, 0, 0.6);
    content: attr(data-placeholder);
    display: block;
    font-style: italic;
    margin-top: -1.42em;
    min-height: 1em;
    pointer-events: none;
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

emanuelbsilva picture emanuelbsilva  路  3Comments

benbro picture benbro  路  3Comments

markstewie picture markstewie  路  3Comments

Yves-K picture Yves-K  路  3Comments

visore picture visore  路  3Comments