diff --git a/content/posts/2023.07.02.css-only-contenteditable-placeholder.md b/content/posts/2023.07.02.css-only-contenteditable-placeholder.md new file mode 100644 index 0000000..34279b2 --- /dev/null +++ b/content/posts/2023.07.02.css-only-contenteditable-placeholder.md @@ -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 + + +``` + +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 `
` 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.