Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS: :focus of elements within contenteditable

If you have the following HTML:

<div contenteditable="true">
  <p>The first paragraph</p>
  <p>The second paragraph</p>
</div>

Is there a way to style the paragraph that is being edited differently from all other paragraphs in the div that is contenteditable?

div > p:focus { border: 1px solid red }

won't be applied to the paragraph being edited.

Here's a JSFiddle you can play with.

How can I style the paragraph being edited (the <p>-tag) differently?

I'd prefer a CSS-only solution, but perhaps I'll have to use JavaScript.

EDIT:

Since we could not find a pure CSS solution (and using :hover is not a real solution for me) I am now looking for some lines of JavaScript that set the attribute class="focus" on the node that is being edited.

like image 995
pvorb Avatar asked May 30 '13 09:05

pvorb


People also ask

Can you focus a div CSS?

The <div> does not accept input, so it cannot have :focus . Furthermore, CSS does not allow you to set styles on an element based on targeting its descendants. So you can't really do this unless you are willing to use JavaScript.

What does Contenteditable attribute do?

The contenteditable attribute specifies whether the content of an element is editable or not.

What is false about Contenteditable attribute?

contenteditable="false" Indicates that the element is not editable. contenteditable="inherit" Indicates that the element is editable if its immediate parent element is editable.


1 Answers

I think I found a solution.

With the following code snippet you can get the parent element at the current caret position when the selection changes.

var selectedElement = null;
function setFocus(e) {
  if (selectedElement)
    selectedElement.style.outline = 'none';

  selectedElement = window.getSelection().focusNode.parentNode;
  // walk up the DOM tree until the parent node is contentEditable
  while (selectedElement.parentNode.contentEditable != 'true') {
    selectedElement = selectedElement.parentNode;
  }
  selectedElement.style.outline = '1px solid #f00';
};
document.onkeyup = setFocus;
document.onmouseup = setFocus;

Here I change the outline property manually but you could of course add a class attribute and set the style via CSS.

You still have to manually check if selectedElement is a child of our <div> with the contenteditable attribute. But I think you can get the basic idea.

Here's the updated JSFiddle.

EDIT: I updated the code as well as the JSFiddle to make it work in Firefox and Internet Explorer 9+, too. Unfortunately these Browsers do not have a onselectionchange event handler, so I had to use onkeyup and onmouseup.

like image 149
pvorb Avatar answered Oct 04 '22 04:10

pvorb