Solution 1 :

Pseudo-elements seem to work fine.

p {
  width: 50%;
}

p::before {
  content: "("
}

p::after {
  content: ")"
}
<p contenteditable style="display:inline-block">Lorem, ipsum dolor sit amet consectetur adipisicing elit. Est distinctio molestias, cupiditate soluta quibusdam dolore dolor optio quae praesentium recusandae incidunt deserunt eaque explicabo vero.</p>

Solution 2 :

A (somewhat hackish) workaround for the trailing breaks: hide all <br> elements when content isn’t focused

[contenteditable] {
  display: inline
}

[contenteditable]:focus br {
  display: inline-block
}

[contenteditable] br {
  display: none
}

[contenteditable]:focus {
  background: yellow;
  padding: 3px;
}
<span>(</span>
<div contenteditable="true">
  <span contenteditable="inherit">type here<span>
</div>
<span>)</span>

Problem :

I have an HTML page with editable paragraphs (though these could be spans or divs if that helps solve the problem). I want the user to type in some text, and have the page automatically put parentheses around it. The parentheses need to be in another element that is not editable so that they cannot be deleted. For example, suppose the user types this:

Hello
World

The page should display this:

(Hello
 World)

Important: note how the closing paren should be in line with the last line of text.

Here is some code that gets me very close, but not quite there:

<span>(</span>
<p contenteditable style="display:inline"></p>
<span>)</span>

This works fine with a single line of text. The problem is that entering more than one line of text causes the closing paren to drop down after the last line of text due to the browser (I’m using Chrome) automatically inserting a break at the end of the paragraph, so we get this:

(Hello
 World
)

Maybe all I need to do is to prevent the browser from adding that trailing break, but I don’t know how. I’d like the solution to be HTML/CSS ideally, something along the lines of text-decoration or text-transform. I’ve tried using ::before and ::after on the paragraph instead of the spans but I couldn’t get that to work right either. Any ideas?

Thanks for your help!

Comments

Comment posted by isherwood

Nice. Seems like you’d want to apply the paragraph styling using a class or attribute selector instead:

Comment posted by Paulie_D

@isherwood Indeed but I just took the OPs code and adapted it.

Comment posted by Mitchell Glaser

OP here – thanks, and yes I tried this, but your example is a single line of text. Move the cursor to the end of that line of text and hit enter and you will see the effect that I got, with the paren moving to the next line. Just now I noticed that if you hit enter in the middle of the line there is no problem. It only happens when you heit enter at the end of a line, like when you type in multiple paragraphs, which my users may do.

Comment posted by Paulie_D

That is not what you asked. You only mention a single paragraph. If you wanted a solution for multiple paragraphs then you should have asked that. Paragraphs do not contain line breaks

Comment posted by Mitchell Glaser

OP here – I’m sorry if I was not clear. When I said multiple lines of text I meant multiple paragraphs. The good news is that I created a way to do this, by attaching a javascript function to an onblur event.

By