- From: Jussi Kalliokoski <jussi.kalliokoski@gmail.com>
- Date: Thu, 30 Aug 2012 11:44:46 +0300
- To: Ian Hickson <ian@hixie.ch>
- Cc: whatwg@lists.whatwg.org, Aryeh Gregor <ayg@aryeh.name>
On Thu, Aug 30, 2012 at 11:43 AM, Jussi Kalliokoski < jussi.kalliokoski@gmail.com> wrote: > It's pretty simple to make a naive placeholder for contenteditable > elements with CSS: > > [contenteditable]:not(:focus):empty::after { > content: attr(data-placeholder); > color: #ccc; > } > > I call it a bit naive because it turns out that if you have insert a line > break in the box, there will always be one line break inside the element > (even if you clean it empty), making the element non-empty and hence the > placeholder won't show. > > You can try it in action here: > file:///home/jussi/code/contenteditable/index.html > Whoooops, yeah, I'm pretty sure that won't work, try this instead: http://labs.avd.io/contenteditable/ > > Cheers, > Jussi > > P.S. The trick is courtesy of my colleague Nick Markwell ( > https://duckinator.net/ ) so if you want to thank someone for it, thank > him. > > > On Thu, Aug 30, 2012 at 2:27 AM, Ian Hickson <ian@hixie.ch> wrote: > >> On Sun, 17 Jun 2012, Aryeh Gregor wrote: >> > On Thu, Jun 14, 2012 at 1:11 AM, Ian Hickson <ian@hixie.ch> wrote: >> > > I strongly disagree. <input> and <textarea> are high-level constructs, >> > > so it's fine for them to be defined by the UA's platform. But >> > > contenteditable is a very low-level primitive. We can't just punt on >> > > how it interacts with CSS; otherwise people will have no way to >> > > reliably make UIs with it. >> > >> > I don't know why you think contenteditable is "lower-level" than >> > input/textarea. >> >> By "high level" I mean something that is self-contained, usable as a >> standalone feature, which typically integrates with other features in an >> atomic fashion; "lower-level", then, means something that in comparison >> requires more work to use, can only be used in conjunction with something >> else, etc. By analogy, a fruit juice box is high-level: it comes with its >> own straw, it doesn't need any additional tools to open it, it provides a >> final product without requiring any additional work. On the other hand, a >> can of frozen grape concentrate requires a bowl in which to mix the >> concentrate and some water, a spoon to stir them together, a jug from >> which to pour the result, a glass in which to pour it and from which to >> drink the resulting fruit juice. >> >> <input type=text> is a high-level construct: it provides a self-contained >> place in which text can be entered, it plugs straight into the form >> submission system, it exposes hooks for setting the value or retrieving >> the user's input that do not require knowing how the control works. >> >> contenteditable="", on the other hand, exposes the DOM directly, has no >> integration with other features like form submission, has a much less >> obvious boundary between it and surrounding content... if you want to use >> it in real content, there's no way to do it without script of some kind, >> and if you want to use it to do anything especially compelling, you need a >> lot of script (to provide all the UI for formatting, etc). >> >> This isn't a criticism of contenteditable="". Low-level primitives are the >> building blocks of platforms. But it does mean that we have different >> tradeoffs to make in the designs of the features. >> >> >> > >> In the end this is the check that I'm using at the moment (I didn't >> > >> perform extensive tests, just enough to check that it seemed to work) >> > >> >> > >> var value = data.replace( /[\n|\t]*/g, '' ).toLowerCase(); >> > >> if ( !value || value == '<br>' || value == '<p> <br></p>' || >> value == >> > >> '<p><br></p>' || value == '<p> </p>' ) >> > >> return true; >> > > >> > > Now there's a problem we should fix. Having five different >> representations >> > > of "nothing" seems like a terrible position for us to be in. >> > >> > If you type some stuff and then delete it all, the desired result will >> > vary based on lots of factors, e.g.: >> > >> > * Whether <div> or <p> is being used for paragraph separators. Both >> > <p><br></p> and <div><br></div> might make sense for "nothing", >> > depending. This is author-configurable using the >> > defaultParagraphSeparator command. >> > >> > * Whether there was any styling present before. If all the text was >> > previously bold, for instance, deleting everything might result in >> > something like <p><b><br></b></p>, because per spec, deletion doesn't >> > remove style tags from empty lines. >> > >> > * Whether there was any other special markup. If something (like >> > execCommand("insertHTML")) made the first line have <p id="foo">, then >> > deleting everything would result in <p id="foo"><br></p>. >> > >> > * What the author specified as the initial contents of the editable >> > area. If you have <div contenteditable><br></div> to start with, and >> > the user puts the cursor there and then types "foo" and then deletes >> > it, you'll go back to having just <br>, because nothing ever inserted >> > a <p> or <div> or anything. (As soon as the user hits Enter, both the >> > old and new lines are wrapped in a paragraph separator per spec, >> > although only IE/Opera do this right now.) >> > >> > Really, you can have any HTML markup at all in contenteditable, and we >> > can't avoid that. There's not going to be any reliable way to figure >> > out what "nothing" is if you can't answer the same question for >> > arbitrary HTML. >> >> Maybe the right way to detect "nothing" is to compare textContent against >> "" and then to look for specific elements that count as palpable content, >> like <img>. Would it make sense to provide an API for that? >> >> -- >> Ian Hickson U+1047E )\._.,--....,'``. fL >> http://ln.hixie.ch/ U+263A /, _.. \ _\ ;`._ ,. >> Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' > > >
Received on Thursday, 30 August 2012 08:45:18 UTC