Add "CSS only placeholder for contenteditable elements" post
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
This commit is contained in:
parent
d0527f7d0c
commit
db46e25ed7
|
@ -0,0 +1,60 @@
|
|||
---
|
||||
title: "CSS only placeholder for contenteditable elements"
|
||||
date: 2023-07-02T13:06:15-05:00
|
||||
toc: false
|
||||
images:
|
||||
tags:
|
||||
- dev
|
||||
- web
|
||||
---
|
||||
|
||||
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:
|
||||
|
||||
```html
|
||||
<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:
|
||||
|
||||
{{<raw>}}
|
||||
<iframe width="100%" height="300" src="//jsfiddle.net/SeriousBug/t9hmgyq5/13/embedded/result,html,css/" allowfullscreen="allowfullscreen" allowpaymentrequest frameborder="0"></iframe>
|
||||
{{</raw>}}
|
||||
|
||||
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.
|
Loading…
Reference in a new issue