2.4 KiB
title | date | toc | images | tags | ||
---|---|---|---|---|---|---|
CSS only placeholder for contenteditable elements | 2023-07-02T13:06:15-05:00 | false |
|
The HTML elements input
and textarea
include a placeholder
property. This
property puts a placeholder text, which then disappears once the user selects
the input and types something in. I'm sure you've seen a placeholder before, it
doesn't need much explanation.
But what if an input
or textarea
doesn't fit your needs? input
only allows
a single line of text. While textarea
does allow multiple lines, the height of
the text area is fixed. If you want it to expand as the user types, you need to
add javascript to resize it on the fly. But there is an alternative: you can use
a div
that is marked contenteditable
. Div's can resize based on their
contents, so this is an easy way to create a text area that resizes
automatically without any javascript.
But the downside to using an editable div is that basic functionality like
placeholder
doesn't exist. And if you duckduckgo this, you'll find a lot of
people working around the problem with javascript. While this is certainly
possible, I am trying to minimize the amount of javascript on this page. That's
the whole reason why I didn't use a textarea
in the first place! But I found a
way to add a placeholder to a contenteditable
span without javascript. Here it is:
<span contenteditable="true" data-placeholder="click on me and type"></span>
<style>
/* Add the placeholder text */
[data-placeholder]::before {
content: attr(data-placeholder);
/* Or whatever */
color: gray;
}
/* Hide the placeholder when selected, or when there is text inside */
[data-placeholder]:focus::before, [data-placeholder]:not(:empty)::before {
content: none;
}
</style>
And here what it looks like:
{{}}
{{}}This also works with a div
, but there is one caveat: If the user types
something into the div
then deletes it, the browser will leave a <br/>
in
the div
. This means the div
won't be empty, and the placeholder won't come
back. Boo! The same issue doesn't happen with a span
though, so use a span
that is set to display: block
instead.
Also, remember to not only rely on just the placeholder. Make sure to add labels to your inputs.